Protezione delle build di container

1. Introduzione

ead1609267034bf7.png

Le vulnerabilità del software sono debolezze che possono causare un guasto accidentale del sistema o fornire agli utenti malintenzionati un mezzo per compromettere il software. Container Analysis fornisce due tipi di scansione del sistema operativo per trovare vulnerabilità nei container:

  • L'API On-Demand Scanning ti consente di analizzare manualmente le immagini container per rilevare vulnerabilità del sistema operativo, localmente sul computer o da remoto in Container Registry o Artifact Registry.
  • L'API Container Scanning consente di automatizzare il rilevamento delle vulnerabilità del sistema operativo, eseguendo la scansione ogni volta che esegui il push di un'immagine in Container Registry o Artifact Registry. Se abiliti questa API, vengono abilitate anche le scansioni dei pacchetti di linguaggio per le vulnerabilità di Go e Java.

L'API On-Demand Scanning consente di analizzare le immagini archiviate localmente sul computer o in remoto in Container Registry o Artifact Registry. In questo modo hai un controllo granulare sui container di cui vuoi eseguire la scansione per rilevare le vulnerabilità. Puoi utilizzare la scansione on demand per analizzare le immagini nella pipeline CI/CD prima di decidere se archiviarle in un registro.

Cosa imparerai a fare

In questo lab imparerai a:

  • Creare immagini con Cloud Build
  • Utilizzare Artifact Registry per i container
  • Utilizzare l'analisi automatizzata delle vulnerabilità
  • Configurare la scansione on demand
  • Aggiungere la scansione delle immagini in CICD in Cloud Build

2. Configurazione e requisiti

Configurazione dell'ambiente autonomo

  1. Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Il nome del progetto è il nome visualizzato per i partecipanti a questo progetto. È una stringa di caratteri non utilizzata dalle API di Google. Puoi aggiornarlo in qualsiasi momento.
  • L'ID progetto è univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo l'impostazione). La console Cloud genera automaticamente una stringa univoca, di solito non ti interessa di cosa si tratta. Nella maggior parte dei codelab, devi fare riferimento all'ID progetto (in genere è identificato come PROJECT_ID). Se non ti piace l'ID generato, puoi generarne un altro casuale. In alternativa, puoi provare a crearne uno e vedere se è disponibile. Non può essere modificato dopo questo passaggio e rimarrà per tutta la durata del progetto.
  • Per tua informazione, esiste un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
  1. Successivamente, devi abilitare la fatturazione in Cloud Console per utilizzare le risorse/API Cloud. L'esecuzione di questo codelab non dovrebbe costare molto, se non nulla. Per arrestare le risorse in modo da non incorrere in costi di fatturazione al termine di questo tutorial, puoi eliminare le risorse che hai creato o l'intero progetto. I nuovi utenti di Google Cloud possono beneficiare del programma prova senza costi di 300$.

Configurazione dell'ambiente

In Cloud Shell, imposta l'ID progetto e il numero del tuo progetto. Salvali come variabili PROJECT_ID e PROJECT_ID.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

Abilitazione dei servizi

Attiva tutti i servizi necessari:

gcloud services enable \
  cloudkms.googleapis.com \
  cloudbuild.googleapis.com \
  container.googleapis.com \
  containerregistry.googleapis.com \
  artifactregistry.googleapis.com \
  containerscanning.googleapis.com \
  ondemandscanning.googleapis.com \
  binaryauthorization.googleapis.com 

3. Creazione di immagini con Cloud Build

In questa sezione creerai una pipeline di build automatizzata che creerà l'immagine container, la analizzerà e valuterà i risultati. Se non vengono trovate vulnerabilità CRITICHE, l'immagine viene inviata al repository. Se vengono rilevate vulnerabilità CRITICHE, la build non verrà creata e verrà interrotta.

Fornisci l'accesso per l'account di servizio Cloud Build

Cloud Build avrà bisogno dei diritti di accesso all'API di scansione on demand. Fornisci l'accesso con i seguenti comandi.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
        
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/ondemandscanning.admin"

