1. Wprowadzenie
Container Analysis udostępnia skanowanie kontenerów pod kątem luk w zabezpieczeniach i przechowywanie metadanych kontenerów. Usługa skanowania przeprowadza skanowanie pod kątem luk w zabezpieczeniach obrazów w Artifact Registry i Container Registry, a następnie przechowuje uzyskane metadane i udostępnia je do wykorzystania za pomocą interfejsu API. Przechowywanie metadanych umożliwia przechowywanie informacji z różnych źródeł, w tym skanowania pod kątem luk w zabezpieczeniach, usług Google Cloud i dostawców zewnętrznych.
Skanowanie pod kątem luk w zabezpieczeniach może odbywać się automatycznie lub na żądanie:
- Gdy automatyczne skanowanie jest włączone, skanowanie jest uruchamiane automatycznie za każdym razem, gdy przesyłasz nowy obraz do Artifact Registry lub Container Registry. Informacje o lukach w zabezpieczeniach są stale aktualizowane, gdy zostaną wykryte nowe luki.
- Gdy włączone jest skanowanie na żądanie, musisz uruchomić polecenie, aby przeskanować obraz lokalny lub obraz w Artifact Registry lub Container Registry. Skanowanie na żądanie zapewnia elastyczność w zakresie czasu skanowania kontenerów. Możesz na przykład przeskanować obraz utworzony lokalnie i usunąć luki w zabezpieczeniach przed zapisaniem go w rejestrze. Wyniki skanowania są dostępne do 48 godzin po jego zakończeniu, a informacje o lukach w zabezpieczeniach nie są aktualizowane po skanowaniu.
Dzięki integracji analizy kontenerów z potokiem CI/CD możesz podejmować decyzje na podstawie tych metadanych. Możesz na przykład użyć Binary Authorization, aby utworzyć zasady wdrażania, które zezwalają tylko na wdrażanie zgodnych obrazów z zaufanych rejestrów.
Czego się nauczysz
- Jak włączyć automatyczne skanowanie
- Jak przeprowadzić skanowanie na żądanie
- Jak zintegrować skanowanie z potokiem kompilacji
- Jak podpisywać zatwierdzone obrazy
- Jak używać kontrolerów dostępu GKE do blokowania obrazów
- Konfigurowanie GKE, aby zezwalać tylko na podpisane zatwierdzone obrazy
2. Konfiguracja i wymagania
Samodzielne konfigurowanie środowiska
- Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.



- Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Możesz ją zaktualizować w dowolnym momencie.
- Identyfikator projektu jest unikalny we wszystkich projektach Google Cloud i nie można go zmienić po ustawieniu. Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się nim przejmować. W większości ćwiczeń z programowania musisz odwoływać się do identyfikatora projektu (zwykle jest on oznaczony jako
PROJECT_ID). Jeśli wygenerowany identyfikator Ci się nie podoba, możesz wygenerować inny losowy identyfikator. Możesz też spróbować własnej nazwy i sprawdzić, czy jest dostępna. Po tym kroku nie można go zmienić i będzie obowiązywać przez cały czas trwania projektu. - Warto wiedzieć, że istnieje też trzecia wartość, czyli numer projektu, z której korzystają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Ukończenie tego laboratorium nie powinno wiązać się z dużymi kosztami, a nawet z żadnymi. Aby wyłączyć zasoby i uniknąć naliczania opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub cały projekt. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.
Uruchamianie edytora Cloud Shell
To laboratorium zostało zaprojektowane i przetestowane pod kątem używania w edytorze Google Cloud Shell. Aby uzyskać dostęp do edytora:
- uzyskać dostęp do projektu Google na stronie https://console.cloud.google.com;
- W prawym górnym rogu kliknij ikonę edytora Cloud Shell.

