Policy Controller-Audit-Verstöße im Security Command Center melden

Last reviewed 2023-04-17 UTC

In dieser Anleitung wird gezeigt, wie Sicherheitsadministratoren der Plattform Richtlinienverstöße für Kubernetes-Ressourcen sowie Sonstige Sicherheitslücken und Sicherheitsergebnisse in Security Command Center anzeigen lassen und verwalten können. In dieser Anleitung können Sie entweder Policy Controller oder Open Policy Agent (OPA) Gatekeeper verwenden.

Architektur

Der Policy Controller überprüft, prüft und erzwingt, dass Ihre Kubernetes-Cluster-Ressourcen die Richtlinien in Bezug auf Sicherheit, Vorschriften oder Geschäftsregeln einhalten. Policy Controller basiert auf dem Open-Source-Projekt OPA Gatekeeper.

Mit den Audit-Funktionen von Policy Controller und OPA Gatekeeper können Sie deklarative Kontrollen implementieren, mit denen Ressourcen regelmäßig auf Richtlinien hin ausgewertet werden. Wenn ein Problem erkannt wird, erzeugen die Steuerelemente Verstöße für Ressourcen, die nicht den Richtlinien entsprechen. Diese Verstöße werden im Cluster gespeichert und Sie können sie mit Kubernetes-Tools wie kubectl abfragen.

Um diese Verstöße sichtbar zu machen und Ihnen bei der Durchführung von Aktionen zu helfen, können Sie das Security Command Center nutzen. Das Security Command Center stellt ein Dashboard und APIs bereit, mit denen Sie Sicherheits- und Datenrisiken in einer Organisation für Google Cloud-Ressourcen, Kubernetes-Ressourcen und Hybrid- oder Multi-Cloud-Ressourcen erkennen, verstehen und beheben können.

Das Security Command Center zeigt mögliche Sicherheitsrisiken und Richtlinienverstöße an, die als Ergebnisse bezeichnet werden. Die Ergebnisse stammen aus Quellen, von denen Risiken und Verstöße erkannt und gemeldet werden. Das Security Command Center umfasst integrierte Dienste und Sie können Drittanbieterquellen und Ihre eigenen Quellen hinzufügen.

In dieser Anleitung und im zugehörigen Quellcode wird gezeigt, wie Sie im Security Command Center eine Quelle und Ergebnisse für Richtlinienverletzungen des Policy Controllers und des OPA Gatekeepers erstellen.

Das folgende Diagramm zeigt die in dieser Anleitung implementierte Architektur:

Architektur mit Quelle, Controller und Synchronisierung.

Wie im vorherigen Diagramm gezeigt, erstellen Sie in dieser Anleitung eine Quelle in Security Command Center mithilfe eines Befehlszeilentools. Sie stellen einen Controller in einem GKE-Cluster (Google Kubernetes Engine) bereit, um Beschränkungsverstöße des Policy Controllers und des OPA Gatekeepers mit den Ergebnissen im Security Command Center zu synchronisieren.

Wie Sie Richtlinienverstöße für Google Cloud-Ressourcen synchronisieren, erfahren Sie in unserer Anleitung zum Erstellen richtlinienkonformer Google Cloud-Ressourcen mit Config Connector und Policy Controller.

Ziele

  • Erstellen Sie eine Richtlinie und eine Ressource, die gegen die Richtlinie verstößt.
  • Quelle in Security Command Center erstellen
  • Erzeugen Sie ein Ergebnis im Security Command Center aus einer OPA Gatekeeper-Richtlinienverletzung mithilfe eines Befehlszeilen-Tools.
  • Stellen Sie einen Controller für den GKE-Cluster bereit, um die Ergebnisse von OPA Gatekeeper-Richtlinienverletzungen im Security Command Center regelmäßig zu synchronisieren.
  • Sehen Sie sich die Ergebnisse im Terminal und in der Google Cloud Console an.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweis

  1. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  2. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  3. Für diese Anleitung benötigen Sie eine geeignete Bearbeiterrolle für das Security Command Center auf Organisationsebene, z. B. den Sicherheitscenter-Admin-Bearbeiter. Der Administrator Ihrer Organisation kann Ihnen diese Rolle zuweisen.
  4. Aktivieren Sie Cloud Shell in der Google Cloud Console.

    Cloud Shell aktivieren

Umgebung vorbereiten

  1. Legen Sie in Cloud Shell das Google Cloud-Projekt fest, das Sie für diese Anleitung verwenden möchten:

    gcloud config set project PROJECT_ID
    

    Ersetzen Sie PROJECT_ID durch Ihre Google Cloud-Projekt-ID. Wenn Sie diesen Befehl ausführen, erstellt Cloud Shell eine exportierte Umgebungsvariable namens GOOGLE_CLOUD_PROJECT, die Ihre Projekt-ID enthält.

  2. Aktivieren Sie die Resource Manager API, die GKE API, die Security Command Center API und die Service Usage API:

    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        securitycenter.googleapis.com \
        serviceusage.googleapis.com
    

