Container-Builds sichern

1. Einführung

ead1609267034bf7.png

Sicherheitslücken in Software sind Schwachstellen, die zu einem unbeabsichtigten Systemausfall führen oder böswilligen Akteuren die Möglichkeit geben können, Ihre Software zu manipulieren. Container Analysis bietet zwei Arten von Betriebssystemscans, um Sicherheitslücken in Containern zu finden:

  • Mit der On-Demand Scanning API können Sie Container-Images manuell auf Betriebssystem-Sicherheitslücken scannen – entweder lokal auf Ihrem Computer oder remote in Container Registry oder Artifact Registry.
  • Mit der Container Scanning API können Sie die Erkennung von Sicherheitslücken im Betriebssystem automatisieren und jedes Mal einen Scan ausführen, wenn Sie ein Image in Container Registry oder Artifact Registry hochladen. Wenn Sie diese API aktivieren, werden auch Sprachpakete auf Go- und Java-Sicherheitslücken gescannt.

Mit der On-Demand Scanning API können Sie Images scannen, die lokal auf Ihrem Computer oder remote in Container Registry oder Artifact Registry gespeichert sind. So lässt sich genau steuern, welche Container auf Sicherheitslücken gescannt werden sollen. Mit On-Demand-Scans können Sie Images in Ihrer CI/CD-Pipeline scannen, bevor Sie entscheiden, ob Sie sie in einer Registry speichern möchten.

Lerninhalte

Aufgaben in diesem Lab:

  • Images mit Cloud Build erstellen
  • Artifact Registry für Container verwenden
  • Automatisches Scannen auf Sicherheitslücken verwenden
  • On-Demand-Scans konfigurieren
  • Image-Scans in CICD in Cloud Build hinzufügen

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

