Segnalazione di violazioni di audit di Policy Controller in Security Command Center

Last reviewed 2023-04-17 UTC

Questo tutorial mostra agli amministratori della sicurezza della piattaforma come visualizzare e gestire le violazioni dei criteri per le risorse Kubernetes, insieme ad altri risultati su vulnerabilità e sicurezza in Security Command Center. In questo tutorial puoi utilizzare Policy Controller o Open Policy Agent (OPA) Gatekeeper.

Architettura

Policy Controller controlla, controlla e applica la conformità delle risorse del cluster Kubernetes ai criteri relativi a sicurezza, normative o regole aziendali. Policy Controller viene creato a partire dal progetto open source OPA Gatekeeper.

La funzionalità di controllo in Policy Controller e OPA Gatekeeper consente di implementare controlli di rilevamento che valutano periodicamente le risorse in base ai criteri. Se viene rilevato un problema, i controlli creano violazioni per le risorse non conformi ai criteri. Queste violazioni sono archiviate nel cluster ed è possibile eseguire query utilizzando strumenti Kubernetes come kubectl.

Per rendere visibili queste violazioni e aiutarti a intervenire, puoi utilizzare Security Command Center. Security Command Center fornisce una dashboard e API per visualizzare, comprendere e risolvere i rischi per la sicurezza e i dati in un'organizzazione per le risorse Google Cloud, le risorse Kubernetes e le risorse ibride o multi-cloud.

Security Command Center mostra i possibili rischi per la sicurezza e violazioni dei criteri, chiamati risultati. I risultati provengono dalle fonti, che sono meccanismi in grado di rilevare e segnalare rischi e violazioni. Security Command Center include servizi integrati e puoi aggiungere origini di terze parti e le tue.

Questo tutorial e il codice sorgente associato mostrano come creare un'origine e i risultati in Security Command Center per le violazioni dei criteri di Policy Controller e OPA Gatekeeper.

Il seguente diagramma mostra l'architettura implementata in questo tutorial:

Architettura con origine, controller e sincronizzazione.

Come mostrato nel diagramma precedente, in questo tutorial creerai un'origine in Security Command Center utilizzando uno strumento a riga di comando. Esegui il deployment di un controller in un cluster Google Kubernetes Engine (GKE) per sincronizzare le violazioni dei vincoli di Policy Controller e OPA Gatekeeper con i risultati in Security Command Center.

Se vuoi scoprire come sincronizzare le violazioni dei criteri per le risorse Google Cloud, prova il nostro tutorial su come creare risorse Google Cloud conformi ai criteri utilizzando Config Connector e Policy Controller.

Obiettivi

  • Crea un criterio e una risorsa che violano il criterio.
  • Crea un'origine in Security Command Center.
  • Crea un risultato in Security Command Center da una violazione dei criteri del gatekeeper OPA utilizzando uno strumento a riga di comando.
  • Esegui il deployment di un controller nel cluster GKE per sincronizzare periodicamente i risultati in Security Command Center dalle violazioni dei criteri OPA Gatekeeper.
  • Visualizza i risultati nel terminale e nella console Google Cloud.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud possono essere idonei a una prova senza costi aggiuntivi.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Prima di iniziare

  1. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  2. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  3. Per completare questo tutorial, devi avere un ruolo di editor appropriato per Security Command Center a livello di organizzazione, ad esempio Editor amministratore Centro sicurezza. L'amministratore della tua organizzazione può concederti questo ruolo.
  4. Nella console Google Cloud, attiva Cloud Shell.

    Attiva Cloud Shell

Preparazione dell'ambiente

  1. In Cloud Shell, imposta il progetto Google Cloud che vuoi utilizzare per questo tutorial:

    gcloud config set project PROJECT_ID
    

    Sostituisci PROJECT_ID con l'ID del tuo progetto Google Cloud. Quando esegui questo comando, Cloud Shell crea una variabile di ambiente esportata denominata GOOGLE_CLOUD_PROJECT che contiene il tuo ID progetto.

  2. Abilita le API Resource Manager, GKE, Security Command Center e Service Usage:

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