GKE-Cluster erstellen

  1. Erstellen Sie in Cloud Shell einen GKE-Cluster mit aktivierter Workload Identity:

    gcloud container clusters create gatekeeper-securitycenter-tutorial \
        --enable-ip-alias \
        --release-channel regular \
        --workload-pool $GOOGLE_CLOUD_PROJECT.svc.id.goog \
        --zone us-central1-f
    

    Mit diesem Befehl wird der Cluster in der Zone us-central1-f erstellt. Sie können eine andere Zone oder Region verwenden.

  2. Weisen Sie sich die Clusterrolle cluster-admin zu:

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin \
        --user $(gcloud config get-value core/account)
    

    Sie benötigen diese Rolle später, um einige von dem Controller verwendete Kubernetes-Ressourcen zu erstellen. Sie benötigen ihn auch, wenn Sie die Open-Source-OPA Gatekeeper-Distribution installieren.

Richtlinientool installieren

Wenn Sie einen verwalteten GKE Enterprise-Cluster haben, folgen Sie der Anleitung zum Installieren von Policy Controller. Andernfalls installieren Sie die OPA Gatekeeper-Distribution.

Policy Controller

Installieren Sie Policy Controller gemäß der Installationsanleitung.

Verwenden Sie ein Prüfintervall von 60 Sekunden.

OPA Gatekeeper

  1. Definieren Sie in Cloud Shell die OPA Gatekeeper-Version, die Sie installieren möchten:

    GATEKEEPER_VERSION=v3.10.0
    
  2. Installieren Sie OPA Gatekeeper:

    kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/$GATEKEEPER_VERSION/deploy/gatekeeper.yaml
    
  3. Prüfen Sie, ob OPA Gatekeeper installiert ist:

    kubectl rollout status deploy gatekeeper-controller-manager \
        -n gatekeeper-system
    

    Wenn die Installation abgeschlossen ist, zeigt die Ausgabe deployment "gatekeeper-controller-manager" successfully rolled out an.

Richtlinie erstellen

Eine Richtlinie in Policy Controller und OPA Gatekeeper besteht aus einer Einschränkungsvorlage und einer Einschränkung. Die Einschränkungsvorlage enthält die Richtlinienlogik. Die Einschränkung gibt an, wo die Richtlinie angewendet wird, und gibt Eingabeparameter für die Richtlinienlogik an.

In diesem Abschnitt erstellen Sie eine Richtlinie für Kubernetes-Pods und einen Pod, der gegen die Richtlinie verstößt.

  1. Klonen Sie in Cloud Shell das Repository der OPA Gatekeeper-Bibliothek, rufen Sie das Repository-Verzeichnis auf und sehen Sie sich ein bekanntes Commit an:

    git clone https://github.com/open-policy-agent/gatekeeper-library.git \
        ~/gatekeeper-library
    
    cd ~/gatekeeper-library
    
    git checkout 1da0facae99658accb73c291cb79f497fcddf641
    
  2. Erstellen Sie im Namespace default einen Pod mit dem Namen nginx-disallowed:

    kubectl apply -f library/general/allowedrepos/samples/repo-must-be-openpolicyagent/example_disallowed.yaml
    

    Das folgende Manifest gilt für das Erstellen des Pods:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-disallowed
    spec:
      containers:
        - name: nginx
          image: nginx
          resources:
            limits:
              cpu: "100m"
              memory: "30Mi"
    

    Dieser Pod verwendet ein Container-Image aus einem Repository, das von der Richtlinie nicht genehmigt wurde.

  3. Erstellen Sie eine Einschränkungsvorlage mit dem Namen k8sallowedrepos:

    kubectl apply -f library/general/allowedrepos/template.yaml
    

    Das Manifest der Einschränkungsvorlage lautet so:

    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: k8sallowedrepos
      annotations:
        description: >-
          Requires container images to begin with a string from the specified list.
    spec:
      crd:
        spec:
          names:
            kind: K8sAllowedRepos
          validation:
            # Schema for the `parameters` field
            openAPIV3Schema:
              type: object
              properties:
                repos:
                  description: The list of prefixes a container image is allowed to have.
                  type: array
                  items:
                    type: string
      targets:
        - target: admission.k8s.gatekeeper.sh
          rego: |
            package k8sallowedrepos
    
            violation[{"msg": msg}] {
              container := input.review.object.spec.containers[_]
              satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]
              not any(satisfied)
              msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
            }
    
            violation[{"msg": msg}] {
              container := input.review.object.spec.initContainers[_]
              satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]
              not any(satisfied)
              msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
            }
    
  4. Erstellen Sie eine Einschränkung mit dem Namen repo-is-openpolicyagent:

    kubectl apply -f library/general/allowedrepos/samples/repo-must-be-openpolicyagent/constraint.yaml
    

    Das Einschränkungsmanifest lautet so:

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sAllowedRepos
    metadata:
      name: repo-is-openpolicyagent
    spec:
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Pod"]
        namespaces:
          - "default"
      parameters:
        repos:
          - "openpolicyagent/"
    

