1. Einführung
Mit der Binärautorisierung wird die Sicherheit beim Deployment überprüft. So können Sie dafür sorgen, dass nur vertrauenswürdige Container-Images in der Google Kubernetes Engine (GKE) oder Cloud Run bereitgestellt werden. Sie können dabei festlegen, dass die Images während des Entwicklungsprozesses von vertrauenswürdigen Stellen signiert werden, und dann beim Deployment die Signaturprüfung erzwingen. Damit haben Sie eine stärkere Kontrolle über die Containerumgebung und sorgen dafür, dass nur verifizierte Images in den Build- und Release-Prozess eingebunden werden.
Das folgende Diagramm zeigt die Komponenten einer Binärautorisierung/Cloud Build-Einrichtung:
**Abbildung 1.**Cloud Build-Pipeline, die eine Attestierung für die Binärautorisierung erstellt.
In dieser Pipeline gilt:
- Code zum Erstellen des Container-Images wird an ein Quell-Repository wie Cloud Source Repositories übertragen.
- Cloud Build ist ein Tool für Continuous Integration (CI), erstellt und testet den Container.
- Der Build überträgt das Container-Image per Push in Container Registry oder eine andere Registry, in der die erstellten Images gespeichert sind.
- Der Cloud Key Management Service bietet eine Schlüsselverwaltung für das kryptografische Schlüsselpaar und signiert das Container-Image. Die resultierende Signatur wird dann in einer neu erstellten Attestierung gespeichert.
- Zum Zeitpunkt der Bereitstellung überprüft der Attestierer die Attestierung mithilfe des öffentlichen Schlüssels aus dem Schlüsselpaar. Die Binärautorisierung erzwingt die Richtlinie, indem zum Bereitstellen des Container-Images signierte Attestierungen erforderlich sind.
In diesem Lab konzentrieren Sie sich auf die Tools und Techniken zum Schutz bereitgestellter Artefakte. In diesem Lab geht es um Artefakte (Container), die erstellt, aber nicht in einer bestimmten Umgebung bereitgestellt wurden.
Aufgaben in diesem Lab
- Bildsignatur
- Zugangskontrollrichtlinien
- Gescannte Bilder signieren
- Signierte Bilder autorisieren
- Blockierte Images ohne Signatur
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.
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
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 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
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.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
3. Bildsignatur
Was ist ein Attestierer?
Attestierer
- Diese Person bzw. dieser Prozess ist für ein Glied in der Vertrauenskette des Systems verantwortlich.
- Sie haben einen kryptografischen Schlüssel und signieren ein Bild, wenn es den Genehmigungsprozess besteht.
- Der Policy Creator legt die Richtlinien auf übergeordneter und abstrakter Weise fest. Der Attestierer ist jedoch dafür verantwortlich, einen Aspekt der Richtlinie konkret durchzusetzen.
- Dabei kann es sich um eine echte Person wie ein QA-Tester oder einen Manager oder um einen Bot in einem CI-System handeln.
- Die Sicherheit des Systems hängt von seiner Vertrauenswürdigkeit ab. Daher ist es wichtig, dass die privaten Schlüssel sicher aufbewahrt werden.
Jede dieser Rollen kann eine einzelne Person oder ein Team von Personen in Ihrer Organisation repräsentieren. In einer Produktionsumgebung werden diese Rollen wahrscheinlich von separaten Google Cloud Platform-Projekten (GCP) verwaltet und der Zugriff auf Ressourcen wird eingeschränkt über Cloud IAM zwischen ihnen geteilt.
Attestierer in der Binärautorisierung werden zusätzlich zur Cloud Container Analysis API implementiert. Daher ist es wichtig zu beschreiben, wie das funktioniert, bevor Sie fortfahren. Mit der Container Analysis API können Sie Metadaten bestimmten Container-Images zuordnen.
Beispielsweise kann eine Notiz erstellt werden, um die Sicherheitslücke Herzblutend zu verfolgen. Sicherheitsanbieter erstellten dann Scanner, um Container-Images auf die Sicherheitslücke zu testen, und erstellten ein Vorkommen, das jedem manipulierten Container zugeordnet ist.
Container Analysis wurde zusammen mit dem Tracking von Sicherheitslücken als generische Metadaten-API entwickelt. Bei der Binärautorisierung werden mithilfe von Container Analysis Signaturen den zu überprüfenden Container-Images zugeordnet.** Ein Container Analysis-Hinweis wird für einen einzelnen Attestierer verwendet. Vorkommen werden erstellt und mit jedem Container verknüpft, der vom Attestierer genehmigt wurde.
Die Binary Authorization API verwendet das Konzept der „Attestierer“ und "Attestierungen". Diese werden jedoch mit entsprechenden Hinweisen und Vorkommen in der Container Analysis API implementiert.
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}"
Ihre Notiz wird jetzt in der Container Analysis API gespeichert.
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. Damit Sie den Attestierer verwenden können, müssen Sie den Hinweis auch bei der Binärautorisierung registrieren:
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
Bevor Sie diesen Attestierer verwenden können, muss Ihre Behörde ein kryptografisches Schlüsselpaar erstellen, mit dem Container-Images signiert werden können. Dies kann über den Google Cloud Key Management Service (KMS) erfolgen.
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. Verwenden Sie den zuvor erstellten Attestierer, um das Container-Image zu signieren, mit dem Sie gearbeitet haben.
Eine Attestierung muss eine kryptografische Signatur enthalten, die angibt, dass der Attestierer ein bestimmtes Container-Image verifiziert hat und sicher auf Ihrem Cluster ausgeführt werden kann. Um anzugeben, welches Container-Image attestiert werden soll, müssen Sie den zugehörigen Digest ermitteln.
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}
4. 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 mit aktivierter Binärautorisierung:
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
Diese Richtlinie ist relativ einfach. In der Zeile globalPolicyEvaluationMode wird deklariert, dass diese Richtlinie die von Google definierte globale Richtlinie erweitert. Dadurch können alle offiziellen GKE-Container standardmäßig ausgeführt werden. Außerdem deklariert die Richtlinie eine defaultAdmissionRule, die angibt, dass alle anderen Pods abgelehnt werden. Die Zulassungsregel enthält die Zeile enforcementMode, die angibt, dass alle Pods, die nicht dieser Regel entsprechen, für den Cluster blockiert werden sollen.
Eine Anleitung zum Erstellen komplexerer Richtlinien finden Sie in der Dokumentation zur Binärautorisierung.
- Ö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
5. Gescannte Bilder 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
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"
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 Cloud Build-Pipeline den Attestierungsschritt hinzu.
- Lies dir den folgenden Schritt zur Signatur durch.
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'
- Schreiben Sie eine cloudbuild.yaml-Datei mit der vollständigen Pipeline unten.
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.
6. Signierte Bilder autorisieren
In diesem Abschnitt aktualisieren Sie die GKE so, dass mit der Binärautorisierung geprüft wird, 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.
Derzeit wird in Ihrem Cluster eine Richtlinie mit einer Regel ausgeführt: Container aus offiziellen Repositories zulassen und alle anderen ablehnen.
Ü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
Auf dem Laufwerk sollte jetzt eine neue Datei mit dem Namen " updated_policy.yaml" vorhanden sein. Anstatt jetzt alle Images abzulehnen, prüft die Standardregel zuerst Ihren Attestierer auf Überprüfungen.
Laden Sie die neue Richtlinie in die Binärautorisierung hoch:
gcloud beta container binauthz policy import binauth_policy.yaml
Signiertes Image bereitstellen
Image-Digest für das gute 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.
7. Blockierte Images ohne Signatur
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:bad .
Unsigniertes Image in das Repository übertragen
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
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
8. Glückwunsch!
Glückwunsch, du hast das Codelab abgeschlossen.
Behandelte Themen:
- Bildsignatur
- Zugangskontrollrichtlinien
- Gescannte Bilder signieren
- Signierte Bilder autorisieren
- Blockierte Images ohne Signatur
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.
–
Letzte Aktualisierung: 21.03.2023