Crea un cluster GKE

  1. In Cloud Shell, crea un cluster GKE in cui è abilitato 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
    

    Questo comando crea il cluster nella zona us-central1-f. Puoi utilizzare una zona o un'area geografica diversa.

  2. Concedi a te il ruolo di cluster cluster-admin:

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

    Questo ruolo ti servirà in un secondo momento per creare alcune delle risorse Kubernetes utilizzate dal controller. Ti servirà anche se installi la distribuzione open source OPA Gatekeeper.

Installazione dello strumento per i criteri

Se hai un cluster GKE gestito, segui le istruzioni per installare Policy Controller, altrimenti installa la distribuzione OPA Gatekeeper.

Policy Controller

Installa Policy Controller seguendo le istruzioni di installazione.

Utilizza un intervallo di controllo di 60 secondi.

Gatekeeper OPA

  1. In Cloud Shell, definisci la versione del gatekeeper OPA che vuoi installare:

    GATEKEEPER_VERSION=v3.10.0
    
  2. Installa OPA Gatekeeper:

    kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/$GATEKEEPER_VERSION/deploy/gatekeeper.yaml
    
  3. Verifica che OPA Gatekeeper sia installato:

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

    Al termine dell'installazione, l'output mostra deployment "gatekeeper-controller-manager" successfully rolled out.

Creazione di un criterio

Un criterio in Policy Controller e in OPA Gatekeeper è costituito da un modello di vincolo e da un vincolo. Il modello di vincolo contiene la logica del criterio. Il vincolo specifica dove viene applicato il criterio e specifica i parametri di input per la logica del criterio.

In questa sezione creerai un criterio per i pod Kubernetes e un pod che viola il criterio.

  1. In Cloud Shell, clona il repository della libreria OPA Gatekeeper, vai alla directory del repository ed esamina un commit noto:

    git clone https://github.com/open-policy-agent/gatekeeper-library.git \
        ~/gatekeeper-library
    
    cd ~/gatekeeper-library
    
    git checkout 1da0facae99658accb73c291cb79f497fcddf641
    
  2. Crea un pod denominato nginx-disallowed nello spazio dei nomi default:

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

    Di seguito è riportato il manifest che applichi per creare il pod:

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

    Questo pod utilizza un'immagine container da un repository non approvata dal criterio.

  3. Crea un modello di vincolo denominato k8sallowedrepos:

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

    Di seguito è riportato il manifest del modello di vincolo:

    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. Crea un vincolo denominato repo-is-openpolicyagent:

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

    Di seguito è riportato il manifest del vincolo:

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

Vincoli di controllo

Il controller di controllo in Policy Controller e in OPA Gatekeeper valuta periodicamente le risorse rispetto ai vincoli. Questo controllo consente di rilevare le risorse che violano i criteri create prima della creazione del vincolo.

  1. In Cloud Shell, visualizza le violazioni di tutti i vincoli eseguendo una query utilizzando la categoria constraint:

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

    L'output è il seguente:

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

    Esiste una violazione per il pod che hai creato prima della creazione del vincolo. Se visualizzi null anziché l'output precedente, il controllo di Policy Controller o di OPA Gatekeeper non è stato eseguito dopo la creazione del vincolo. Per impostazione predefinita, il controllo viene eseguito ogni minuto. Aspetta un minuto e riprova.

Creazione di un'origine Security Command Center