Einschränkungen prüfen

Der Audit-Controller in Policy Controller und OPA Gatekeeper wertet Ressourcen regelmäßig anhand von Einschränkungen aus. So können Sie Ressourcen ermitteln, die gegen die Richtlinien verstoßen, bevor Sie die Einschränkung erstellt haben.

  1. In Cloud Shell können Sie Verstöße für alle Einschränkungen mit der Kategorie constraint abfragen:

    kubectl get constraint -o json | jq '.items[].status.violations'
    

    Die Ausgabe sieht so aus:

    [
      {
        "enforcementAction": "deny",
        "kind": "Pod",
        "message": "container <nginx> has an invalid image repo <nginx>, allowed repos are [\"openpolicyagent\"]",
        "name": "nginx-disallowed",
        "namespace": "default"
      }
    ]
    

    Für den Pod, den Sie vor dem Erstellen der Einschränkung erstellt haben, gibt es einen Verstoß. Wenn anstelle der vorherigen Ausgabe null angezeigt wird, wurde der Policy Controller oder das OPA Gatekeeper-Audit nicht ausgeführt, seit sie die Einschränkung erstellt haben. Die Prüfung wird standardmäßig jede Minute ausgeführt. Warten Sie eine Minute und versuchen Sie es dann noch einmal.

Quelle für Security Command Center erstellen

Security Command Center erfasst Ergebnisse anhand von Quellen. So erstellen Sie eine Quelle für Ergebnisse aus Policy Controller und OPA Gatekeeper:

  1. Erstellen Sie in Cloud Shell ein Google-Dienstkonto und speichern Sie den Namen des Dienstkontos in einer Umgebungsvariablen:

    SOURCES_ADMIN_SA=$(gcloud iam service-accounts create \
        securitycenter-sources-admin \
        --display-name "Security Command Center sources admin" \
        --format 'value(email)')
    

    Mit diesem Google-Dienstkonto können Sie Security Command Center-Quellen verwalten.

  2. Definieren Sie eine Umgebungsvariable, die Ihre Google Cloud-Organisations-ID enthält:

    ORGANIZATION_ID=$(gcloud projects get-ancestors $GOOGLE_CLOUD_PROJECT \
        --format json | jq -r '.[] | select (.type=="organization") | .id')
    
  3. Weisen Sie dem Google-Dienstkonto des Quelladministrators auf Organisationsebene die Rolle Sicherheitscenter-Quellenadministrator zu:

    gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
        --member "serviceAccount:$SOURCES_ADMIN_SA" \
        --role roles/securitycenter.sourcesAdmin
    

    Diese Rolle bietet die securitycenter.sources.*-Berechtigungen, die zum Verwalten von Quellen erforderlich sind.

  4. Weisen Sie dem Quelladministrator des Google-Dienstkontos auf Organisationsebene die Rolle Service Usage-Nutzer zu:

    gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
        --member "serviceAccount:$SOURCES_ADMIN_SA" \
        --role roles/serviceusage.serviceUsageConsumer
    

    Diese Rolle bietet die Berechtigung serviceusage.services.use für die Verwendung von Projekten in der Organisation für Kontingent- und Abrechnungszwecke.

  5. Gewähren Sie sich selbst für das Google-Dienstkonto des Quelladministrators die Rolle „Dienstkonto-Token-Ersteller”:

    gcloud iam service-accounts add-iam-policy-binding \
        $SOURCES_ADMIN_SA \
        --member "user:$(gcloud config get-value account)" \
        --role roles/iam.serviceAccountTokenCreator
    

    Mit dieser Rolle kann Ihre Nutzeridentität das Google-Dienstkonto imitieren.

  6. Laden Sie die neueste Version des gatekeeper-securitycenter-Befehlszeilentools für Ihre Plattform herunter und machen Sie sie ausführbar:

    VERSION=v0.4.0
    
    curl -Lo gatekeeper-securitycenter "https://github.com/GoogleCloudPlatform/gatekeeper-securitycenter/releases/download/${VERSION}/gatekeeper-securitycenter_$(uname -s)_$(uname -m)"
    
    chmod +x gatekeeper-securitycenter
    
  7. Mit dem gatekeeper-securitycenter-Tool können Sie eine Security Command Center-Quelle für Ihre Organisation erstellen. Vollständigen Quellnamen in einer Umgebungsvariablen erfassen

    export SOURCE_NAME=$(./gatekeeper-securitycenter sources create \
        --organization $ORGANIZATION_ID \
        --display-name "Gatekeeper" \
        --description "Reports violations from Policy Controller audits" \
        --impersonate-service-account $SOURCES_ADMIN_SA | jq -r '.name')
    

    Mit diesem Befehl wird eine Quelle mit dem Anzeigenamen Gatekeeper erstellt. Dieser Anzeigename ist im Security Command Center sichtbar. Sie können auch einen anderen Anzeigenamen und eine andere Beschreibung verwenden.

    Wenn Sie eine Antwort mit der Fehlermeldung The caller does not have permission erhalten, warten Sie eine Minute und versuchen Sie es dann noch einmal. Dieser Fehler kann auftreten, wenn die IAM-Bindungen (Identity and Access Management) noch nicht wirksam sind.