Crea una directory di lavoro e passa a questa directory

mkdir vuln-scan && cd vuln-scan

Definisci un'immagine di esempio

Crea un file denominato Dockerfile con i seguenti contenuti.

cat > ./Dockerfile << EOF
FROM gcr.io/google-appengine/debian9@sha256:ebffcf0df9aa33f342c4e1d4c8428b784fc571cdf6fbab0b31330347ca8af97a

# System
RUN apt update && apt install python3-pip -y

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==1.1.4
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

EOF

Crea un file denominato main.py con i seguenti contenuti

cat > ./main.py << EOF
import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    name = os.environ.get("NAME", "Worlds")
    return "Hello {}!".format(name)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF

Crea la pipeline di Cloud Build

Il comando seguente creerà un file cloudbuild.yaml nella directory che verrà utilizzato per il processo automatizzato. Per questo esempio, i passaggi sono limitati al processo di compilazione del container. In pratica, tuttavia, includerai istruzioni e test specifici dell'applicazione oltre ai passaggi del container.

Crea il file con il seguente comando.

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']


EOF

Esegui la pipeline CI

Invia la build per l'elaborazione

gcloud builds submit

Rivedere i dettagli della build

Una volta avviato il processo di compilazione, controlla l'avanzamento nella dashboard Cloud Build.

  1. Apri Cloud Build in Cloud Console.
  2. Fai clic sulla build per visualizzarne i contenuti.

4. Artifact Registry per i container

Crea il repository Artifact Registry

In questo lab utilizzerai Artifact Registry per archiviare e scansionare le immagini. Crea il repository con il seguente comando.

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

Configura Docker per utilizzare le tue credenziali gcloud quando accedi ad Artifact Registry.

gcloud auth configure-docker us-central1-docker.pkg.dev

Aggiorna la pipeline di Cloud Build

Modifica la pipeline di build per eseguire il push dell'immagine risultante in Artifact Registry

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

# push to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image']

images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF

Esegui la pipeline CI

Invia la build per l'elaborazione

gcloud builds submit

5. Analisi automatizzata delle vulnerabilità

La scansione degli artefatti viene attivata automaticamente ogni volta che esegui il push di una nuova immagine su Artifact Registry o Container Registry. Le informazioni sulle vulnerabilità vengono aggiornate continuamente quando vengono scoperte nuove vulnerabilità. In questa sezione esaminerai l'immagine che hai appena creato e di cui hai eseguito il push in Artifact Registry ed esplorerai i risultati delle vulnerabilità.

Rivedere i dettagli dell'immagine

Una volta completato il processo di compilazione precedente, esamina l'immagine e i risultati delle vulnerabilità nella dashboard di Artifact Registry.

  1. Apri Artifact Registry in Cloud Console.
  2. Fai clic su artifact-scanning-repo per visualizzare i contenuti.
  3. Fai clic sui dettagli dell'immagine.
  4. Fai clic sull'ultimo riepilogo della tua immagine
  5. Al termine della scansione, fai clic sulla scheda delle vulnerabilità per l'immagine.

Nella scheda Vulnerabilità vedrai i risultati della scansione automatica dell'immagine appena creata.

361be7b3bf293fca.png

L'automazione della scansione è abilitata per impostazione predefinita. Esplora le impostazioni di Artifact Registry per scoprire come attivare/disattivare la scansione automatica.

6. Scansione on demand

Esistono vari scenari in cui potrebbe essere necessario eseguire una scansione prima di eseguire il push dell'immagine in un repository. Ad esempio, uno sviluppatore di container può analizzare un'immagine e risolvere i problemi prima di eseguire il push del codice nel controllo del codice sorgente. Nell'esempio riportato di seguito, creerai e analizzerai l'immagine localmente prima di agire in base ai risultati.

Creare un'immagine

In questo passaggio utilizzerai Docker locale per creare l'immagine nella cache locale.

docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .

Scansionare l'immagine