- U dołu okna otworzy się nowy panel.
Konfiguracja środowiska
W Cloud Shell ustaw identyfikator projektu i numer projektu. Zapisz je jako zmienne PROJECT_ID i PROJECT_ID.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
Włączanie usług
Włącz wszystkie niezbędne usługi:
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
Tworzenie repozytorium Artifact Registry
W tym laboratorium będziesz używać Artifact Registry do przechowywania i skanowania obrazów. Utwórz repozytorium za pomocą tego polecenia.
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
Skonfiguruj Dockera tak, aby podczas uzyskiwania dostępu do Artifact Registry korzystał z Twoich danych logowania gcloud.
gcloud auth configure-docker us-central1-docker.pkg.dev
3. Automatyczne skanowanie
Skanowanie artefaktów jest uruchamiane automatycznie za każdym razem, gdy przesyłasz nowy obraz do Artifact Registry lub Container Registry. Informacje o lukach w zabezpieczeniach są stale aktualizowane, gdy zostaną wykryte nowe luki. W tej sekcji prześlesz obraz do Artifact Registry i zapoznasz się z wynikami.
Tworzenie katalogu roboczego i przechodzenie do niego
mkdir vuln-scan && cd vuln-scan
Określanie przykładowego obrazu
Utwórz plik o nazwie Dockerfile z tą zawartością.
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
Utwórz plik o nazwie main.py z tą zawartością:
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
Tworzenie i przekazywanie obrazu do AR
Użyj Cloud Build, aby utworzyć kontener i automatycznie przesłać go do Artifact Registry. Zwróć uwagę na tag bad na obrazie. Pomoże Ci to zidentyfikować go w kolejnych krokach.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
Sprawdzanie szczegółów obrazu
Po zakończeniu procesu kompilacji przejrzyj obraz i wyniki skanowania pod kątem luk w zabezpieczeniach w panelu Artifact Registry.
- Otwórz Artifact Registry w Cloud Console.
- Kliknij repozytorium skanowania artefaktów, aby wyświetlić jego zawartość.
- Kliknij szczegóły obrazu.
- Kliknij najnowsze podsumowanie obrazu
- Po zakończeniu skanowania kliknij kartę luk w zabezpieczeniach dla obrazu.
Na karcie luk w zabezpieczeniach zobaczysz wyniki automatycznego skanowania utworzonego właśnie obrazu.