Ergebnisse mit der Befehlszeile erstellen

Sie können Ergebnisse von Security Command Center über Policy Controller- und OPA Gatekeeper-Einschränkungsverstöße mit dem gatekeeper-securitycenter-Tool im Rahmen einer Build-Pipeline oder einer geplanten Aufgabe erstellen.

  1. Erstellen Sie in Cloud Shell ein Google-Dienstkonto und speichern Sie den Namen des Dienstkontos in einer Umgebungsvariablen:

    FINDINGS_EDITOR_SA=$(gcloud iam service-accounts create \
        gatekeeper-securitycenter \
        --display-name "Security Command Center Gatekeeper findings editor" \
        --format 'value(email)')
    

    Sie verwenden dieses Google-Dienstkonto, um Ergebnisse für Ihre Security Command Center-Quelle zu erstellen.

  2. Weisen Sie dem Google-Dienstkonto für die Quelle die Rolle Sicherheitscenter-Ergebnisbearbeiter zu:

    ./gatekeeper-securitycenter sources add-iam-policy-binding \
        --source $SOURCE_NAME \
        --member "serviceAccount:$FINDINGS_EDITOR_SA" \
        --role roles/securitycenter.findingsEditor \
        --impersonate-service-account $SOURCES_ADMIN_SA
    

    Diese Rolle bietet die securitycenter.findings.*-Berechtigungen, die zum Erstellen und Bearbeiten von Ergebnissen erforderlich sind. Wenn Sie diesen Befehl ausführen, imitieren Sie das Google-Dienstkonto des Quelladministrators.

  3. Weisen Sie dem Google-Dienstkonto des Ergebnisbearbeiters die Rolle Service Usage-Nutzer auf Organisationsebene zu:

    gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
        --member "serviceAccount:$FINDINGS_EDITOR_SA" \
        --role roles/serviceusage.serviceUsageConsumer
    
  4. Weisen Sie Ihrer Nutzeridentität für das Google-Dienstkonto des Ergebnisbearbeiters die Rolle Ersteller von Dienstkonto-Tokens zu:

    gcloud iam service-accounts add-iam-policy-binding \
        $FINDINGS_EDITOR_SA \
        --member "user:$(gcloud config get-value account)" \
        --role roles/iam.serviceAccountTokenCreator
    
  5. Senden Sie Ergebnisse ans Terminal, anstatt sie im Security Command Center abzuspeichern:

    ./gatekeeper-securitycenter findings sync --dry-run=true
    

    Dieser Befehl verwendet standardmäßig Ihren aktuellen kubeconfig-Kontext. Wenn Sie eine andere kubeconfig-Datei verwenden möchten, verwenden Sie das Flag --kubeconfig.

    Die Ausgabe sieht dann ungefähr so aus:

    [
      {
        "finding_id": "0be44bcf181ef03162eed40126a500a0",
        "finding": {
          "resource_name": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed",
          "state": 1,
          "category": "K8sAllowedRepos",
          "external_uri": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent",
          "source_properties": {
            "Cluster": "",
            "ConstraintName": "repo-is-openpolicyagent",
            "ConstraintSelfLink": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent",
            "ConstraintTemplateSelfLink": "https://API_SERVER/apis/templates.gatekeeper.sh/v1beta1/constrainttemplates/k8sallowedrepos",
            "ConstraintTemplateUID": "e35b1c39-15f7-4a7a-afae-1637b44e81b2",
            "ConstraintUID": "b904dddb-0a23-4f4f-81bb-0103de838d3e",
            "Explanation": "container \u003cnginx\u003e has an invalid image repo \u003cnginx\u003e, allowed repos are [\"openpolicyagent\"]",
            "ProjectId": "",
            "ResourceAPIGroup": "",
            "ResourceAPIVersion": "v1",
            "ResourceKind": "Pod",
            "ResourceName": "nginx-disallowed",
            "ResourceNamespace": "default",
            "ResourceSelfLink": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed",
            "ResourceStatusSelfLink": "",
            "ResourceUID": "8ddd752f-e620-43ea-b966-4ae2ae507c67",
            "ScannerName": "GATEKEEPER"
          },
          "event_time": {
            "seconds": 1606287680
          }
        }
      }
    ]
    

    In der vorherigen Ausgabe ist API_SERVER die IP-Adresse oder der Hostname des API-Servers Ihres GKE-Clusters.

    Informationen zur Bedeutung der Felder finden Sie auf der Seite zur Ressourcensuche der Security Command Center API.

  6. Erstellen Sie Ergebnisse im Security Command Center:

    ./gatekeeper-securitycenter findings sync \
        --source $SOURCE_NAME \
        --impersonate-service-account $FINDINGS_EDITOR_SA
    

    Wenn Sie diesen Befehl ausführen, imitieren Sie das Google-Dienstkonto des Ergebnis-Editors.

    Die Ausgabe enthält create finding. Das bedeutet, dass das gatekeeper-securitycenter-Befehlszeilentool ein Ergebnis erstellt hat. Das Attribut findingID dieser Ausgabe enthält den vollständigen Namen des Ergebnisses im Format:

    organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID
    

    In dieser Ausgabe gilt:

    • ORGANIZATION_ID ist Ihre Google Cloud-Organisations-ID.
    • SOURCE_ID ist Ihre Security Command Center-Quell-ID.
    • FINDING_ID ist die Ergebnis-ID.

    Weitere Informationen finden Sie im Abschnitt Ergebnisse ansehen.

    Wenn Sie eine Antwort mit der Fehlermeldung The caller does not have permission erhalten, warten Sie eine Minute und versuchen Sie es dann noch einmal. Dieser Fehler kann auftreten, wenn die IAM-Bindungen (Identity and Access Management) noch nicht wirksam sind.