Security Command Center registra i risultati rispetto alle origini. Segui questi passaggi per creare un'origine per i risultati da Policy Controller e OPA Gatekeeper:

  1. In Cloud Shell, crea un account di servizio Google e archivia il nome dell'account di servizio in una variabile di ambiente:

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

    Questo account di servizio Google viene utilizzato per amministrare le origini di Security Command Center.

  2. Definisci una variabile di ambiente contenente il tuo ID organizzazione Google Cloud:

    ORGANIZATION_ID=$(gcloud projects get-ancestors $GOOGLE_CLOUD_PROJECT \
        --format json | jq -r '.[] | select (.type=="organization") | .id')
    
  3. Concedi il ruolo Amministratore origini Centro sicurezza all'account di servizio Google amministratore delle origini a livello di organizzazione:

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

    Questo ruolo fornisce le autorizzazioni securitycenter.sources.* necessarie per amministrare le origini.

  4. Concedi il ruolo Service Usage Consumer all'account di servizio Google amministratore delle origini a livello di organizzazione:

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

    Questo ruolo fornisce l'autorizzazione serviceusage.services.use per utilizzare i progetti nell'organizzazione a fini di quota e fatturazione.

  5. Concedi a te il ruolo Creatore token account di servizio per l'account di servizio Google amministratore delle origini:

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

    Questo ruolo consente alla tua identità utente di simulare l'account di servizio Google o di impersonare.

  6. Scarica la versione più recente dello strumento a riga di comando gatekeeper-securitycenter per la tua piattaforma e rendila eseguibile:

    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. Usa lo strumento gatekeeper-securitycenter per creare un'origine Security Command Center per la tua organizzazione. Acquisisci il nome completo dell'origine in una variabile di ambiente.

    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')
    

    Questo comando crea un'origine con il nome visualizzato Gatekeeper. Questo nome visualizzato è visibile in Security Command Center. Puoi usare un nome visualizzato e una descrizione diversi.

    Se ricevi una risposta con il messaggio di errore The caller does not have permission, attendi un minuto e riprova. Questo errore può verificarsi se le associazioni di Identity and Access Management (IAM) non sono ancora state applicate.

Creazione dei risultati tramite la riga di comando

Puoi creare risultati di Security Command Center dalle violazioni dei vincoli di Policy Controller e OPA Gatekeeper utilizzando lo strumento gatekeeper-securitycenter nell'ambito di un'attività pianificata o di una pipeline di build.

  1. In Cloud Shell, crea un account di servizio Google e archivia il nome dell'account di servizio in una variabile di ambiente:

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

    Utilizzerai questo account di servizio Google per creare risultati per l'origine Security Command Center.

  2. Concedi il ruolo Editor risultati del Centro sicurezza all'account di servizio Google per l'origine:

    ./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
    

    Questo ruolo fornisce le autorizzazioni securitycenter.findings.* necessarie per creare e modificare i risultati. Quando esegui questo comando, impersona l'account di servizio Google amministratore delle origini.

  3. Concedi il ruolo Service Usage Consumer all'account di servizio Google Editor dei risultati a livello di organizzazione:

    gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
        --member "serviceAccount:$FINDINGS_EDITOR_SA" \
        --role roles/serviceusage.serviceUsageConsumer
    
  4. Concedi alla tua identità utente il ruolo Creatore token account di servizio per l'account di servizio Google dell'editor dei risultati:

    gcloud iam service-accounts add-iam-policy-binding \
        $FINDINGS_EDITOR_SA \
        --member "user:$(gcloud config get-value account)" \
        --role roles/iam.serviceAccountTokenCreator
    
  5. Stampa i risultati sul terminale anziché crearli in Security Command Center:

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

    Questo comando utilizza il tuo contesto di kubeconfig attuale per impostazione predefinita. Se vuoi usare un file kubeconfig diverso, usa il flag --kubeconfig.

    L'output è simile al seguente:

    [
      {
        "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
          }
        }
      }
    ]
    

    Nell'output precedente, API_SERVER è l'indirizzo IP o il nome host del server API del tuo cluster GKE.

    Per conoscere il significato dei campi, consulta la pagina relativa al ricerca di risorse dell'API Security Command Center.

  6. Crea i risultati in Security Command Center:

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

    Quando esegui questo comando, usi l'identità dell'account di servizio Google dell'editor dei risultati.

    L'output include create finding, il che significa che lo strumento a riga di comando gatekeeper-securitycenter ha creato un risultato. L'attributo findingID dell'output contiene il nome completo del risultato nel formato:

    organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID
    

    In questo output:

    • ORGANIZATION_ID è l'ID organizzazione Google Cloud
    • SOURCE_ID è il tuo ID origine di Security Command Center
    • FINDING_ID è l'ID risultato

    Per visualizzare il risultato, consulta la sezione Visualizzazione dei risultati.

    Se ricevi una risposta con il messaggio di errore The caller does not have permission, attendi un minuto e riprova. Questo errore può verificarsi se le associazioni di Identity and Access Management (IAM) non sono ancora state applicate.

Creazione dei risultati mediante un controller Kubernetes

Puoi eseguire il deployment di gatekeeper-securitycenter come controller nel tuo cluster GKE. Questo controller verifica periodicamente la presenza di violazioni dei vincoli e crea un risultato in Security Command Center per ogni violazione.