Una volta creata l'immagine, richiedi una scansione. I risultati della scansione vengono archiviati in un server dei metadati. Il job viene completato con una posizione dei risultati nel server dei metadati.

gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --format="value(response.scan)" > scan_id.txt

Esamina il file di output

Esamina l'output del passaggio precedente, memorizzato nel file scan_id.txt. Nota la posizione del report dei risultati dell'analisi nel server di metadati.

cat scan_id.txt

Esaminare i risultati dettagliati della scansione

Per visualizzare i risultati effettivi della scansione, utilizza il comando list-vulnerabilities nella posizione del report indicata nel file di output.

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) 

L'output contiene una quantità significativa di dati su tutte le vulnerabilità nell'immagine.

Segnalare problemi critici

Gli utenti raramente utilizzano direttamente i dati archiviati nel report. In genere, i risultati vengono utilizzati da un processo automatizzato. Utilizza i comandi riportati di seguito per leggere i dettagli del report e registrare se sono state trovate vulnerabilità CRITICHE

export SEVERITY=CRITICAL

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq ${SEVERITY}; then echo "Failed vulnerability check for ${SEVERITY} level"; else echo "No ${SEVERITY} Vulnerabilities found"; fi

L'output di questo comando sarà

Failed vulnerability check for CRITICAL level

7. Scansione in CI/CD con Cloud Build

Fornisci l'accesso per l'account di servizio Cloud Build

Cloud Build avrà bisogno dei diritti di accesso all'API di scansione on demand. Fornisci l'accesso con i seguenti comandi.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
        
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/ondemandscanning.admin"

Aggiorna la pipeline di Cloud Build

Il comando seguente creerà un file cloudbuild.yaml nella directory che verrà utilizzato per il processo automatizzato. Per questo esempio, i passaggi sono limitati al processo di compilazione del container. In pratica, tuttavia, includerai istruzioni e test specifici dell'applicazione oltre ai passaggi del container.

Crea il file con il seguente comando.

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#pushing to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']

images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF

Esegui la pipeline CI

Invia la build per l'elaborazione per verificare che la build si interrompa quando viene rilevata una vulnerabilità di gravità CRITICA.

gcloud builds submit

Esamina l'errore di build

La build che hai appena inviato non andrà a buon fine perché l'immagine contiene vulnerabilità CRITICHE.

Esamina l'errore di build nella pagina Cronologia di Cloud Build.

Correggere la vulnerabilità

Aggiorna il Dockerfile in modo che utilizzi un'immagine di base che non contenga vulnerabilità CRITICAL.

Sovrascrivi il Dockerfile per utilizzare l'immagine Debian 10 con questo comando

cat > ./Dockerfile << EOF
from python:3.8-slim  

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app

EOF

Esegui il processo CI con l'immagine corretta

Invia la build per l'elaborazione per verificare che la build venga completata correttamente quando non vengono trovate vulnerabilità di gravità CRITICA.

gcloud builds submit

Esaminare la creazione riuscita

La build che hai appena inviato verrà completata perché l'immagine aggiornata non contiene vulnerabilità CRITICHE.

Controlla l'esito positivo della build nella pagina Cronologia di Cloud Build.

Esaminare i risultati della scansione

Esamina l'immagine corretta in Artifact Registry

  1. Apri Artifact Registry in Cloud Console.
  2. Fai clic su artifact-scanning-repo per visualizzare i contenuti.
  3. Fai clic sui dettagli dell'immagine.
  4. Fai clic sull'ultimo riepilogo della tua immagine
  5. Fai clic sulla scheda delle vulnerabilità dell'immagine.

8. Complimenti!

Congratulazioni, hai completato il codelab.

Argomenti trattati:

  • Creazione di immagini con Cloud Build
  • Artifact Registry per i container
  • Analisi automatizzata delle vulnerabilità
  • Scansione on demand
  • Scansione in CI/CD con Cloud Build

Qual è il passaggio successivo?

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione è eliminare il progetto creato per il tutorial.

Ultimo aggiornamento: 21/03/23