Ergebnisse mit einem Kubernetes-Controller erstellen

Sie können gatekeeper-securitycenter als Controller in Ihrem GKE-Cluster bereitstellen. Dieser Controller prüft in regelmäßigen Abständen, ob Verstöße vorliegen, und erstellt bei jedem Verstoß ein Ergebnis in Security Command Center.

Wenn die Ressource konform ist, legt der Controller den Status des vorhandenen Ergebnisses auf INACTIVE fest.

  1. Erstellen Sie in Cloud Shell eine IAM-Richtlinienbindung für Workload Identity, damit das gatekeeper-securitycenter-controller-Dienstkonto von Kubernetes im Namespace gatekeeper-securitycenter die Identität für das Google-Dienstkonto des Ergebnisbearbeiters übernehmen kann.

    gcloud iam service-accounts add-iam-policy-binding \
        $FINDINGS_EDITOR_SA \
        --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[gatekeeper-securitycenter/gatekeeper-securitycenter-controller]" \
        --role roles/iam.workloadIdentityUser
    

    Sie erstellen das Kubernetes-Dienstkonto und den Kubernetes-Namespace, wenn Sie den Controller bereitstellen.

  2. Rufen Sie das kpt-Paket für den gatekeeper-securitycenter-Controller ab:

    VERSION=v0.4.0
    
    kpt pkg get https://github.com/GoogleCloudPlatform/gatekeeper-securitycenter.git/manifests@$VERSION manifests
    

    Mit diesem Befehl wird ein Verzeichnis namens manifests erstellt, das die Ressourcenmanifestdateien für den Controller enthält.

    kpt ist ein Befehlszeilentool, mit dem Sie Kubernetes-Ressourcen verwalten, bearbeiten, anpassen und anwenden können. In dieser Anleitung verwenden Sie kpt, um die Ressourcenmanifeste für Ihre Umgebung anzupassen.

  3. Legen Sie den Namen des Security Command Center-Quellennamens fest:

    kpt fn eval manifests \
        --image gcr.io/kpt-fn/apply-setters:v0.2 -- \
        "source=$SOURCE_NAME"
    
  4. Legen Sie den Clusternamen fest:

    kpt fn eval manifests \
        --image gcr.io/kpt-fn/apply-setters:v0.2 -- \
        "cluster=$(kubectl config current-context)"
    

    Der Controller fügt den Namen des Clusters als Quellattribut zu den Ergebnissen hinzu, die im Security Command Center erstellt werden. Wenn Sie mehrere Cluster haben, können Sie mit diesem Namen ermitteln, zu welchem Cluster ein Ergebnis gehört.

  5. Fügen Sie die Workload Identity-Annotation hinzu, um das Kubernetes-Dienstkonto des Controllers an das Google-Dienstkonto des Ergebniseditors zu binden:

    kpt fn eval manifests \
        --image gcr.io/kpt-fn/set-annotations:v0.1.4 \
        --match-kind ServiceAccount \
        --match-name gatekeeper-securitycenter-controller \
        --match-namespace gatekeeper-securitycenter -- \
        "iam.gke.io/gcp-service-account=$FINDINGS_EDITOR_SA"
    
  6. Initialisieren Sie das Controller-Paket:

    kpt live init manifests
    
  7. Wenden Sie die Controller-Ressourcen auf Ihren Cluster an:

    kpt live apply manifests --reconcile-timeout 3m --output table
    

    Mit diesem Befehl werden die folgenden Ressourcen in Ihrem Cluster erstellt:

    • Ein Namespace mit dem Namen gatekeeper-securitycenter.
    • Ein Dienstkonto mit dem Namen gatekeeper-securitycenter-controller.
    • Eine Clusterrolle, die get- und list-Zugriff auf alle Ressourcen in allen API-Gruppen gewährt. Diese Rolle ist erforderlich, da der Controller die Ressourcen abruft, die Richtlinienverstöße verursacht haben.
    • Eine Clusterrollenbindung, die dem Dienstkonto die Clusterrolle zuweist.
    • Eine Bereitstellung mit dem Namen gatekeeper-securitycenter-controller-manager.
    • Eine ConfigMap mit dem Namen gatekeeper-securitycenter-config, die Konfigurationswerte für die Bereitstellung enthält.

    Der Befehl wartet außerdem darauf, dass die Ressourcen bereit sind.

  8. Überprüfen Sie mit dem Controller-Log, ob der Controller Richtlinienverstöße lesen und mit der Security Command Center API kommunizieren kann:

    kubectl logs deployment/gatekeeper-securitycenter-controller-manager \
        --namespace gatekeeper-securitycenter --follow --all-containers
    

    Sie sehen Logeinträge mit der Nachricht syncing findings.

    Wenn Sie dem Log nicht mehr folgen möchten, drücken Sie Ctrl+C.

  9. Erstellen Sie eine Richtlinie und eine Ressource, die gegen die Richtlinie verstößt, um zu prüfen, ob der Controller neue Ergebnisse erstellen kann. Der Pod verwendet Image-Digests, um auf Container-Images zu verweisen.

    Wechseln Sie in das Repository-Verzeichnis der OPA Gatekeeper-Bibliothek:

    cd ~/gatekeeper-library
    
  10. Erstellen Sie im Namespace default einen Pod mit dem Namen opa-disallowed:

    kubectl apply --namespace default -f \
        library/general/imagedigests/samples/container-image-must-have-digest/example_disallowed.yaml
    

    Das folgende Manifest gilt für das Erstellen des Pods:

    apiVersion: v1
    kind: Pod
    metadata:
      name: opa-disallowed
    spec:
      containers:
        - name: opa
          image: openpolicyagent/opa:0.9.2
          args:
            - "run"
            - "--server"
            - "--addr=localhost:8080"
    

    Diese Pod-Spezifikation verweist auf ein Container-Image nach Tag und nicht nach Digest.

  11. Erstellen Sie eine Einschränkungsvorlage mit dem Namen k8simagedigests:

    kubectl apply -f library/general/imagedigests/template.yaml
    

    Das Manifest der Einschränkungsvorlage lautet so:

    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: k8simagedigests
      annotations:
        description: >-
          Requires container images to contain a digest.
    
          https://kubernetes.io/docs/concepts/containers/images/
    spec:
      crd:
        spec:
          names:
            kind: K8sImageDigests
      targets:
        - target: admission.k8s.gatekeeper.sh
          rego: |
            package k8simagedigests
    
            violation[{"msg": msg}] {
              container := input.review.object.spec.containers[_]
              satisfied := [re_match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)]
              not all(satisfied)
              msg := sprintf("container <%v> uses an image without a digest <%v>", [container.name, container.image])
            }
    
            violation[{"msg": msg}] {
              container := input.review.object.spec.initContainers[_]
              satisfied := [re_match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)]
              not all(satisfied)
              msg := sprintf("initContainer <%v> uses an image without a digest <%v>", [container.name, container.image])
            }
    
  12. Erstellen Sie eine Einschränkung mit dem Namen container-image-must-have-digest:

    kubectl apply -f library/general/imagedigests/samples/container-image-must-have-digest/constraint.yaml
    

    Das Einschränkungsmanifest lautet so:

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sImageDigests
    metadata:
      name: container-image-must-have-digest
    spec:
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Pod"]
        namespaces:
          - "default"
    

    Diese Einschränkung gilt nur für den Namespace default.

  13. Folgen Sie dem Controllerlog:

    kubectl logs deployment/gatekeeper-securitycenter-controller-manager \
        --namespace gatekeeper-securitycenter --follow --all-containers
    

    Nach einigen Minuten wird ein Logeintrag mit der Meldung create finding angezeigt. Diese Nachricht bedeutet, dass der Controller gatekeeper-securitycenter ein Ergebnis erstellt hat.

    Wenn Sie dem Log nicht mehr folgen möchten, drücken Sie Ctrl+C.

  14. Löschen Sie den Pod opa-disallowed im Namespace default, um zu prüfen, ob der Controller den Ergebnisstatus auf INACTIVE einstellen kann, wenn ein Richtlinienverstoß nicht mehr vom Policy Controller oder OPA Gatekeeper gemeldet wird:

    kubectl delete pod opa-disallowed --namespace default
    
  15. Folgen Sie dem Controllerlog:

    kubectl logs deployment/gatekeeper-securitycenter-controller-manager \
        --namespace gatekeeper-securitycenter --follow --all-containers
    

    Nach einigen Minuten wird ein Logeintrag mit der Nachricht updating finding state und dem Attribut "state":"INACTIVE" angezeigt. Diese Nachricht bedeutet, dass der Controller den Ergebnisstatus auf „inaktiv” gesetzt hat.

    Wenn Sie dem Log nicht mehr folgen möchten, drücken Sie Ctrl+C.