Se la risorsa diventa conforme, il controller imposta lo stato del risultato esistente su INACTIVE.

  1. In Cloud Shell, crea un'associazione dei criteri IAM di Workload Identity per consentire all'gatekeeper-securitycenter-controlleraccount di servizio Kubernetes nello gatekeeper-securitycenterspazio dei nomi di impersonare l'editor dei risultati Account di servizio Google:

    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
    

    L'account di servizio e lo spazio dei nomi Kubernetes vengono creati al momento del deployment del controller.

  2. Recupera il pacchetto kpt per il controller gatekeeper-securitycenter:

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

    Questo comando crea una directory denominata manifests che contiene i file manifest delle risorse per il controller.

    kpt è uno strumento a riga di comando che consente di gestire, manipolare, personalizzare e applicare le risorse Kubernetes. In questo tutorial utilizzerai kpt per personalizzare i manifest delle risorse.

  3. Imposta il nome dell'origine di Security Command Center:

    kpt fn eval manifests \
        --image gcr.io/kpt-fn/apply-setters:v0.2 -- \
        "source=$SOURCE_NAME"
    
  4. Imposta il nome del cluster:

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

    Il controller aggiunge il nome del cluster come proprietà sorgente ai risultati creati in Security Command Center. Se hai più cluster, questo nome ti aiuta a trovare a quale cluster appartiene un risultato.

  5. Per associare l'account di servizio Kubernetes del controller all'account di servizio Google dell'editor dei risultati, aggiungi l'annotazione Workload Identity:

    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. Inizializza il pacchetto del controller:

    kpt live init manifests
    
  7. Applica le risorse controller al cluster:

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

    Questo comando crea le seguenti risorse nel cluster:

    • Uno spazio dei nomi denominato gatekeeper-securitycenter.
    • Un account di servizio denominato gatekeeper-securitycenter-controller.
    • Un ruolo del cluster che fornisce l'accesso get e list a tutte le risorse in tutti i gruppi API. Questo ruolo è obbligatorio perché il controller recupera le risorse che hanno causato violazioni dei criteri.
    • Un'associazione di ruoli del cluster che concede il ruolo del cluster all'account di servizio.
    • Un deployment chiamato gatekeeper-securitycenter-controller-manager.
    • Una mappa di configurazione denominata gatekeeper-securitycenter-config che contiene i valori di configurazione per il deployment.

    Il comando attende inoltre che le risorse siano pronte.

  8. Verifica che il controller possa leggere le violazioni dei vincoli e comunicare con l'API Security Command Center seguendo il log del controller:

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

    Vengono visualizzate voci di log con il messaggio syncing findings.

    Per smettere di seguire il log, premi Ctrl+C.

  9. Per verificare che il controller possa creare nuovi risultati, crea un criterio e una risorsa che violino il criterio. Il pod usa digest di immagini per fare riferimento alle immagini container.

    Vai alla directory del repository della libreria OPA Gatekeeper:

    cd ~/gatekeeper-library
    
  10. Crea un pod denominato opa-disallowed nello spazio dei nomi default:

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

    Di seguito è riportato il manifest che applichi per creare il pod:

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

    Questa specifica del pod fa riferimento a un'immagine container per tag anziché per digest.

  11. Crea un modello di vincolo denominato k8simagedigests:

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

    Di seguito è riportato il manifest del modello di vincolo:

    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. Crea un vincolo denominato container-image-must-have-digest:

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

    Di seguito è riportato il manifest del vincolo:

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

    Questo vincolo si applica solo allo spazio dei nomi default.

  13. Segui il log del controller:

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

    Dopo alcuni minuti, viene visualizzata una voce di log con il messaggio create finding. Questo messaggio indica che il controller gatekeeper-securitycenter ha creato un risultato.

    Per smettere di seguire il log, premi Ctrl+C.

  14. Per verificare che il controller possa impostare lo stato del risultato su INACTIVE quando una violazione non viene più segnalata da Policy Controller o OPA Gatekeeper, elimina il pod chiamato opa-disallowed nello spazio dei nomi default:

    kubectl delete pod opa-disallowed --namespace default
    
  15. Segui il log del controller:

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

    Dopo alcuni minuti, viene visualizzata una voce di log con il messaggio updating finding state e l'attributo "state":"INACTIVE". Questo messaggio indica che il controller ha impostato lo stato del risultato su inattivo.

    Per smettere di seguire il log, premi Ctrl+C.

