|
Ce document a été traduit à l'aide d'une technologie de traduction automatique. Bien que nous nous efforcions de fournir des traductions exactes, nous ne fournissons aucune garantie quant à l'exhaustivité, l'exactitude ou la fiabilité du contenu traduit. En cas de divergence, la version originale anglaise prévaut et fait foi. |
|
Il s'agit d'une documentation non publiée pour Admission Controller 1.34-dev. |
Utiliser l’admission de sécurité des pods avec SUSE Security Admission Controller
Les politiques de sécurité des pods (PSP) ont été supprimées depuis la version 1.25 de Kubernetes. Elles sont remplacées par l’Admission de sécurité des pods (PSA).
La PSA simplifie la sécurisation des pods dans les clusters Kubernetes.
La PSA a trois profils (décrits dans les normes de sécurité des pods) pour les espaces de noms :
-
privilégié, offrant la plus large gamme de permissions
-
de base, pour prévenir de nouvelles escalades de privilèges
-
restreint, restreint pour durcir les pods
Un contrôleur PSA effectue des actions lors de la détection de violations.
Les actions sont : enforce, audit et warn.
Elles peuvent être configurées.
Au moment de la rédaction, avec Kubernetes 1.28, le contrôleur PSA a les limitations suivantes :
-
Pas de capacités de mutation
-
Les objets de niveau supérieur (comme
Deployment,Job) ne sont évalués que lorsque les modesauditouwarnsont activés.
Admission Controller peut être utilisé pour intégrer un profil PSA afin d’éviter ces limitations.
|
Vous pourriez utiliser Admission Controller pour remplacer l’ancienne configuration PSP comme indiqué dans migration PSP. Cependant, l’objectif de cet article est de montrer comment Admission Controller peut compléter le nouveau PSA. |
Par exemple :
Dans cet exemple, nous créons un espace de noms et appliquons des stratégies PSA restreintes :
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.25
EOF
Ce profil PSA ne permet pas de créer des conteneurs qui exécutent leur application en tant qu’utilisateur root.
Lors de la définition de ce conteneur :
-
l’attribut
runAsNonRootdoit être défini surtrue -
le
runAsUserne peut pas être défini sur0.
Ainsi, la ressource suivante n’atteindra pas son état souhaité :
Commande kubectl configurant une ressource avec runAsUser: 0 (marquée comme ➀)
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
runAsUser: 0 (1)
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
| 1 | runAsUser: 0 |
Si nous vérifions le déploiement, nous pouvons voir que le PSA empêche la création du pod :
kubectl get deploy -n my-namespace nginx-deployment -o json | jq ".status.conditions[] | select(.reason == \"FailedCreate\")"
{
"lastTransitionTime": "2022-10-28T19:09:56Z",
"lastUpdateTime": "2022-10-28T19:09:56Z",
"message": "pods \"nginx-deployment-5f98b4db8c-2m96l\" is forbidden: violates PodSecurity \"restricted:v1.25\": runAsUser=0 (container \"nginx\" must not set runAsUser=0)",
"reason": "FailedCreate",
"status": "True",
"type": "ReplicaFailure"
}
Vous pouvez corriger cela en supprimant le runAsUser: 0 de la définition du conteneur :
Commande kubectl configurant une ressource sans runAsUser: 0
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
Maintenant, le PSA permet une tentative de création de pod mais cela échoue toujours.
kubectl get pods -n my-namespace
NAME READY STATUS RESTARTS AGE
nginx-deployment-57d8568bbb-h4bx7 0/1 CreateContainerConfigError 0 47s
C’est parce que la définition du conteneur n’a pas spécifié d’utilisateur à utiliser lors du démarrage d’un programme à l’intérieur du conteneur.
Par défaut, il s’exécute en tant qu’utilisateur root si tel est le cas.
Cela n’est pas autorisé par la directive runAsNonRoot :
kubectl get pods -n my-namespace nginx-deployment-57d8568bbb-h4bx7 -o json | jq ".status.containerStatuses"
[
{
"image": "nginx:1.14.2",
"imageID": "",
"lastState": {},
"name": "nginx",
"ready": false,
"restartCount": 0,
"started": false,
"state": {
"waiting": {
"message": "container has runAsNonRoot and image will run as root (pod: \"nginx-deployment-57d8568bbb-8mvkc_my-namespace(add7bcc5-3d23-43d0-94e9-6e78f887a53f)\", container: nginx)",
"reason": "CreateContainerConfigError"
}
}
}
]
C’est ici que Admission Controller peut aider.
Vous pouvez utiliser la stratégie user-group-policy pour modifier la définition du déploiement.
Cela configure un utilisateur par défaut pour les conteneurs en omettant cette information.
|
Vous avez besoin de la pile Admission Controller dans le cluster Kubernetes pour cet exemple. Voir le QuickStart pour plus de détails. |
Il est possible d’imposer une plage d’identifiants d’utilisateur, par exemple, 1000—2000 et 4000—5000 :
Commande kubectl imposant une plage d’identifiants d’utilisateur
kubectl apply -f - <<EOF
apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
name: user-group-psp
spec:
policyServer: default
module: registry://ghcr.io/kubewarden/policies/user-group-psp:latest
rules:
- apiGroups: ["", "apps"]
apiVersions: ["v1"]
resources: ["pods", "deployments"]
operations:
- CREATE
- UPDATE
mutating: true
settings:
run_as_user:
rule: "MustRunAs"
overwrite: false
ranges:
- min: 1000
max: 2000
- min: 4000
max: 5000
run_as_group:
rule: "RunAsAny"
supplemental_groups:
rule: "RunAsAny"
EOF
Vérifiez que la stratégie est active avant de continuer :
kubectl get clusteradmissionpolicy.policies.kubewarden.io/user-group-psp
Lorsque la stratégie est active, recréez le déploiement :
Commande kubectl recréant le déploiement
kubectl delete deployment -n my-namespace nginx-deployment && \
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
Maintenant, le déploiement est modifié par la stratégie de Admission Controller qui permet au Pod de démarrer.
Le conteneur défini à l’intérieur du Pod a une valeur par défaut de runAsUser :
kubectl get pods -n my-namespace nginx-deployment-57d8568bbb-nv8fj -o json | jq ".spec.containers[].securityContext"
{
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"ALL"
]
},
"runAsNonRoot": true,
"runAsUser": 1000,
"seccompProfile": {
"type": "RuntimeDefault"
}
}
L’intégration Admission Controller peut faire plus dans ce scénario.
Elle peut vérifier la valeur du runAsUser fourni.
Cette ressource est rejetée par la stratégie Admission Controller mentionnée précédemment :
Commande kubectl pour montrer le rejet de la ressource
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment2
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
runAsUser: 7000 (1)
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
| 1 | runAsUser: 7000 |
Elle est rejetée parce que la valeur runAsUser est définie sur 7000, ce qui est en dehors des plages autorisées par la stratégie :
kubectl get deploy -n my-namespace nginx-deployment -o json | jq ".status.conditions[] | select(.reason == \"FailedCreate\")"
{
"lastTransitionTime": "2022-10-28T19:22:04Z",
"lastUpdateTime": "2022-10-28T19:22:04Z",
"message": "admission webhook \"clusterwide-user-group-psp.kubewarden.admission\" denied the request: User ID outside defined ranges",
"reason": "FailedCreate",
"status": "True",
"type": "ReplicaFailure"
}