Ergebnisse ansehen

Sie können Ergebnisse von Security Command Center auf dem Terminal und in der Google Cloud Console ansehen.

  1. Verwenden Sie in Cloud Shell die gcloud CLI, um Ergebnisse für Ihre Organisation und Quelle aufzulisten:

    gcloud scc findings list $ORGANIZATION_ID \
        --source $(basename $SOURCE_NAME) \
        --format json
    

    Mit dem Befehl basename rufen Sie die numerische Quellen-ID aus dem vollständigen Quellnamen ab.

    Die Ausgabe sieht dann ungefähr so aus:

    [
      {
        "finding": {
          "category": "K8sAllowedRepos",
          "createTime": "2020-11-25T06:58:47.213Z",
          "eventTime": "2020-11-25T06:58:20Z",
          "externalUri": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent",
          "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID",
          "parent": "organizations/ORGANIZATION_ID/sources/SOURCE_ID",
          "resourceName": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed",
          "securityMarks": {
            "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID/securityMarks"
          },
          "sourceProperties": {
            "Cluster": "cluster-name",
            "ConstraintName": "repo-is-openpolicyagent",
            "ConstraintSelfLink": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent",
            "ConstraintTemplateSelfLink": "https://API_SERVER/apis/templates.gatekeeper.sh/v1beta1/constrainttemplates/k8sallowedrepos",
            "ConstraintTemplateUID": "e35b1c39-15f7-4a7a-afae-1637b44e81b2",
            "ConstraintUID": "b904dddb-0a23-4f4f-81bb-0103de838d3e",
            "Explanation": "container <nginx> has an invalid image repo <nginx>, allowed repos are [\"openpolicyagent\"]",
            "ProjectId": "",
            "ResourceAPIGroup": "",
            "ResourceAPIVersion": "v1",
            "ResourceKind": "Pod",
            "ResourceName": "nginx-disallowed",
            "ResourceNamespace": "default",
            "ResourceSelfLink": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed",
            "ResourceStatusSelfLink": "",
            "ResourceUID": "8ddd752f-e620-43ea-b966-4ae2ae507c67",
            "ScannerName": "GATEKEEPER"
          },
          "state": "ACTIVE"
        },
        "resource": {
          "name": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed"
        }
      },
      {
        "finding": {
          "category": "K8sImageDigests",
          [...]
      }
    ]
    

    In dieser Ausgabe gilt:

    • API_SERVER ist die IP-Adresse oder der Hostname des API-Servers Ihres GKE-Clusters.
    • ORGANIZATION_ID ist Ihre Google Cloud-Organisations-ID.
    • SOURCE_ID ist Ihre Security Command Center-Quell-ID.
    • FINDING_ID ist die Ergebnis-ID.

    Informationen zu den Ergebnisattributen finden Sie unter Ergebnisressource in der Security Command Center API.

  2. Rufen Sie die Ergebnisse in der Google Cloud Console auf dem Tab Ergebnisse des Security Command Center auf.

    Zu Ergebnissen

  3. Wählen Sie Ihre Organisation aus und klicken Sie auf Auswählen.

  4. Klicken Sie auf Anzeigen nach Quelltyp.

  5. Klicken Sie in der Liste Quelltyp auf Gatekeeper. Wenn Gatekeeper nicht in der Liste Quelltyp aufgeführt ist, löschen Sie alle Filter in der Ergebnisliste.

  6. Klicken Sie in der Ergebnisliste auf ein Ergebnis, um sich die Ergebnisattribute und Quellattribute anzeigen zu lassen.

    Wenn eine Ressource aufgrund einer Änderung an der Ressource oder der Richtlinie keinen Verstoß mehr verursacht, setzt der Controller den Ergebnisstatus auf inaktiv. Es kann einige Minuten dauern, bis diese Änderung im Security Command Center angezeigt wird.

    Standardmäßig zeigt Security Command Center aktive Ergebnisse an. Klicken Sie zum Anzeigen inaktiver Ergebnisse auf Weitere Optionen, wählen Sie Inaktive Ergebnisse einschließen aus und klicken Sie auf OK.

Fehlerbehebung

  • Wenn Policy Controller oder OPA Gatekeeper keine Verstöße im Feld status der Einschränkungsobjekte meldet, rufen Sie mit Cloud Shell die Logs des Audit-Controllers auf:

    kubectl logs deployment/gatekeeper-audit --namespace gatekeeper-system \
        --all-containers
    
  • Wenn der gatekeeper-securitycenter-Controller keine Ergebnisse im Security Command Center erstellt, können Sie die Logs des Controller-Managers einsehen:

    kubectl logs deployment/gatekeeper-securitycenter-controller-manager \
        --namespace gatekeeper-securitycenter --all-containers
    
  • Wenn das Befehlszeilentool gatekeeper-securitycenter Fehler meldet, können Sie die Ausführlichkeit der Logausgabe erhöhen, indem Sie die Umgebungsvariable DEBUG auf true setzen, bevor Sie den Befehl gatekeeper-securitycenter ausführen:

    export DEBUG=true
    
  • Wenn Sie das gatekeeper-securitycenter-Befehlszeilentool verwenden, um eine Quelle in Security Command Center zu erstellen, erhalten Sie möglicherweise eine Fehlermeldung, die mit folgendem Text endet:

    oauth2: cannot fetch token: 400 Bad Request
    Response: {
      "error": "invalid_grant",
      "error_description": "Bad Request"
    }
    

    Rufen Sie in diesem Fall neue Anmeldedaten für die Verwendung mit Standardanmeldedaten für Anwendungen ab:

    gcloud auth application-default login
    

    Verwenden Sie die neuen Anmeldedaten, um die Quelle noch einmal zu erstellen.

Wenn Sie andere Probleme mit dieser Anleitung haben, empfehlen wir Ihnen, die folgenden Dokumente zu lesen:

Einrichtung automatisieren

Für zukünftige Bereitstellungen können Sie die Schritte in dieser Anleitung automatisieren, indem Sie den Anleitungen im GitHub-Repository gatekeeper-securitycenter folgen.

Bereinigen

Löschen Sie die einzelnen Ressourcen, damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht weiter in Rechnung gestellt werden.

Einzelne Ressourcen löschen

  1. Löschen Sie den GKE-Cluster in Cloud Shell:

    gcloud container clusters delete gatekeeper-securitycenter-tutorial \
        --zone us-central1-f --async --quiet
    
  2. Löschen Sie die gatekeeper-library-Dateien:

    rm -rf ~/gatekeeper-library
    
  3. Löschen Sie die IAM-Richtlinienbindungen:

    GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project)
    
    ORGANIZATION_ID=$(gcloud projects get-ancestors $GOOGLE_CLOUD_PROJECT \
        --format json | jq -r '.[] | select (.type=="organization") | .id')
    
    SOURCE_NAME=$(./gatekeeper-securitycenter sources list \
        --organization "$ORGANIZATION_ID" \
        --impersonate-service-account "securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        | jq -r ".[] | select (.display_name==\"Gatekeeper\") | .name")
    
    ./gatekeeper-securitycenter sources remove-iam-policy-binding \
        --source $SOURCE_NAME \
        --member "serviceAccount:gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --role roles/securitycenter.findingsEditor \
        --impersonate-service-account securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    
    gcloud iam service-accounts remove-iam-policy-binding \
        gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[gatekeeper-securitycenter/gatekeeper-securitycenter-controller]" \
        --role roles/iam.workloadIdentityUser
    
    gcloud iam service-accounts remove-iam-policy-binding \
        gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --member "user:$(gcloud config get-value account)" \
        --role roles/iam.serviceAccountTokenCreator
    
    gcloud organizations remove-iam-policy-binding $ORGANIZATION_ID \
        --member "serviceAccount:gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --role roles/serviceusage.serviceUsageConsumer
    
    gcloud iam service-accounts remove-iam-policy-binding \
        securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --member "user:$(gcloud config get-value account)" \
        --role roles/iam.serviceAccountTokenCreator
    
    gcloud organizations remove-iam-policy-binding $ORGANIZATION_ID \
        --member "serviceAccount:securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --role roles/serviceusage.serviceUsageConsumer
    
    gcloud organizations remove-iam-policy-binding $ORGANIZATION_ID \
        --member "serviceAccount:securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --role roles/securitycenter.sourcesAdmin
    
  4. Löschen Sie die Google-Dienstkonten:

    gcloud iam service-accounts delete --quiet \
        gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    
    gcloud iam service-accounts delete --quiet \
        securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

Nächste Schritte