Visualizzazione dei risultati

Puoi visualizzare i risultati di Security Command Center nel terminale e nella console Google Cloud.

  1. In Cloud Shell, utilizza gcloud CLI per elencare i risultati per la tua organizzazione e l'origine:

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

    Utilizza il comando basename per ottenere l'ID origine numerico dal nome completo dell'origine.

    L'output è simile al seguente:

    [
      {
        "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 questo output:

    • API_SERVER è l'indirizzo IP o il nome host del server API del tuo cluster GKE
    • ORGANIZATION_ID è l'ID organizzazione Google Cloud
    • SOURCE_ID è il tuo ID origine di Security Command Center
    • FINDING_ID è l'ID risultato

    Per scoprire il significato degli attributi dei risultati, consulta la risorsa Risultati nell'API Security Command Center.

  2. Per visualizzare i risultati nella console Google Cloud, vai alla scheda Risultati di Security Command Center.

    Vai a Risultati

  3. Scegli la tua organizzazione e fai clic su Seleziona.

  4. Fai clic su Visualizza per Tipo di origine.

  5. Nell'elenco Tipo di origine, fai clic su Gatekeeper. Se Gatekeeper non è nell'elenco Tipo di origine, cancella tutti i filtri nell'elenco dei risultati.

  6. Nell'elenco dei risultati, fai clic su un risultato per visualizzarne gli attributi e le proprietà sorgente.

    Se una risorsa non causa più una violazione a causa di una modifica alla risorsa o al criterio, il controller imposta lo stato del risultato su inattivo. Potrebbero essere necessari alcuni minuti prima che questa modifica sia visibile in Security Command Center.

    Per impostazione predefinita, Security Command Center mostra i risultati attivi. Per visualizzare i risultati non attivi, fai clic su Altre opzioni, seleziona Includi risultati non attivi e fai clic su OK.

Risoluzione dei problemi

  • Se Policy Controller o OPA Gatekeeper non segnala violazioni nel campo status degli oggetti del vincolo, utilizza Cloud Shell per visualizzare i log dell'audit controller:

    kubectl logs deployment/gatekeeper-audit --namespace gatekeeper-system \
        --all-containers
    
  • Se il controller gatekeeper-securitycenter non crea risultati in Security Command Center, puoi visualizzare i log del gestore dei controller:

    kubectl logs deployment/gatekeeper-securitycenter-controller-manager \
        --namespace gatekeeper-securitycenter --all-containers
    
  • Se lo strumento a riga di comando gatekeeper-securitycenter segnala errori, puoi aumentare il livello di dettaglio dell'output di log impostando la variabile di ambiente DEBUG su true prima di eseguire il comando gatekeeper-securitycenter:

    export DEBUG=true
    
  • Quando utilizzi lo strumento a riga di comando gatekeeper-securitycenter per creare un'origine in Security Command Center, potresti ricevere un messaggio di errore che termina con il seguente testo:

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

    In questo caso, acquisisci nuove credenziali da utilizzare con le Credenziali predefinite dell'applicazione:

    gcloud auth application-default login
    

    Utilizza le nuove credenziali per riprovare a creare l'origine.

Se riscontri altri problemi con questo tutorial, ti consigliamo di esaminare i seguenti documenti:

Automatizzare la configurazione

Per deployment futuri, puoi automatizzare i passaggi in questo tutorial seguendo le istruzioni nel repository GitHub di gatekeeper-securitycenter.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati ulteriori costi per le risorse utilizzate in questo tutorial, elimina le singole risorse.

Elimina le singole risorse

  1. In Cloud Shell, elimina il cluster GKE:

    gcloud container clusters delete gatekeeper-securitycenter-tutorial \
        --zone us-central1-f --async --quiet
    
  2. Elimina i file gatekeeper-library:

    rm -rf ~/gatekeeper-library
    
  3. Elimina le associazioni di criteri IAM:

    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. Elimina gli account di servizio Google:

    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
    

Passaggi successivi