b35bf95b8bf3d5d8.pnga99b7ace416376c4.pngbd84a6d3004737c5.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es handelt sich um einen String, der nicht von Google APIs verwendet wird. Sie können ihn jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich (kann nach dem Festlegen nicht mehr geändert werden). In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf die Projekt-ID verweisen (sie wird in der Regel als PROJECT_ID angegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie es mit einem eigenen versuchen. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten
  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs zu verwenden. Die Durchführung dieses Codelabs sollte keine oder nur geringe Kosten verursachen. Wenn Sie Ressourcen herunterfahren möchten, damit Ihnen nach Abschluss dieser Anleitung keine Kosten mehr in Rechnung gestellt werden, können Sie die von Ihnen erstellten Ressourcen oder das gesamte Projekt löschen. Neue Nutzer von Google Cloud kommen für das kostenlose Testprogramm mit einem Guthaben von 300 $ infrage.

Umgebung einrichten

Legen Sie in Cloud Shell Ihre Projekt-ID und die Projektnummer für Ihr Projekt fest. Speichern Sie sie als die Variablen PROJECT_ID und PROJECT_ID.

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

Dienste aktivieren

Aktivieren Sie alle erforderlichen Dienste:

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. Images mit Cloud Build erstellen

In diesem Abschnitt erstellen Sie eine automatisierte Build-Pipeline, um Ihr Container-Image zu erstellen, zu scannen und die Ergebnisse auszuwerten. Wenn keine Sicherheitslücken mit dem Schweregrad CRITICAL gefunden werden, wird das Image in das Repository übertragen. Wenn CRITICAL-Sicherheitslücken gefunden werden, schlägt der Build fehl und wird beendet.

Zugriff für Cloud Build-Dienstkonto bereitstellen

Cloud Build benötigt Berechtigungen für den Zugriff auf die On-Demand Scanning API. Gewähren Sie Zugriff mit den folgenden Befehlen.

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"

Arbeitsverzeichnis erstellen und in dieses Verzeichnis wechseln

mkdir vuln-scan && cd vuln-scan

Beispielbild definieren

Erstellen Sie eine Datei mit dem Namen „Dockerfile“ und dem folgenden Inhalt.

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

Erstellen Sie eine Datei mit dem Namen „main.py“ und dem folgenden Inhalt:

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

Cloud Build-Pipeline erstellen

Mit dem folgenden Befehl wird in Ihrem Verzeichnis eine cloudbuild.yaml-Datei erstellt, die für den automatisierten Prozess verwendet wird. In diesem Beispiel beschränken sich die Schritte auf den Container-Build-Prozess. In der Praxis würden Sie jedoch zusätzlich zu den Container-Schritten anwendungsspezifische Anweisungen und Tests einfügen.

Erstellen Sie die Datei mit dem folgenden Befehl.

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

CI-Pipeline ausführen

Build zur Verarbeitung einreichen

gcloud builds submit

Build-Details ansehen

Nachdem der Build-Prozess gestartet wurde, können Sie den Fortschritt im Cloud Build-Dashboard verfolgen.

  1. Cloud Build in der Cloud Console öffnen
  2. Klicken Sie auf den Build, um den Inhalt aufzurufen.

4. Artifact Registry für Container

Artifact Registry-Repository erstellen

In diesem Lab verwenden Sie Artifact Registry zum Speichern und Scannen Ihrer Images. Erstellen Sie das Repository mit dem folgenden Befehl.

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

Konfigurieren Sie Docker so, dass Ihre gcloud-Anmeldedaten für den Zugriff auf Artifact Registry verwendet werden.

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

Cloud Build-Pipeline aktualisieren

Build-Pipeline so ändern, dass das resultierende Image per Push in Artifact Registry übertragen wird

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

CI-Pipeline ausführen

Build zur Verarbeitung einreichen

gcloud builds submit

5. Automatisches Scannen auf Sicherheitslücken

Das Scannen von Artefakten wird jedes Mal automatisch ausgelöst, wenn Sie ein neues Image in Artifact Registry oder Container Registry hochladen. Die Informationen zu Sicherheitslücken werden kontinuierlich aktualisiert, wenn neue Sicherheitslücken entdeckt werden. In diesem Abschnitt sehen Sie sich das Image an, das Sie gerade erstellt und in die Artifact Registry übertragen haben, und untersuchen die Ergebnisse zu den Sicherheitslücken.

Image-Details prüfen

Nach Abschluss des vorherigen Build-Prozesses können Sie sich das Image und die Ergebnisse zu den Sicherheitslücken im Artifact Registry-Dashboard ansehen.

  1. Öffnen Sie Artifact Registry in der Cloud Console.
  2. Klicken Sie auf „artifact-scanning-repo“, um den Inhalt aufzurufen.
  3. Klicken Sie auf die Bilddetails.
  4. Klicken Sie auf den neuesten Digest Ihres Images.
  5. Klicken Sie nach Abschluss des Scans auf den Tab „Sicherheitslücken“ für das Image.

Auf dem Tab „Sicherheitslücken“ sehen Sie die Ergebnisse des automatischen Scans für das Image, das Sie gerade erstellt haben.

361be7b3bf293fca.png

Das automatisierte Scannen ist standardmäßig aktiviert. In den Artifact Registry-Einstellungen können Sie das automatische Scannen deaktivieren oder aktivieren.

6. On-Demand-Scans

Es gibt verschiedene Szenarien, in denen Sie einen Scan durchführen müssen, bevor Sie das Image in ein Repository übertragen. Bei der Containerentwicklung können Sie z. B. ein Image scannen und die gefundenen Probleme beheben, bevor Sie den Code in die Quellcodeverwaltung übertragen. Im folgenden Beispiel erstellen und analysieren Sie das Image lokal, bevor Sie auf die Ergebnisse reagieren.

Image erstellen

In diesem Schritt verwenden Sie das lokale Docker, um das Image in Ihrem lokalen Cache zu erstellen.

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

Bild scannen

Wenn das Image erstellt wurde, fordern Sie einen Scan des Images an. Die Ergebnisse des Scans werden auf einem Metadatenserver gespeichert. Der Job wird mit dem Speicherort der Ergebnisse auf dem Metadatenserver abgeschlossen.

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

Ausgabedatei prüfen

Sehen Sie sich die Ausgabe des vorherigen Schritts an, die in der Datei „scan_id.txt“ gespeichert wurde. Beachten Sie den Speicherort des Berichts mit den Scanergebnissen auf dem Metadatenserver.

cat scan_id.txt

Detaillierte Scanergebnisse ansehen

Verwenden Sie den Befehl list-vulnerabilities für den in der Ausgabedatei angegebenen Speicherort des Berichts, um die tatsächlichen Ergebnisse des Scans aufzurufen.

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

Die Ausgabe enthält eine erhebliche Menge an Daten zu allen Sicherheitslücken im Image.

Schwerwiegende Probleme melden

Die im Bericht gespeicherten Daten werden selten von Menschen direkt verwendet. Die Ergebnisse werden normalerweise von einem automatisierten Prozess genutzt. Mit den folgenden Befehlen können Sie die Berichtsdetails lesen und protokollieren, ob CRITICAL-Sicherheitslücken gefunden wurden.

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

Dies ist die Ausgabe dieses Befehls:

Failed vulnerability check for CRITICAL level

7. Scannen in CICD mit Cloud Build

Zugriff für Cloud Build-Dienstkonto bereitstellen

Cloud Build benötigt Berechtigungen für den Zugriff auf die On-Demand Scanning API. Gewähren Sie Zugriff mit den folgenden Befehlen.

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"

Cloud Build-Pipeline aktualisieren

Mit dem folgenden Befehl wird in Ihrem Verzeichnis eine cloudbuild.yaml-Datei erstellt, die für den automatisierten Prozess verwendet wird. In diesem Beispiel beschränken sich die Schritte auf den Container-Build-Prozess. In der Praxis würden Sie jedoch zusätzlich zu den Container-Schritten anwendungsspezifische Anweisungen und Tests einfügen.

Erstellen Sie die Datei mit dem folgenden Befehl.

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

CI-Pipeline ausführen

Senden Sie den Build zur Verarbeitung, um zu prüfen, ob er fehlschlägt, wenn eine Sicherheitslücke mit dem Schweregrad CRITICAL gefunden wird.

gcloud builds submit

Build-Fehler prüfen

Der Build, den Sie gerade eingereicht haben, schlägt fehl, weil das Image KRITISCHE Sicherheitslücken enthält.

Sehen Sie sich den Build-Fehler auf der Seite Cloud Build-Verlauf an.

Sicherheitslücke beheben

Aktualisieren Sie das Dockerfile, damit ein Basis-Image verwendet wird, das keine Sicherheitslücken mit dem Schweregrad CRITICAL enthält.

Überschreiben Sie das Dockerfile mit dem folgenden Befehl, um das Debian 10-Image zu verwenden:

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

CI-Prozess mit dem guten Bild ausführen

Senden Sie den Build zur Verarbeitung, um zu prüfen, ob er erfolgreich ist, wenn keine Sicherheitslücken mit dem Schweregrad CRITICAL gefunden werden.

gcloud builds submit

Build-Erfolg prüfen

Der Build, den Sie gerade eingereicht haben, wird erfolgreich sein, da das aktualisierte Image keine Sicherheitslücken mit dem Schweregrad CRITICAL enthält.

Prüfen Sie den Build-Erfolg auf der Seite Cloud Build-Verlauf.

Scanergebnisse prüfen

Funktionierendes Image in Artifact Registry prüfen

  1. Öffnen Sie Artifact Registry in der Cloud Console.
  2. Klicken Sie auf „artifact-scanning-repo“, um den Inhalt aufzurufen.
  3. Klicken Sie auf die Bilddetails.
  4. Klicken Sie auf den neuesten Digest Ihres Images.
  5. Klicken Sie für das Image auf den Tab „Sicherheitslücken“.

8. Glückwunsch!

Herzlichen Glückwunsch! Sie haben das Codelab abgeschlossen.

Behandelte Themen:

  • Images mit Cloud Build erstellen
  • Artifact Registry für Container
  • Automatisches Scannen auf Sicherheitslücken
  • On-Demand-Scans
  • Scannen in CICD mit Cloud Build

Nächste Schritte:

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie entweder das Projekt löschen, das die Ressourcen enthält, oder das Projekt beibehalten und die einzelnen Ressourcen löschen.

Projekt löschen

Am einfachsten vermeiden Sie weitere Kosten durch Löschen des für die Anleitung erstellten Projekts.

Letzte Aktualisierung: 21.03.2023