Vordefinierte Sicherheitsrichtlinien auf Pod-Ebene mit PodSecurity anwenden


Auf dieser Seite wird gezeigt, wie Sie mit dem PodSecurity-Admission-Controller vordefinierte Sicherheitskontrollen auf Pod-Ebene in Ihren GKE-Clustern (Google Kubernetes Engine) anwenden.

Weitere Informationen zur Funktionsweise von PodSecurity finden Sie unter Pod-Sicherheitszugang.

Übersicht

PodSecurity ist ein Kubernetes-Admission-Controller, mit dem Sie Pod-Sicherheitsstandards auf Pods anwenden können, die in Ihren GKE-Clustern ausgeführt werden. Pod-Sicherheitsstandards sind vordefinierte Sicherheitsrichtlinien, die die allgemeinen Anforderungen der Pod-Sicherheit in Kubernetes abdecken. Diese Richtlinien reichen von äußerst weit gefassten bis zu sehr restriktiven Richtlinien.

Sie können die folgenden Pod-Sicherheitsstandards auf Ihre GKE-Cluster anwenden:

  • Privilegiert: Eine uneingeschränkte Richtlinie, die die umfassendsten Berechtigungen bietet. Ermöglicht bekannte Rechteausweitungen.
  • Referenz: Eine minimal restriktive Richtlinie, die die standardmäßige, minimal angegebene Pod-Konfiguration zulässt. Verhindert bekannte Rechteausweitungen.
  • Eingeschränkt: Eine stark einschränkende Richtlinie, die den Best Practices für die Pod-Härtung folgt.

Sie können den PodSecurity-Admission-Controller verwenden, um Pod-Sicherheitsstandards in den folgenden Modi anzuwenden:

  • Enforce: Richtlinienverstöße sorgen für das Ablehnen der Erstellung von Pods. Ein Audit-Ereignis wird dem Audit-Log hinzugefügt.
  • Audit: Richtlinienverstöße sorgen für das Hinzufügen eines Audit-Ereignisse zum Audit-Log. Die Pod-Erstellung ist zulässig.
  • Warn: Richtlinienverstöße lösen eine an den Nutzer gerichtete Warnung aus. Die Pod-Erstellung ist zulässig.

Der PodSecurity-Admission-Controller bettet diese Richtlinien in die Kubernetes API ein.

Wenn Sie benutzerdefinierte Sicherheitsrichtlinien auf Pod-Ebene erstellen und anwenden möchten, können Sie stattdessen den Gatekeeper-Admission-Controller verwenden.

Hinweis

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit gcloud components update ab.

Voraussetzungen

Der PodSecurity-Admission-Controller ist standardmäßig in Clustern verfügbar, die auf den folgenden GKE-Versionen ausgeführt werden:

  • Version 1.25 oder höher: stabile Version
  • Version 1.23 und Version 1.24: Beta

Informationen dazu, ob eine GKE-Version verfügbar und die Standardversion für Ihre Release-Version ist, finden Sie im Releasezeitplan.

Pod-Sicherheitsstandards mit PodSecurity anwenden

Um den PodSecurity-Admission-Controller zu verwenden, müssen Sie bestimmte Pod-Sicherheitsstandards in bestimmten Modi auf bestimmte Namespaces anwenden. Dazu können Sie Namespace-Labels verwenden. In dieser Übung tun Sie Folgendes:

  • Zwei neue Namespaces erstellen
  • Sicherheitsrichtlinien auf jeden Namespace anwenden
  • Konfigurierte Richtlinien testen

In den folgenden GKE-Versionen ignoriert GKE Richtlinien, die Sie auf den Namespace kube-system anwenden:

  • 1.23.6-gke.1900 und höher
  • 1.24.0-gke.1200 und höher

Vermeiden Sie in früheren GKE-Versionen das Erzwingen von Richtlinien in kube-system.

Neue Namespaces erstellen

Erstellen Sie in Ihrem Cluster Namespaces:

kubectl create ns baseline-ns
kubectl create ns restricted-ns

Mit diesem Befehl werden die folgenden Namespaces erstellt:

  • baseline-ns: Für Arbeitslasten mit geringer Einschränkung
  • restricted-ns: Für Arbeitslasten mit starker Einschränkung

Labels verwenden, um Sicherheitsrichtlinien anzuwenden

Wenden Sie die folgenden Pod-Sicherheitsstandards an:

  • baseline: Auf baseline-ns im Modus warn anwenden
  • restricted: Auf restricted-ns im Modus enforce anwenden
kubectl label --overwrite ns baseline-ns pod-security.kubernetes.io/warn=baseline
kubectl label --overwrite ns restricted-ns pod-security.kubernetes.io/enforce=restricted

Diese Befehle liefern das folgende Ergebnis:

  • Arbeitslasten im Namespace baseline-ns, die gegen die baseline-Richtlinie verstoßen, sind zulässig und der Client zeigt eine Warnmeldung an.
  • Arbeitslasten im Namespace restricted-ns, die gegen die restricted-Richtlinie verstoßen, werden abgelehnt und GKE fügt den Audit-Logs einen Eintrag hinzu.

Prüfen Sie, ob die Labels hinzugefügt wurden:

kubectl get ns --show-labels

Die Ausgabe sieht in etwa so aus:

baseline-ns       Active   74s   kubernetes.io/metadata.name=baseline-ns,pod-security.kubernetes.io/warn=baseline
restricted-ns     Active   18s   kubernetes.io/metadata.name=restricted-ns,pod-security.kubernetes.io/enforce=restricted
default           Active   57m   kubernetes.io/metadata.name=default
kube-public       Active   57m   kubernetes.io/metadata.name=kube-public
kube-system       Active   57m   kubernetes.io/metadata.name=kube-system

Konfigurierte Richtlinien testen

Wenn Sie prüfen möchten, ob der PodSecurity-Admission-Controller wie beabsichtigt funktioniert, stellen Sie für beide Namespaces eine Arbeitslast bereit, die gegen die baseline- und die restricted-Richtlinie verstößt. Durch das folgende Beispielmanifest wird ein nginx-Container bereitgestellt, der eine Rechteausweitung zulässt.

  1. Speichern Sie das folgende Manifest als psa-workload.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    
  2. Wenden Sie das Manifest auf den Namespace baseline-ns an:

    kubectl apply -f psa-workload.yaml --namespace=baseline-ns
    

    Die Ausgabe sieht in etwa so aus:

    Warning: would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
    

    Die baseline-Richtlinie ermöglicht die Bereitstellung des Pods im Namespace.

  3. Prüfen Sie, ob der Pod erfolgreich bereitgestellt wurde:

    kubectl get pods --namespace=baseline-ns -l=app=nginx
    
  4. Wenden Sie das Manifest auf den Namespace restricted-ns an:

    kubectl apply -f psa-workload.yaml --namespace=restricted-ns
    

    Die Ausgabe sieht in etwa so aus:

    Error from server (Forbidden): error when creating "workload.yaml": pods "nginx"
    is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation
    != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false),
    unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
    runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
    seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
    to "RuntimeDefault" or "Localhost")
    

    Der Pod wird nicht im Namespace bereitgestellt. Dem Log wird ein Audit-Eintrag hinzugefügt.

Richtlinienverstöße in Audit-Logs ansehen

Richtlinienverstöße in den Modi audit und enforce werden in den Audit-Logs für Ihren Cluster aufgezeichnet. Sie können sich diese Logs mit dem Log-Explorer in der Google Cloud Console ansehen.

  1. Rufen Sie in der Google Cloud Console den Log-Explorer auf.

    Zum Log-Explorer

  2. Geben Sie im Feld Abfrage Folgendes ein, um Audit-Logs in den Modi audit und enforce abzurufen:

    resource.type="k8s_cluster"
    protoPayload.resourceName:"/pods/nginx"
    protoPayload.methodName="io.k8s.core.v1.pods.create"
    (labels."pod-security.kubernetes.io/audit-violations":"PodSecurity" OR protoPayload.response.reason="Forbidden")
    
  3. Klicken Sie auf Abfrage ausführen.

  4. Maximieren Sie im Abschnitt Abfrageergebnisse den Logeintrag Forbidden zum Prüfen der Ablehnungslogs im enforce-Modus. Die Details sehen in etwa so aus:

    {
      ...
      protoPayload: {
        @type: "type.googleapis.com/google.cloud.audit.AuditLog"
        authenticationInfo: {1}
        authorizationInfo: [1]
        methodName: "io.k8s.core.v1.pods.create"
        request: {6}
        requestMetadata: {2}
        resourceName: "core/v1/namespaces/restricted-ns/pods/nginx"
        response: {
          @type: "core.k8s.io/v1.Status"
          apiVersion: "v1"
          code: 403
          details: {2}
          kind: "Status"
          message: "pods "nginx" is forbidden: violates PodSecurity "restricted:latest": privileged
                  (container "nginx" must not set securityContext.privileged=true),
                  allowPrivilegeEscalation != false (container "nginx" must set
                  securityContext.allowPrivilegeEscalation=false), unrestricted capabilities
                  (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
                  runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
                  seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
                  to "RuntimeDefault" or "Localhost")"
          metadata: {0}
          reason: "Forbidden"
          status: "Failure"
          }
          serviceName: "k8s.io"
          status: {2}
        }
      receiveTimestamp: "2022-02-01T19:19:25.353235326Z"
      resource: {2}
      timestamp: "2022-02-01T19:19:21.469360Z"
    }
    
  5. Maximieren Sie den Logeintrag audit-violations zum Prüfen von Logs im audit-Modus. Die Details sehen in etwa so aus:

    {
      ...
      labels: {
        ...
        pod-security.kubernetes.io/audit-violations: "would violate PodSecurity "baseline:latest": privileged
                                                    (container "nginx" must not set securityContext.privileged=true)"
        pod-security.kubernetes.io/enforce-policy: "privileged:latest"
      }
      operation: {4}
      protoPayload: {10}
      receiveTimestamp: "2023-12-26T05:18:04.533631468Z"
      resource: {2}
      timestamp: "2023-12-26T05:17:36.102387Z"
    }
    

Bereinigen

Löschen Sie die Namespaces, um zu vermeiden, dass Ihrem Google Cloud-Konto Gebühren in Rechnung gestellt werden:

kubectl delete ns baseline-ns
kubectl delete ns restricted-ns

Alternativen zu PodSecurity

Sie können nicht nur den integrierten Kubernetes-PodSecurity-Admission-Controller zum Anwenden von Pod-Sicherheitsstandards verwenden, sondern auch Gatekeeper (einen Admission-Controller, der auf dem Open Policy Agent (OPA) basiert), um benutzerdefinierte Sicherheitskontrollen auf Pod-Ebene zu erstellen und anzuwenden.

Nächste Schritte