Informationen zu diesem Codelab
1. Einführung
Container Analysis bietet das Scannen auf Sicherheitslücken und das Speichern von Metadaten für Container. Der Scandienst führt Scans auf Sicherheitslücken für Images in Artifact Registry und Container Registry durch, speichert die resultierenden Metadaten und stellt sie über eine API zur Verfügung. Im Metadatenspeicher können Sie Informationen aus verschiedenen Quellen speichern, z. B. das Scannen auf Sicherheitslücken, Google Cloud-Dienste und Drittanbieter.
Das Scannen auf Sicherheitslücken kann automatisch oder on demand erfolgen:
- Wenn automatisches Scannen aktiviert ist, wird der Scan jedes Mal automatisch ausgelöst, wenn Sie ein neues Image per Push an Artifact Registry oder Container Registry übertragen. Informationen zu Sicherheitslücken werden kontinuierlich aktualisiert, wenn neue Sicherheitslücken entdeckt werden.
- Wenn On-Demand-Scans aktiviert ist, müssen Sie einen Befehl ausführen, um ein lokales Image oder ein Image in Artifact Registry oder Container Registry zu scannen. Mit dem On-Demand-Scanning können Sie flexibel entscheiden, wann Sie Container scannen. Sie können beispielsweise ein lokal erstelltes Image scannen und Sicherheitslücken beheben, bevor Sie es in einer Registry speichern. Die Scanergebnisse sind nach Abschluss des Scans bis zu 48 Stunden verfügbar. Informationen zu Sicherheitslücken werden nach dem Scan nicht aktualisiert.
Da Container Analysis in Ihre CI/CD-Pipeline eingebunden ist, können Sie Entscheidungen anhand dieser Metadaten treffen. Mit der Binärautorisierung können Sie beispielsweise Bereitstellungsrichtlinien erstellen, die nur Bereitstellungen für konforme Images aus vertrauenswürdigen Registrys zulassen.
Aufgaben in diesem Lab
- Automatisches Scannen aktivieren
- On-Demand-Scans durchführen
- Scannen in eine Build-Pipeline einbinden
- Genehmigte Bilder signieren
- GKE-Admission-Controller zum Blockieren von Images verwenden
- GKE so konfigurieren, dass nur signierte genehmigte Images zugelassen werden
2. Einrichtung und Anforderungen
Umgebung zum selbstbestimmten Lernen einrichten
- Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.
- Der Projektname ist der Anzeigename für die Projektteilnehmer. Es handelt sich um eine Zeichenfolge, die von Google APIs nicht verwendet wird. Sie können sie jederzeit aktualisieren.
- Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich. Sie kann nach dem Festlegen nicht mehr geändert werden. Die Cloud Console generiert automatisch einen eindeutigen String. ist Ihnen meist egal, was es ist. In den meisten Codelabs musst du auf die Projekt-ID verweisen, die üblicherweise als
PROJECT_ID
gekennzeichnet ist. Wenn Ihnen die generierte ID nicht gefällt, können Sie eine weitere zufällige ID erstellen. Alternativ können Sie einen eigenen verwenden und nachsehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen. - Zur Information gibt es noch einen dritten Wert, die Projektnummer, die von manchen APIs verwendet wird. Weitere Informationen zu allen drei Werten finden Sie in der Dokumentation.
- Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Cloud-Ressourcen/APIs verwenden zu können. Dieses Codelab sollte möglichst wenig kosten. Wenn Sie Ressourcen herunterfahren möchten, um über diese Anleitung hinaus keine Kosten zu verursachen, können Sie die von Ihnen erstellten Ressourcen oder das gesamte Projekt löschen. Neue Google Cloud-Nutzer haben Anspruch auf eine kostenlose Testversion mit 300$Guthaben.
Cloud Shell-Editor starten
Dieses Lab wurde für die Verwendung mit dem Google Cloud Shell-Editor entwickelt und getestet. So greifen Sie auf den Editor zu:
- Rufen Sie Ihr Google-Projekt unter https://console.cloud.google.com auf.
- Klicken Sie rechts oben auf das Symbol für den Cloud Shell-Editor
- Unten im Fenster wird ein neuer Bereich geöffnet.
Umgebung einrichten
Legen Sie in Cloud Shell Ihre Projekt-ID und die Projektnummer für Ihr Projekt fest. Speichern Sie sie als Variablen des Typs 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
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
3. Automatisches Scannen
Das Scannen von Artefakten wird automatisch ausgelöst, wenn Sie ein neues Image per Push an Artifact Registry oder Container Registry übertragen. Informationen zu Sicherheitslücken werden kontinuierlich aktualisiert, wenn neue Sicherheitslücken entdeckt werden. In diesem Abschnitt laden Sie ein Image per Push an Artifact Registry hoch und sehen sich die Ergebnisse an.
Arbeitsverzeichnis erstellen und dorthin wechseln
mkdir vuln-scan && cd vuln-scan
Beispielbild definieren
Erstellen Sie eine Datei namens Dockerfile mit folgendem 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 namens "main.py" mit folgendem 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
Image erstellen und in AR übertragen
Mit Cloud Build können Sie einen Container erstellen und automatisch per Push in Artifact Registry übertragen. Beachten Sie das Tag bad
auf dem Bild. So können Sie ihn für spätere Schritte besser identifizieren.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
Bilddetails prüfen
Sobald der Build-Prozess abgeschlossen ist, prüfen Sie das Image und die Sicherheitslückenergebnisse im Artifact Registry-Dashboard.
- Öffnen Sie Artifact Registry in der Cloud Console
- Klicken Sie auf das Repository „Artefaktscans“, um den Inhalt anzusehen
- Klicken Sie auf die Bilddetails.
- Klicke auf den neuesten Digest deines Images
- Klicken Sie nach Abschluss des Scans auf den Tab „Sicherheitslücken“ für das Image.
Auf dem Tab „Sicherheitslücken“ werden die Ergebnisse des automatischen Scans für das soeben erstellte Image angezeigt.
Das automatische Scannen ist standardmäßig aktiviert. In den Artifact Registry-Einstellungen erfahren Sie, wie Sie das automatische Scannen aktivieren/deaktivieren.
4. On-Demand-Scanning
Es gibt verschiedene Szenarien, in denen Sie möglicherweise einen Scan ausführen müssen, bevor Sie das Image per Push an ein Repository übertragen. Beispielsweise kann ein Containerentwickler ein Image scannen und die Probleme beheben, bevor er Code an die Versionsverwaltung sendet. Im folgenden Beispiel erstellen und analysieren Sie das Image lokal, bevor Sie auf die Ergebnisse reagieren.
Image erstellen
In diesem Schritt erstellen Sie das Image mit lokalem Docker im lokalen Cache.
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .
Bild scannen
Fordern Sie nach dem Erstellen des Images einen Scan des Images an. Die Ergebnisse des Scans werden auf einem Metadatenserver gespeichert. Der Job wird mit dem Speicherort der Ergebnisse im 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
Nehmen Sie sich einen Moment Zeit, um sich die Ausgabe des vorherigen Schritts anzusehen, die in der Datei scan_id.txt gespeichert war. Beachten Sie den Speicherort der Scanergebnisse im Metadatenserver.
cat scan_id.txt
Detaillierte Scanergebnisse ansehen
Wenn Sie sich die tatsächlichen Ergebnisse des Scans ansehen möchten, verwenden Sie den Befehl list-vulnerabilities
für den in der Ausgabedatei angegebenen Speicherort des Berichts.
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.
Kritische Probleme melden
Die im Bericht gespeicherten Daten werden nur selten direkt von Menschen verwendet. Normalerweise werden die Ergebnisse von einem automatisierten Prozess verwendet. Verwende die folgenden Befehle, um die Berichtsdetails zu lesen und zu protokollieren, ob KRITISCHE 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
Die Ausgabe dieses Befehls ist
Failed vulnerability check for CRITICAL level
5. Pipeline-Scan erstellen
In diesem Abschnitt erstellen Sie eine automatisierte Build-Pipeline, die Ihr Container-Image erstellt, es scannt und anschließend die Ergebnisse auswertet. Wenn keine KRITISCHEN Sicherheitslücken gefunden werden, wird das Image in das Repository verschoben. Wenn KRITISCHE Sicherheitslücken gefunden werden, schlägt der Build fehl und wird beendet.
Zugriff für Cloud Build-Dienstkonto gewähren
Cloud Build benötigt Rechte für den Zugriff auf die On-Demand-Scan-API. Gewähren Sie den 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 erstellen
Mit dem folgenden Befehl wird in Ihrem Verzeichnis die Datei cloudbuild.yaml erstellt, die für den automatisierten Prozess verwendet wird. In diesem Beispiel sind die Schritte auf den Container-Build-Prozess beschränkt. In der Praxis würden Sie jedoch zusätzlich zu den Containerschritten anwendungsspezifische Anweisungen und Tests einbeziehen.
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
Reichen Sie den Build zur Verarbeitung ein, um zu prüfen, ob der Build nicht funktioniert, wenn eine Sicherheitslücke mit dem Schweregrad KRITISCH gefunden wird.
gcloud builds submit
Build-Fehler überprüfen
Der gerade eingereichte Build schlägt fehl, da das Image KRITISCHE Sicherheitslücken enthält.
Prüfen Sie den Build-Fehler auf der Seite Cloud Build-Verlauf
Sicherheitslücke beheben
Aktualisieren Sie das Dockerfile, um ein Basis-Image zu verwenden, das keine KRITISCHEN Sicherheitslücken 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 Image ausführen
Reichen Sie den Build zur Verarbeitung ein, um zu prüfen, ob der Build erfolgreich ist, wenn keine Sicherheitslücken mit dem Schweregrad KRITISCH gefunden werden.
gcloud builds submit
Build-Erfolg überprüfen
Der soeben eingereichte Build wird erfolgreich sein, da das aktualisierte Image keine KRITISCHEN Sicherheitslücken enthält.
Build-Erfolg auf der Seite Cloud Build-Verlauf prüfen
Scanergebnisse prüfen
Gutes Image in Artifact Registry prüfen
- Öffnen Sie Artifact Registry in der Cloud Console
- Klicken Sie auf das Repository „Artefaktscans“, um den Inhalt anzusehen
- Klicken Sie auf die Bilddetails.
- Klicke auf den neuesten Digest deines Images
- Klicken Sie für das Image auf den Tab „Sicherheitslücken“.
6. Bilder signieren
Attestierernotiz erstellen
Eine Attestierernotiz ist einfach ein kleines Datenelement, das als Beschriftung für den anzuwendenden Signaturtyp dient. Eine Notiz kann beispielsweise auf das Scannen auf Sicherheitslücken hinweisen, während eine andere für die QA-Genehmigung verwendet wird. Der Hinweis wird während des Signaturvorgangs referenziert.
Notiz erstellen
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
Notiz speichern
NOTE_ID=vulnz_note
curl -vvv -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./vulnz_note.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
Notiz bestätigen
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
Attestierer erstellen
Attestierer werden für den eigentlichen Image-Signierungsprozess verwendet und hängen ein Vorkommen des Hinweises zur späteren Überprüfung an das Image an. Erstellen Sie den Attestierer zur späteren Verwendung.
Attestierer erstellen
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
Attestierer verifizieren
gcloud container binauthz attestors list
In der letzten Zeile steht, NUM_PUBLIC_KEYS: 0
. Sie geben die Schlüssel in einem späteren Schritt an.
Cloud Build erstellt außerdem automatisch den Attestierer built-by-cloud-build
in Ihrem Projekt, wenn Sie einen Build ausführen, der Images generiert. Der obige Befehl gibt also die beiden Attestierer vulnz-attestor
und built-by-cloud-build
zurück. Nachdem die Images erfolgreich erstellt wurden, signiert Cloud Build sie automatisch und erstellt Attestierungen für sie.
IAM-Rolle wird hinzugefügt
Das Dienstkonto Binärautorisierung benötigt Rechte zum Ansehen der Attestierungshinweise. Zugriff mit dem folgenden API-Aufruf bereitstellen
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
cat > ./iam_request.json << EOM
{
'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
'policy': {
'bindings': [
{
'role': 'roles/containeranalysis.notes.occurrences.viewer',
'members': [
'serviceAccount:${BINAUTHZ_SA_EMAIL}'
]
}
]
}
}
EOM
Datei zum Erstellen der IAM-Richtlinie verwenden
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./iam_request.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
KMS-Schlüssel hinzufügen
Der Attestierer benötigt kryptografische Schlüssel, um den Hinweis anzuhängen und überprüfbare Signaturen bereitzustellen. In diesem Schritt erstellen und speichern Sie Schlüssel in KMS, damit Cloud Build später darauf zugreifen kann.
Fügen Sie zuerst einige Umgebungsvariablen hinzu, um den neuen Schlüssel zu beschreiben
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
Schlüsselbund für eine Reihe von Schlüsseln erstellen
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
Neues asymmetrisches Signaturschlüsselpaar für den Attestierer erstellen
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
Ihr Schlüssel sollte in der Google Cloud Console auf der KMS-Seite angezeigt werden.
Verknüpfen Sie nun den Schlüssel über den Befehl „gcloud binauthz“ mit Ihrem Attestierer:
gcloud beta container binauthz attestors public-keys add \
--attestor="${ATTESTOR_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
Wenn Sie die Liste der Behörden noch einmal ausdrucken, sollte jetzt ein Schlüssel registriert sein:
gcloud container binauthz attestors list
Signierte Attestierung erstellen
Jetzt haben Sie die Funktionen konfiguriert, mit denen Sie Bilder signieren können. Mit dem zuvor erstellten Attestierer das Container-Image signieren, mit dem Sie gearbeitet haben
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
--format='get(image_summary.digest)')
Jetzt können Sie die Attestierung mit gcloud erstellen. Der Befehl gibt einfach die Details des Schlüssels an, den Sie zum Signieren verwenden möchten, und das spezifische Container-Image, das Sie genehmigen möchten
gcloud beta container binauthz attestations sign-and-create \
--artifact-url="${CONTAINER_PATH}@${DIGEST}" \
--attestor="${ATTESTOR_ID}" \
--attestor-project="${PROJECT_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
In Container Analysis wird damit ein neues Vorkommen erstellt und an den Hinweis des Attestierers angehängt. Sie können Ihre Attestierungen auflisten, um sicherzustellen, dass alles wie erwartet funktioniert hat
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. Mit Cloud Build signieren
Sie haben die Image-Signatur aktiviert und manuell den Attestierer verwendet, um Ihr Beispiel-Image zu signieren. In der Praxis sollten Sie Attestierungen während automatisierter Prozesse wie CI/CD-Pipelines anwenden.
In diesem Abschnitt konfigurieren Sie Cloud Build so, dass Images automatisch attestiert werden.
Rollen
Fügen Sie dem Cloud Build-Dienstkonto die Rolle "Betrachter der Attestierer von Binärautorisierungen" hinzu:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
Fügen Sie dem Cloud Build-Dienstkonto (KMS-basierte Signatur) die Rolle "Cloud KMS CryptoKey-Signer/Prüffunktion" hinzu:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
Fügen Sie dem Cloud Build-Dienstkonto die Rolle "Hinzufüger von Container Analysis-Hinweisen" hinzu:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
Benutzerdefinierten Cloud Build-Schritt vorbereiten
Sie verwenden einen benutzerdefinierten Build-Schritt in Cloud Build, um den Attestierungsprozess zu vereinfachen. Google bietet diesen benutzerdefinierten Build-Schritt mit Hilfsfunktionen zur Rationalisierung des Prozesses. Vor der Verwendung muss der Code für den benutzerdefinierten Build-Schritt in einen Container eingebunden und an Cloud Build übertragen werden. Führen Sie dazu die folgenden Befehle aus:
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community
Signierschritt zu cloudbuild.yaml hinzufügen
In diesem Schritt fügen Sie der zuvor erstellten Cloud Build-Pipeline den Attestierungsschritt hinzu.
- Sehen Sie sich den neuen Schritt an, den Sie hinzufügen werden.
Nur Rezension. Nicht kopieren
#Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
- Überschreiben Sie Ihre cloudbuild.yaml-Datei mit der aktualisierten vollständigen Pipeline.
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']
#Sign the image only if the previous severity check passes
- id: 'create-attestation'
name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
args:
- '--artifact-url'
- 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
- '--attestor'
- 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
- '--keyversion'
- 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
images:
- us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF
Build ausführen
gcloud builds submit
Build im Cloud Build-Verlauf überprüfen
Öffnen Sie in der Cloud Console die Seite Cloud Build-Verlauf und prüfen Sie den neuesten Build und die erfolgreiche Ausführung der Build-Schritte.
8. Zugangskontrollrichtlinien
Die Binärautorisierung ist ein Feature in GKE und Cloud Run, mit dem Regeln validiert werden können, bevor ein Container-Image ausgeführt werden darf. Die Validierung wird bei jeder Anfrage ausgeführt, um ein Image auszuführen, sei es von einer vertrauenswürdigen CI/CD-Pipeline oder von einem Nutzer, der manuell versucht, ein Image bereitzustellen. Mit dieser Funktion können Sie Ihre Laufzeitumgebungen effektiver schützen als mit CI/CD-Pipelineprüfungen allein.
Damit Sie diese Funktion besser verstehen können, ändern Sie die GKE-Standardrichtlinie, um eine strenge Autorisierungsregel zu erzwingen.
GKE-Cluster erstellen
Erstellen Sie den GKE-Cluster:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
Erlauben Sie Cloud Build die Bereitstellung in diesem Cluster:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
Alle Richtlinien zulassen
Prüfen Sie zuerst den Standardstatus der Richtlinie und Ihre Fähigkeit, ein beliebiges Image bereitzustellen
- Vorhandene Richtlinie überprüfen
gcloud container binauthz policy export
- Beachten Sie, dass die Erzwingungsrichtlinie auf „
ALWAYS_ALLOW
“ festgelegt ist
evaluationMode: ALWAYS_ALLOW
- Beispiel bereitstellen, um zu prüfen, ob alles bereitgestellt werden kann
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Prüfen, ob die Bereitstellung funktioniert hat
kubectl get pods
Sie sehen die folgende Ausgabe
- Deployment löschen
kubectl delete pod hello-server
Alle Richtlinien ablehnen
Aktualisieren Sie jetzt die Richtlinie, um alle Bilder nicht mehr zuzulassen.
- Aktuelle Richtlinie in eine bearbeitbare Datei exportieren
gcloud container binauthz policy export > policy.yaml
- Richtlinie ändern
Ändern Sie in einem Texteditor den Auswertungsmodus von ALWAYS_ALLOW in ALWAYS_DENY.
edit policy.yaml
Die YAML-Richtliniendatei sollte so aussehen:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Öffnen Sie das Terminal, wenden Sie die neue Richtlinie an. Warten Sie dann einige Sekunden, bis die Änderung wirksam wird.
gcloud container binauthz policy import policy.yaml
- Beispiel für die Arbeitslastbereitstellung versuchen
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Die Bereitstellung schlägt mit der folgenden Meldung fehl
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule
Setzen Sie die Richtlinie zurück, um alle zuzulassen
Machen Sie die Richtlinienänderungen rückgängig, bevor Sie mit dem nächsten Abschnitt fortfahren.
- Richtlinie ändern
Ändern Sie in einem Texteditor den Auswertungsmodus von ALWAYS_DENY in ALWAYS_ALLOW.
edit policy.yaml
Die YAML-Richtliniendatei sollte so aussehen:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Wiederhergestellte Richtlinie anwenden
gcloud container binauthz policy import policy.yaml
9. Sicherheitslücken in GKE blockieren
In diesem Abschnitt kombinieren Sie das bisher Gelernte, indem Sie eine CI/CD-Pipeline mit Cloud Build implementieren. Diese scannt die Images und prüft diese auf Sicherheitslücken, bevor Sie das Image signieren und bereitstellen. GKE prüft mithilfe der Binärautorisierung, ob das Image eine Signatur aus dem Scannen auf Sicherheitslücken hat, bevor das Image ausgeführt werden kann.
GKE-Richtlinie so aktualisieren, dass eine Bestätigung erforderlich ist
Erforderliche Images müssen von Ihrem Attestierer signiert sein. Dazu fügen Sie Ihrer GKE-BinAuth-Richtlinie clusterAdmissionRules hinzu.
Überschreiben Sie die Richtlinie mit der aktualisierten Konfiguration mithilfe des folgenden Befehls.
COMPUTE_ZONE=us-central1-a
cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
${COMPUTE_ZONE}.binauthz:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM
Richtlinie anwenden
gcloud beta container binauthz policy import binauth_policy.yaml
Versuchen, das unsignierte Image bereitzustellen
Erstellen Sie mit dem folgenden Befehl einen Bereitstellungsdeskriptor für die zuvor erstellte Anwendung. Das hier verwendete Image ist das Image, das Sie zuvor erstellt haben. Es enthält kritische Sicherheitslücken und NICHT die signierte Attestierung.
GKE-Admission-Controller müssen das genaue Image kennen, das bereitgestellt werden soll, um die Signatur einheitlich validieren zu können. Um dies zu erreichen, müssen Sie den Image-Digest und ein einfaches Tag verwenden.
Image-Digest für schlechtes Image abrufen
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
--format='get(image_summary.digest)')
Digest in der Kubernetes-Konfiguration verwenden
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
Versuchen, die Anwendung in GKE bereitzustellen
kubectl apply -f deploy.yaml
Überprüfen Sie die Arbeitslast in der Console und sehen Sie sich den Fehler an, der besagt, dass die Bereitstellung abgelehnt wurde:
No attestations found that were valid and signed by a key trusted by the attestor
Signiertes Image bereitstellen
Image-Digest für schlechtes Image abrufen
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
--format='get(image_summary.digest)')
Digest in der Kubernetes-Konfiguration verwenden
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
Anwendung in GKE bereitstellen
kubectl apply -f deploy.yaml
Überprüfen Sie die Arbeitslast in der Console und notieren Sie die erfolgreiche Bereitstellung des Images.
10. Glückwunsch!
Glückwunsch, du hast das Codelab abgeschlossen.
Behandelte Themen:
- Automatisches Scannen aktivieren
- On-Demand-Scans durchführen
- Scannen in eine Build-Pipeline einbinden
- Genehmigte Bilder signieren
- GKE-Admission-Controller zum Blockieren von Images verwenden
- GKE so konfigurieren, dass nur signierte genehmigte Images zugelassen werden
Nächste Schritte:
- Image-Bereitstellungen in Cloud Run und Google Kubernetes Engine sichern | Cloud Build-Dokumentation
- Kurzanleitung: Richtlinie für die Binärautorisierung mit GKE konfigurieren | Google Cloud
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.