Automatyzacja skanowania jest domyślnie włączona. Zapoznaj się z ustawieniami Artifact Registry, aby dowiedzieć się, jak włączyć lub wyłączyć automatyczne skanowanie.
4. Skanowanie na żądanie
Istnieją różne scenariusze, w których przed przekazaniem obrazu do repozytorium musisz przeprowadzić skanowanie. Na przykład programista kontenerów może przeskanować obraz i rozwiązać problemy przed przesłaniem kodu do kontroli źródła. W przykładzie poniżej skompilujesz i przeanalizujesz obraz lokalnie, zanim podejmiesz działania na podstawie wyników.
Tworzenie obrazu
W tym kroku użyjesz lokalnego Dockera, aby utworzyć obraz w lokalnej pamięci podręcznej.
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .
Skanowanie obrazu
Po utworzeniu obrazu poproś o jego skanowanie. Wyniki skanowania są przechowywane na serwerze metadanych. Zadanie kończy się lokalizacją wyników na serwerze metadanych.
gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--format="value(response.scan)" > scan_id.txt
Sprawdzanie pliku wyjściowego
Poświęć chwilę na przejrzenie wyników poprzedniego kroku, które zostały zapisane w pliku scan_id.txt. Zwróć uwagę na lokalizację raportu z wynikami skanowania na serwerze metadanych.
cat scan_id.txt
Sprawdzanie szczegółowych wyników skanowania
Aby wyświetlić rzeczywiste wyniki skanowania, użyj polecenia list-vulnerabilities w lokalizacji raportu podanej w pliku wyjściowym.
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt)
Dane wyjściowe zawierają znaczną ilość informacji o wszystkich lukach w zabezpieczeniach obrazu.
Oznaczanie problemów krytycznych
Ludzie rzadko korzystają bezpośrednio z danych przechowywanych w raporcie. Wyniki są zwykle wykorzystywane przez proces automatyczny. Użyj poniższych poleceń, aby odczytać szczegóły raportu i zarejestrować informacje o znalezionych krytycznych lukach w zabezpieczeniach.
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
Wynik tego polecenia będzie następujący:
Failed vulnerability check for CRITICAL level
5. Skanowanie potoku kompilacji
W tej sekcji utworzysz automatyczny potok kompilacji, który skompiluje obraz kontenera, przeskanuje go, a następnie oceni wyniki. Jeśli nie zostaną znalezione żadne luki w zabezpieczeniach o krytycznym znaczeniu, obraz zostanie przesłany do repozytorium. Jeśli zostaną znalezione luki w zabezpieczeniach o krytycznym poziomie ważności, kompilacja zakończy się niepowodzeniem.
Przyznawanie dostępu kontu usługi Cloud Build
Cloud Build będzie potrzebować uprawnień dostępu do interfejsu API skanowania na żądanie. Udziel dostępu za pomocą tych poleceń.
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"
Tworzenie potoku Cloud Build
To polecenie utworzy w Twoim katalogu plik cloudbuild.yaml, który będzie używany w procesie automatycznym. W tym przykładzie czynności są ograniczone do procesu kompilacji kontenera. W praktyce jednak oprócz kroków dotyczących kontenera należy uwzględnić instrukcje i testy dotyczące konkretnej aplikacji.
Utwórz plik za pomocą tego polecenia.
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
Uruchamianie potoku CI
Prześlij kompilację do przetworzenia, aby sprawdzić, czy kompilacja ulegnie uszkodzeniu po wykryciu luki w zabezpieczeniach o krytycznym poziomie ważności.
gcloud builds submit
Nie udało się skompilować wersji do sprawdzenia
Przesłana kompilacja nie zostanie zaakceptowana, ponieważ obraz zawiera KRYTYCZNE luki w zabezpieczeniach.
Sprawdź błąd kompilacji na stronie Historia Cloud Build.
Naprawianie luki w zabezpieczeniach
Zaktualizuj plik Dockerfile, aby używać obrazu podstawowego, który nie zawiera krytycznych luk w zabezpieczeniach.
Zastąp Dockerfile, aby używać obrazu Debian 10, za pomocą tego polecenia:
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
Uruchom proces CI z prawidłowym obrazem
Prześlij kompilację do przetworzenia, aby sprawdzić, czy zakończy się ona powodzeniem, gdy nie zostaną znalezione luki w zabezpieczeniach o krytycznym poziomie ważności.
gcloud builds submit
Sprawdzanie powodzenia kompilacji
Przesłana kompilacja zakończy się powodzeniem, ponieważ zaktualizowany obraz nie zawiera krytycznych luk w zabezpieczeniach.
Sprawdź, czy kompilacja zakończyła się sukcesem na stronie Historia Cloud Build.
Sprawdzanie wyników skanowania
Sprawdź prawidłowy obraz w Artifact Registry.
- Otwórz Artifact Registry w Cloud Console.
- Kliknij repozytorium skanowania artefaktów, aby wyświetlić jego zawartość.
- Kliknij szczegóły obrazu.
- Kliknij najnowsze podsumowanie obrazu
- Kliknij kartę luk w zabezpieczeniach obrazu.
6. Podpisywanie obrazów
Tworzenie notatki atestatora
Notatka atestatora to po prostu niewielki fragment danych, który pełni funkcję etykiety dla typu stosowanego podpisu. Na przykład jedna notatka może dotyczyć skanowania pod kątem luk w zabezpieczeniach, a inna może być używana do zatwierdzania kontroli jakości. Notatka będzie używana podczas procesu podpisywania.
Tworzenie notatki
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
Zapisywanie notatki
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}"
Weryfikacja notatki
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
Tworzenie atestatora
Atestatory służą do przeprowadzania procesu podpisywania obrazu i dołączają do niego wystąpienie notatki w celu późniejszej weryfikacji. Utwórz atestatora do późniejszego użycia.
Utwórz atestator
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
Weryfikowanie atestatora
gcloud container binauthz attestors list
Zwróć uwagę, że ostatni wiersz wskazuje, że NUM_PUBLIC_KEYS: 0klucze podasz w późniejszym kroku.
Pamiętaj też, że Cloud Build automatycznie tworzy w Twoim projekcie built-by-cloud-build atestatora, gdy uruchamiasz kompilację, która generuje obrazy. Powyższe polecenie zwraca więc 2 potwierdzających: vulnz-attestor i built-by-cloud-build. Po pomyślnym utworzeniu obrazów Cloud Build automatycznie je podpisuje i tworzy dla nich atesty.
Dodawanie roli uprawnień
Konto usługi Binary Authorization musi mieć uprawnienia do wyświetlania notatek atestu. Przyznaj dostęp za pomocą tego wywołania interfejsu API
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
Użyj pliku do utworzenia zasady uprawnień
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"
Dodawanie klucza KMS
Aby dołączyć notatkę i zapewnić weryfikowalne podpisy, podmiot potwierdzający potrzebuje kluczy kryptograficznych. W tym kroku utworzysz i zapiszesz klucze w KMS, aby Cloud Build mógł do nich później uzyskać dostęp.
Najpierw dodaj zmienne środowiskowe, aby opisać nowy klucz.
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
Utwórz pęk kluczy, aby przechowywać zestaw kluczy
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
Utwórz nową asymetryczną parę kluczy podpisywania dla atestatora.
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
Klucz powinien być widoczny na stronie KMS w konsoli Google Cloud.
Teraz powiąż klucz z atestatorem za pomocą polecenia gcloud binauthz:
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}"
Jeśli ponownie wyświetlisz listę organów, powinien być widoczny zarejestrowany klucz:
gcloud container binauthz attestors list
Tworzenie podpisanego atestu
Na tym etapie masz już skonfigurowane funkcje, które umożliwiają podpisywanie obrazów. Użyj utworzonego wcześniej atestatora, aby podpisać obraz kontenera, z którym pracujesz.
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)')
Teraz możesz użyć gcloud do utworzenia atestu. Polecenie po prostu przyjmuje szczegóły klucza, którego chcesz użyć do podpisywania, oraz konkretny obraz kontenera, który chcesz zatwierdzić.
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}"
W terminologii Container Analysis spowoduje to utworzenie nowego wystąpienia i dołączenie go do notatki atestatora. Aby upewnić się, że wszystko działa zgodnie z oczekiwaniami, możesz wyświetlić listę swoich zaświadczeń.
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. Podpisywanie za pomocą Cloud Build
Masz włączone podpisywanie obrazów i ręcznie używasz atestatora, aby podpisać przykładowy obraz. W praktyce będziesz stosować atesty w procesach zautomatyzowanych, takich jak potoki CI/CD.
W tej sekcji skonfigurujesz Cloud Build do automatycznego potwierdzania obrazów.
Role
Dodaj rolę wyświetlającego atestatory autoryzacji plików binarnych do konta usługi Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
Dodaj rolę Podpisujący/weryfikujący klucze CryptoKey Cloud KMS do konta usługi Cloud Build (podpisywanie oparte na KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
Dodaj rolę dodającego notatki analizy kontenera do konta usługi Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
Przygotowywanie niestandardowego kroku kompilacji Cloud Build
Aby uprościć proces atestowania, użyjesz niestandardowego kroku kompilacji w Cloud Build. Google udostępnia ten krok kompilacji niestandardowej, który zawiera funkcje pomocnicze ułatwiające ten proces. Przed użyciem kod niestandardowego kroku kompilacji musi zostać skompilowany w kontenerze i przesłany do Cloud Build. Aby to zrobić, uruchom te polecenia:
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
Dodawanie kroku podpisywania do pliku cloudbuild.yaml
W tym kroku dodasz krok atestowania do utworzonego wcześniej potoku Cloud Build.
- Sprawdź nowy krok, który chcesz dodać.
Tylko do wglądu. Nie kopiuj
#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'
- Zastąp plik cloudbuild.yaml zaktualizowaną kompletną ścieżką.
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
Uruchamianie kompilacji
gcloud builds submit
Sprawdź kompilację w historii Cloud Build
Otwórz konsolę Cloud na stronie Historia Cloud Build i sprawdź najnowszą kompilację oraz prawidłowe wykonanie kroków kompilacji.
8. Zasady kontroli ruchu przychodzącego
Binary Authorization to funkcja GKE i Cloud Run, która umożliwia weryfikację reguł przed uruchomieniem obrazu kontenera. Weryfikacja jest przeprowadzana w przypadku każdej prośby o uruchomienie obrazu, niezależnie od tego, czy pochodzi ona z zaufanego potoku CI/CD, czy od użytkownika, który ręcznie próbuje wdrożyć obraz. Ta funkcja pozwala skuteczniej zabezpieczać środowiska wykonawcze niż same kontrole potoku CI/CD.
Aby poznać tę funkcję, zmodyfikujesz domyślne zasady GKE, aby wymusić ścisłą regułę autoryzacji.
Tworzenie klastra GKE
Utwórz klaster GKE:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
Zezwól Cloud Build na wdrażanie w tym klastrze:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
Zasada zezwalająca na wszystko
Najpierw sprawdź domyślny stan zasad i możliwość wdrażania dowolnego obrazu.
- Sprawdzanie istniejących zasad
gcloud container binauthz policy export
- Zwróć uwagę, że zasada egzekwowania jest ustawiona na
ALWAYS_ALLOW.
evaluationMode: ALWAYS_ALLOW
- Wdróż próbkę, aby sprawdzić, czy możesz wdrożyć dowolny element.
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Sprawdzanie, czy wdrożenie zadziałało
kubectl get pods
Zobaczysz te dane wyjściowe:

- Usuń wdrożenie
kubectl delete pod hello-server
Zasada odrzucania wszystkich
Teraz zaktualizuj zasadę, aby zabronić wyświetlania wszystkich obrazów.
- Eksportowanie bieżących zasad do edytowalnego pliku
gcloud container binauthz policy export > policy.yaml
- Zmień zasadę
W edytorze tekstu zmień wartość evaluationMode z ALWAYS_ALLOW na ALWAYS_DENY.
edit policy.yaml
Plik YAML zasad powinien wyglądać tak:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Otwórz Terminal i zastosuj nowe zasady. Zaczekaj kilka sekund, aż zmiana zostanie wprowadzona.
gcloud container binauthz policy import policy.yaml
- Wypróbuj wdrożenie przykładowego zadania
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Wdrożenie kończy się niepowodzeniem z tym komunikatem:
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
Przywróć zasadę zezwalającą na wszystko
Zanim przejdziesz do następnej sekcji, cofnij zmiany w zasadach.
- Zmień zasadę
W edytorze tekstu zmień wartość evaluationMode z ALWAYS_DENY na ALWAYS_ALLOW.
edit policy.yaml
Plik YAML zasad powinien wyglądać tak:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Zastosuj przywrócone zasady
gcloud container binauthz policy import policy.yaml
9. Blokowanie luk w zabezpieczeniach w GKE
W tej sekcji połączysz zdobytą wiedzę, wdrażając potok CI/CD w Cloud Build, który skanuje obrazy, a następnie sprawdza, czy nie zawierają luk w zabezpieczeniach, zanim podpisze obraz i spróbuje go wdrożyć. GKE użyje usługi Binary Authorization, aby sprawdzić, czy obraz ma podpis pochodzący ze skanowania pod kątem luk w zabezpieczeniach, zanim zezwoli na jego uruchomienie.

Aktualizowanie zasad GKE, aby wymagać atestu
Wymagaj, aby obrazy były podpisane przez atestatora, dodając do zasad BinAuth GKE reguły clusterAdmissionRules.
Zastąp zasadę zaktualizowaną konfiguracją za pomocą tego polecenia.
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
Stosowanie zasad
gcloud beta container binauthz policy import binauth_policy.yaml
Próba wdrożenia niepodpisanego obrazu
Utwórz deskryptor wdrożenia dla aplikacji utworzonej wcześniej za pomocą tego polecenia: Użyty tutaj obraz to utworzony wcześniej obraz, który zawiera krytyczne luki w zabezpieczeniach i NIE zawiera podpisanego atestu.
Kontrolery dostępu GKE muszą znać dokładny obraz, który ma zostać wdrożony, aby konsekwentnie weryfikować sygnaturę. Aby to zrobić, musisz użyć skrótu obrazu zamiast prostego tagu.
Pobieranie podsumowania obrazu dla nieodpowiedniego obrazu
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)')
Używanie skrótu w konfiguracji Kubernetes
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
Próba wdrożenia aplikacji w GKE
kubectl apply -f deploy.yaml
Sprawdź obciążenie w konsoli i zwróć uwagę na błąd informujący o odmowie wdrożenia:
No attestations found that were valid and signed by a key trusted by the attestor
Wdrażanie podpisanego obrazu
Pobieranie podsumowania obrazu dla nieodpowiedniego obrazu
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)')
Używanie skrótu w konfiguracji Kubernetes
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
Wdrażanie aplikacji w GKE
kubectl apply -f deploy.yaml
Sprawdź obciążenie w konsoli i zwróć uwagę na pomyślne wdrożenie obrazu.
10. Gratulacje!
Gratulacje! Codelab został ukończony.
Omówione zagadnienia:
- Jak włączyć automatyczne skanowanie
- Jak przeprowadzić skanowanie na żądanie
- Jak zintegrować skanowanie z potokiem kompilacji
- Jak podpisywać zatwierdzone obrazy
- Jak używać kontrolerów dostępu GKE do blokowania obrazów
- Konfigurowanie GKE, aby zezwalać tylko na podpisane zatwierdzone obrazy
Co dalej?
- Zabezpieczanie wdrożeń obrazów w Cloud Run i Google Kubernetes Engine | Dokumentacja Cloud Build
- Krótkie wprowadzenie: konfigurowanie zasady usługi Binary Authorization w GKE | Google Cloud
Czyszczenie danych
Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby zużyte w tym samouczku, możesz usunąć projekt zawierający te zasoby lub zachować projekt i usunąć poszczególne zasoby.
Usuwanie projektu
Najprostszym sposobem na uniknięcie płatności jest usunięcie projektu utworzonego w tym samouczku.