|
Dies ist eine unveröffentlichte Dokumentation für Admission Controller 1.37-dev. |
Verwendung von Pod-Sicherheitszulassung mit SUSE Security Admission Controller
Pod-Sicherheitsrichtlinien (PSP) wurden seit der Kubernetes-Version 1.25 entfernt. Sie werden durch die Pod-Sicherheitszulassung (PSA) ersetzt.
Die PSA vereinfacht die Sicherung der Pods in Kubernetes-Clustern.
Die PSA hat drei Profile (beschrieben in den Pod-Sicherheitsstandards) für Namespaces:
-
privilegiert, das die breiteste Palette von Berechtigungen bietet
-
Basislinie, um neue Privilegieneskalationen zu verhindern
-
eingeschränkt, um Pods zu härten
Ein PSA-Controller führt Aktionen bei der Erkennung von Verstößen durch.
Die Aktionen sind: enforce, audit und warn.
Sie können konfiguriert werden.
Zum Zeitpunkt des Schreibens, mit Kubernetes 1.28, hat der PSA-Controller die folgenden Einschränkungen:
-
Keine Mutationsfähigkeiten
-
Höhere Objekte (wie
Deployment,Job) werden nur bewertet, wenn dieauditoderwarnModi aktiviert sind
Admission Controller kann verwendet werden, um ein PSA-Profil zu integrieren und so diese Einschränkungen zu vermeiden.
|
Sie könnten Admission Controller verwenden, um die alte PSP-Konfiguration zu ersetzen, wie in PSP-Migration gezeigt. Das Ziel dieses Artikels ist es jedoch zu zeigen, wie Admission Controller die neue PSA ergänzen kann. |
Beispiel
In diesem Beispiel erstellen wir einen Namespace und wenden restriktive PSA-Richtlinien an:
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
Dieses PSA-Profil erlaubt es nicht, Container zu erstellen, die ihre Anwendung als den root Benutzer ausführen.
Bei der Definition dieses Containers:
-
muss das
runAsNonRootAttribut auftruegesetzt werden. -
das
runAsUserkann nicht auf0gesetzt werden.
Daher wird die folgende Ressource ihren gewünschten Zustand nicht erreichen:
kubectl Befehl zur Konfiguration einer Ressource mit runAsUser: 0 (markiert als ➀)
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 |
Wenn wir die Bereitstellung überprüfen, können wir sehen, dass die PSA die Erstellung des Pods verhindert:
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"
}
Sie können dies beheben, indem Sie das runAsUser: 0 aus der Container-Definition entfernen:
kubectl Befehl zur Konfiguration einer Ressource ohne 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
Jetzt erlaubt die PSA einen Versuch zur Erstellung des Pods, aber es schlägt immer noch fehl.
kubectl get pods -n my-namespace
NAME READY STATUS RESTARTS AGE
nginx-deployment-57d8568bbb-h4bx7 0/1 CreateContainerConfigError 0 47s
Das liegt daran, dass die Containerdefinition keinen Benutzer angegeben hat, der beim Starten eines Programms im Container verwendet werden soll.
Der Standard ist, als Root-Benutzer auszuführen, wenn dies der Fall ist.
Das ist durch die runAsNonRoot Direktive nicht erlaubt:
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"
}
}
}
]
Hier kann Admission Controller helfen.
Sie können die user-group-policy Richtlinie verwenden, um die Bereitstellungsdefinition zu ändern.
Dies konfiguriert einen Standardbenutzer für Container, die diese Information weglassen.
|
Für dieses Beispiel benötigen Sie den Admission Controller Stack im Kubernetes-Cluster. Siehe die Quickstart-Anleitung für weitere Details. |
Es ist möglich, einen Benutzer-ID-Bereich durchzusetzen, zum Beispiel 1000—2000 und 4000—5000:
kubectl-Befehl zur Durchsetzung eines Benutzer-ID-Bereichs
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
Überprüfen Sie, ob die Richtlinie aktiv ist, bevor Sie fortfahren:
kubectl get clusteradmissionpolicy.policies.kubewarden.io/user-group-psp
Wenn die Richtlinie aktiv ist, erstellen Sie die Bereitstellung erneut:
kubectl-Befehl zur erneuten Erstellung der Bereitstellung
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
Jetzt wird die Bereitstellung durch die Richtlinie von Admission Controller verändert, die es erlaubt, dass der Pod gestartet wird.
Der im Pod definierte Container hat einen Standardwert von 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"
}
}
Die Admission Controller-Integration kann in diesem Szenario mehr tun.
Es kann den Wert des bereitgestellten runAsUser überprüfen.
Diese Ressource wird von der vorherigen Admission Controller-Richtlinie abgelehnt:
kubectl-Befehl zur Anzeige der Ressourcenablehnung
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 |
Es wird abgelehnt, weil der runAsUser-Wert auf 7000 gesetzt ist, was außerhalb der von der Richtlinie erlaubten Bereiche liegt:
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"
}