1. Wprowadzenie
Container Analysis umożliwia skanowanie pod kątem luk w zabezpieczeniach i przechowywanie metadanych kontenerów. Usługa skanowania wykonuje 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 użycia za pomocą interfejsu API. Przechowywanie metadanych umożliwia przechowywanie informacji z różnych źródeł, w tym z usług 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 uruchamia się 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 wykrywane są nowe luki.
- Gdy włączone jest skanowanie na żądanie, musisz uruchomić polecenie, aby zeskanować obraz lokalny lub obraz w Artifact Registry lub Container Registry. Skanowanie na żądanie zapewnia elastyczność w zakresie skanowania kontenerów. Możesz na przykład przeskanować obraz utworzony lokalnie i usunąć luki w zabezpieczeniach, zanim zapiszesz go w rejestrze. Wyniki skanowania są dostępne przez 48 godzin po zakończeniu skanowania, a informacje o lukach w zabezpieczeniach nie są aktualizowane po zakończeniu skanowania.
Dzięki temu, że usługa Container Analysis jest zintegrowana z Twoim kanałem CI/CD, możesz podejmować decyzje na podstawie tych metadanych. Możesz na przykład użyć autoryzacji plików binarnych, aby utworzyć zasady wdrażania, które zezwalają na wdrażanie tylko zgodnych obrazów z zaufanych rejestrów.
Czego się nauczysz
- Jak włączyć automatyczne skanowanie
- Jak wykonać skanowanie na żądanie
- Jak zintegrować skanowanie w przepływie tworzenia
- Jak podpisywać zatwierdzone obrazy
- Jak używać kontrolerów dostępu GKE do blokowania obrazów
- Jak skonfigurować GKE, aby zezwalać tylko na podpisane zatwierdzone obrazy
2. Konfiguracja i wymagania
Konfigurowanie środowiska we własnym tempie
- 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órego nie używają interfejsy API Google. Możesz ją zaktualizować w dowolnym momencie.
- Identyfikator projektu jest niepowtarzalny w ramach wszystkich projektów Google Cloud i nie można go zmienić (po ustawieniu). Cloud Console automatycznie generuje unikalny ciąg znaków. Zwykle nie ma znaczenia, jaki to ciąg. W większości laboratoriów z kodem musisz odwoływać się do identyfikatora projektu (zazwyczaj jest to
PROJECT_ID
). Jeśli nie podoba Ci się wygenerowany identyfikator, możesz wygenerować inny losowy. Możesz też spróbować użyć własnego adresu e-mail i sprawdzić, czy jest on dostępny. Po tym kroku nie można go zmienić. Pozostanie ona niezmieniona przez cały czas trwania projektu. - Informacyjnie: istnieje jeszcze 3 wartość, numer projektu, którego używają niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć rozliczenia w konsoli Cloud, aby korzystać z zasobów i interfejsów API Cloud. Przejście przez ten moduł Codelab nie powinno wiązać się z wielkimi kosztami, jeśli w ogóle z nimi będzie. Aby wyłączyć zasoby, aby nie generować opłat po zakończeniu 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
Ten moduł praktyczny został zaprojektowany i przetestowany pod kątem korzystania z edytora 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 powłoki chmury.
- Nowy panel otworzy się u dołu okna.
Konfiguracja środowiska
W Cloud Shell ustaw identyfikator 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 do przechowywania i skanowania obrazów użyjesz Artifact Registry. 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, aby używać danych logowania gcloud podczas uzyskiwania dostępu do Artifact Registry.
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 wykrywane są nowe luki. W tej sekcji prześlesz obraz do Artifact Registry i sprawdzisz wyniki.
Tworzenie katalogu roboczego i przechodzenie do niego
mkdir vuln-scan && cd vuln-scan
Definiowanie 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 skompilować i automatycznie przesłać kontener 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
Szczegóły obrazu
Po zakończeniu procesu kompilacji przejrzyj wyniki dotyczące obrazu i luk w zabezpieczeniach w panelu Artifact Registry.
- Otwórz Artifact Registry w konsoli Cloud
- Aby wyświetlić zawartość, kliknij repozytorium artifact-scanning-repo.
- Kliknij szczegóły obrazu.
- Kliknij najnowszy przegląd swojego obrazu.
- Po zakończeniu skanowania kliknij kartę z podanymi wrażliwościami obrazu.
Na karcie Luki w zabezpieczeniach zobaczysz wyniki automatycznego skanowania właśnie utworzonego obrazu.
Automatyczne skanowanie jest domyślnie włączone. W ustawieniach Artifact Registry dowiesz się, jak wyłączyć lub włączyć automatyczne skanowanie.
4. Skanowanie na żądanie
W różnych sytuacjach może być konieczne przeprowadzenie skanowania przed przesłaniem obrazu do repozytorium. Na przykład deweloper kontenera może zeskanować obraz i naprawić problemy, zanim przekaże kod do kontroli źródłowej. W przykładzie poniżej skompilujesz i przeanalizujesz obraz lokalnie, zanim wykorzystasz wyniki.
Kompilowanie obrazu
Na tym etapie użyjesz lokalnego Dockera do skompilowania obrazu do 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 zeskanowanie. Wyniki skanowania są przechowywane na serwerze metadanych. Zadanie kończy się z 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 sprawdzenie danych wyjściowych z poprzedniego kroku, które zostały zapisane w pliku scan_id.txt. Zwróć uwagę na lokalizację raportu wyników 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 miejscu raportu podanym w pliku wyjściowym.
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt)
Dane wyjściowe zawierają znaczną ilość danych o wszystkich lukach w zabezpieczeniach w obrazie.
Oznaczanie krytycznych problemów
Użytkownicy rzadko korzystają bezpośrednio z danych zapisanych w raporcie. Wyniki są zwykle wykorzystywane przez proces automatyczny. Aby odczytać szczegóły raportu i sprawdzać, czy znaleziono jakieś krytyczne luki, użyj poniższych poleceń.
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 taki:
Failed vulnerability check for CRITICAL level
5. Skanowanie potoku kompilacji
W tej sekcji utworzysz automatyczny potok kompilacji, który skompiluje obraz kontenera, zeskanuje go, a potem oceni wyniki. Jeśli nie zostaną znalezione żadne krytyczne luki, obraz zostanie przesłany do repozytorium. Jeśli zostaną znalezione luki CRITICAL, kompilacja zakończy się niepowodzeniem i zostanie zamknięta.
Przyznawanie dostępu do konta usługi Cloud Build
Cloud Build będzie potrzebować uprawnień dostępu do interfejsu skanowania na żądanie. Aby przyznać dostęp, użyj 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
Podane niżej polecenie utworzy w katalogu plik cloudbuild.yaml, który będzie używany w ramach procesu zautomatyzowanego. W tym przykładzie czynności ograniczają się do procesu kompilacji kontenera. W praktyce jednak oprócz instrukcji dotyczących kontenera należy dodać 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 się zatrzymuje, gdy zostanie znaleziona luka o poważnym stopniu zagrożenia.
gcloud builds submit
Niepowodzenie kompilacji opinii
Przesłany przez Ciebie pakiet nie zostanie zaakceptowany, 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 bazowego, który nie zawiera podatności na zagrożenia o krytycznym znaczeniu.
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 dobrym obrazem.
Prześlij kompilację do przetwarzania, aby sprawdzić, czy kompilacja zakończy się sukcesem, gdy nie zostaną znalezione żadne luki o poważnym stopniu zagrożenia.
gcloud builds submit
Sprawdzanie powodzenia kompilacji
Przesłany przez Ciebie pakiet zostanie zaakceptowany, ponieważ zaktualizowany obraz nie zawiera żadnych krytycznych luk w zabezpieczeniach.
Sprawdź, czy kompilacja się powiodła, na stronie Historia Cloud Build.
Sprawdzanie wyników skanowania
Sprawdź prawidłowy obraz w Artifact Registry.
- Otwórz Artifact Registry w konsoli Cloud
- Aby wyświetlić zawartość, kliknij repozytorium artifact-scanning-repo.
- Kliknij szczegóły obrazu.
- Kliknij najnowszy przegląd swojego obrazu.
- Kliknij kartę Luki w zabezpieczeniach obrazu.
6. Podpisywanie obrazów
Tworzenie notatki atestatora
Uwaga weryfikatora to po prostu niewielka ilość danych, która służy jako etykieta typu podpisu. Na przykład jedna uwaga może dotyczyć skanowania pod kątem podatności, a druga może być używana do zatwierdzenia kontroli jakości. Uwaga będzie się pojawiać 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}"
Sprawdź notatkę
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żywane do przeprowadzania procesu podpisywania obrazu i dołączają do obrazu notatkę na potrzeby późniejszej weryfikacji. Utwórz atestatora na potrzeby 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}
Weryfikacja atestatora
gcloud container binauthz attestors list
Ostatni wiersz wskazuje, że NUM_PUBLIC_KEYS: 0
klucze podasz w następnym kroku.
Pamiętaj też, że Cloud Build automatycznie tworzy w Twoim projekcie atestorów built-by-cloud-build
, gdy uruchamiasz kompilację, która generuje obrazy. Dlatego polecenie z powyższego przykładu zwraca 2 osoby potwierdzające: vulnz-attestor
i built-by-cloud-build
. Po pomyślnym skompilowaniu obrazów Cloud Build automatycznie podpisuje je i tworzy dla nich oświadczenia.
Dodawanie roli uprawnień
Konto usługi Binary Authorization będzie musiało mieć uprawnienia do wyświetlania notatek dotyczących uwierzytelniania. Zezwól na 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 załączyć notatkę i podać podpisy weryfikowalne, weryfikator musi mieć klucze kryptograficzne. Na tym etapie utworzysz i zapiszesz klucze w KMS, aby Cloud Build mógł z nich korzystać.
Najpierw dodaj zmienne środowiskowe, aby opisać nowy klucz
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
Tworzenie wieszaka na klucze
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
Utwórz nową parę kluczy podpisywania asymetrycznych dla weryfikatora
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
Klucz powinien pojawić się na stronie KMS w konsoli Google Cloud.
Teraz powiązać klucz z weryfikatorem 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 wydrukujesz listę urzędów ponownie, powinieneś zobaczyć zarejestrowany klucz:
gcloud container binauthz attestors list
Tworzenie podpisanego atestu
W tym momencie masz skonfigurowane funkcje, które umożliwiają podpisywanie obrazów. Użyj wcześniej utworzonego narzędzia Attestor do podpisania obrazu 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 utworzyć zaświadczenie za pomocą gcloud. Polecenie zawiera informacje o kluczu, którego chcesz użyć do podpisywania, oraz informacje o konkretnym obrazie 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 weryfikatora. Aby mieć pewność, że wszystko działa zgodnie z oczekiwaniami, możesz wyświetlić swoje oświadczenia
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. Podpisywanie za pomocą Cloud Build
masz włączone podpisywanie obrazu i ręcznie używasz narzędzia Attestor do podpisywania przykładowego obrazu. W praktyce warto stosować uwierzytelnienia podczas zautomatyzowanych procesów, takich jak potoki CI/CD.
W tej sekcji skonfigurujesz Cloud Build tak, aby automatycznie weryfikował obrazy.
Role
Dodaj do konta usługi Cloud Build rolę Weryfikator autoryzacji plików binarnych (podgląd):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
Dodaj do konta usługi Cloud Build rolę Podpisujący/weryfikujący klucze CryptoKey Cloud KMS (podpisywanie na podstawie KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
Dodaj do konta usługi Cloud Build rolę dodający notatki analizy kontenera:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
Przygotuj krok niestandardowego procesu tworzenia w Cloud Build
Aby uprościć proces uwierzytelniania, użyjesz w Cloud Build kroku kompilacji niestandardowej. Google udostępnia ten krok kompilacji niestandardowej, który zawiera funkcje pomocnicze ułatwiające ten proces. Zanim użyjesz kodu niestandardowego kroku kompilacji, musisz go skompilować w kontenerze i przesłać 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 do utworzonego wcześniej potoku Cloud Build krok weryfikacji.
- Zapoznaj się z nowym krokiem, który chcesz dodać.
Tylko do sprawdzenia. Nie kopiować
#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 zaktualizowanym kompletnym potworkiem.
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
Sprawdzanie kompilacji w historii Cloud Build
Otwórz Cloud Console na stronie Historia Cloud Build i sprawdź najnowszą kompilację oraz udane wykonanie kroków kompilacji.
8. Zasady kontroli dostępu
Autoryzacja plików binarnych to funkcja w GKE i Cloud Run, która umożliwia sprawdzanie reguł przed zezwoleniem na uruchomienie obrazu kontenera. Weryfikacja jest wykonywana w przypadku każdego żądania uruchomienia obrazu, czy to z zaufanego potoku CI/CD, czy też gdy użytkownik ręcznie próbuje wdrożyć obraz. Ta funkcja pozwala skuteczniej chronić środowisko w czasie wykonywania niż tylko sprawdzanie potoku CI/CD.
Aby zrozumieć tę funkcję, zmodyfikujesz domyślne zasady GKE, aby zastosować ś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
Zezwalaj 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
Najpierw sprawdź stan domyślnych zasad i możliwość wdrożenia dowolnego obrazu.
- Sprawdzanie istniejącej zasady
gcloud container binauthz policy export
- Zwróć uwagę, że zasada egzekwowania jest ustawiona na
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- Wdróż przykład, aby sprawdzić, czy możesz wdrożyć cokolwiek
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Sprawdzanie, czy wdrożenie się powiodło
kubectl get pods
Powinny się wyświetlić te dane wyjściowe
- Usuń wdrożenie
kubectl delete pod hello-server
Zasada odrzucania wszystkich
Zaktualizuj teraz zasady, aby zablokować wszystkie obrazy.
- Eksportowanie bieżących zasad do edytowalnego pliku
gcloud container binauthz policy export > policy.yaml
- Zmień zasadę
W edytorze tekstu zmień wartość parametru 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 nową zasadę. Poczekaj kilka sekund, aż zmiana zostanie rozpowszechniona.
gcloud container binauthz policy import policy.yaml
- Próba wdrożenia 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 tego powodu
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óć zasady, aby zezwolić na wszystkie
Zanim przejdziesz do następnej sekcji, cofnij zmiany zasad
- Zmień zasadę
W edytorze tekstu zmień wartość parametru 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óconą zasadę
gcloud container binauthz policy import policy.yaml
9. Blokowanie luk w zabezpieczeniach w GKE
W tej sekcji połączysz dotychczasową wiedzę, wdrażając potok CI/CD za pomocą usługi Cloud Build, która skanuje obrazy, a potem sprawdza, czy nie zawierają one luk w zabezpieczeniach, zanim zostaną podpisane i wdrożone. Zanim pozwoli na uruchomienie obrazu, GKE użyje autoryzacji plików binarnych, aby sprawdzić, czy obraz ma podpis z skanowania pod kątem luk w zabezpieczeniach.
Zmiana zasad GKE na wymagające uwierzytelniania
Wymagaj, aby obrazy były podpisane przez Attestera, dodając clusterAdmissionRules do zasad autoryzacji Bin GKE.
Zastąp zasadę zaktualizowaną konfiguracją, używając podanego niżej 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 opis wdrożenia dla wcześniej utworzonej aplikacji za pomocą tego polecenia. Obraz użyty w tym przykładzie to obraz utworzony wcześniej, 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ć podpis. Aby to zrobić, musisz użyć podsumowania obrazu i prostego tagu.
Pobierz skrót obrazu, który nie spełnia wymogów
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 digesta 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 odrzuceniu wdrożenia:
No attestations found that were valid and signed by a key trusted by the attestor
Wdrażanie podpisanego obrazu
Pobierz skrót obrazu, który nie spełnia wymogów
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 digesta 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ź zadanie w konsoli i sprawdź, czy obraz został prawidłowo wdrożony.
10. Gratulacje!
Gratulacje! Masz ukończone zajęcia.
Omówione zagadnienia:
- Jak włączyć automatyczne skanowanie
- Jak wykonać skanowanie na żądanie
- Jak zintegrować skanowanie w przepływie tworzenia
- Jak podpisywać zatwierdzone obrazy
- Jak używać kontrolerów dostępu GKE do blokowania obrazów
- Jak skonfigurować GKE, aby zezwalać tylko na podpisane zatwierdzone obrazy
Co dalej:
- Zabezpieczanie wdrożonych obrazów w Cloud Run i Google Kubernetes Engine | Dokumentacja Cloud Build
- Krótki przewodnik: konfigurowanie zasady autoryzacji plików binarnych 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 na potrzeby samouczka.