Contrôler les déploiements avec l'authentification binaire

1. Introduction

L'autorisation binaire est un contrôle de sécurité intervenant au moment du déploiement qui garantit que seules des images de conteneur fiables sont déployées sur Google Kubernetes Engine (GKE) ou Cloud Run. Avec l'autorisation binaire, vous pouvez exiger que toutes les images soient signées par des autorités de confiance lors du processus de développement, puis appliquer la validation de signature lors du déploiement. Grâce à cette validation, vous pouvez exercer un contrôle plus strict sur votre environnement de conteneurs en vous assurant que seules les images validées sont intégrées au processus de compilation et de déploiement.

Le schéma suivant présente les composants d'une configuration d'autorisation binaire/Cloud Build:

Pipeline d'attestation par l'autorisation binaire avec Cloud Build.**Figure 1.**Pipeline Cloud Build qui crée une attestation d'autorisation binaire.

Dans ce pipeline :

  1. Le code permettant de créer l'image de conteneur est transféré vers un dépôt source, tel que Cloud Source Repositories.
  2. Cloud Build, un outil d'intégration continue (CI), crée et teste le conteneur.
  3. La compilation transfère l'image de conteneur vers Container Registry ou dans un autre registre qui stocke les images compilées.
  4. Cloud Key Management Service, qui assure la gestion des clés pour la paire de clés cryptographiques, signe l'image du conteneur. La signature obtenue est ensuite stockée dans une nouvelle attestation.
  5. Au moment du déploiement, le certificateur valide l'attestation à l'aide de la clé publique de la paire de clés. L'autorisation binaire applique la règle en exigeant des attestations signées pour déployer l'image de conteneur.

Dans cet atelier, vous allez découvrir les outils et techniques permettant de sécuriser les artefacts déployés. Cet atelier se concentre sur les artefacts (conteneurs) après leur création sans être déployés dans un environnement en particulier.

Points abordés

  • Signature d'images
  • Règles concernant le contrôle des admissions
  • Signature d'images numérisées
  • Autoriser les images signées
  • Images non signées bloquées

2. Préparation

Configuration de l'environnement d'auto-formation

  1. Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères non utilisée par les API Google. Vous pouvez le modifier à tout moment.
  • L'ID du projet est unique parmi tous les projets Google Cloud et non modifiable une fois défini. La console Cloud génère automatiquement une chaîne unique. généralement, vous ne vous souciez pas de ce que c’est. Dans la plupart des ateliers de programmation, vous devrez référencer l'ID du projet (il est généralement identifié comme PROJECT_ID). Si l'ID généré ne vous convient pas, vous pouvez en générer un autre au hasard. Vous pouvez également essayer la vôtre pour voir si elle est disponible. Il ne peut pas être modifié après cette étape et restera actif pendant toute la durée du projet.
  • Pour votre information, il existe une troisième valeur, le numéro de projet, utilisé par certaines API. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
  1. Vous devez ensuite activer la facturation dans la console Cloud pour utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour arrêter les ressources afin d'éviter que des frais ne vous soient facturés au-delà de ce tutoriel, vous pouvez supprimer les ressources que vous avez créées ou l'ensemble du projet. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai gratuit pour bénéficier d'un crédit de 300 $.

Configuration de l'environnement

Dans Cloud Shell, définissez l'ID et le numéro de votre projet. Enregistrez-les en tant que variables PROJECT_ID et PROJECT_ID.

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

Activer les services

Activez tous les services nécessaires :

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 

Créer un dépôt Artifact Registry

Dans cet atelier, vous allez stocker et analyser vos images à l'aide d'Artifact Registry. Créez le dépôt à l'aide de la commande suivante.

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

Configurez Docker pour utiliser vos identifiants gcloud lorsque vous accédez à Artifact Registry.

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

Créer un répertoire professionnel et y accéder

mkdir vuln-scan && cd vuln-scan

Définir un exemple d'image

Créez un fichier nommé Dockerfile avec le contenu suivant.

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

Créez un fichier nommé main.py avec le contenu suivant :

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

Créer l'image et la transférer en RA

Utilisez Cloud Build pour créer votre conteneur et le transférer automatiquement vers Artifact Registry.

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

3. Signature d'images

Qu'est-ce qu'un certificateur

Certificateur

  • Cette personne/ce processus est responsable d'un maillon dans la chaîne de confiance du système.
  • Ils détiennent une clé cryptographique et signent une image si celle-ci passe son processus d'approbation.
  • Alors que le créateur du règlement détermine le règlement de manière générale et abstraite, le certificateur est responsable de l'application concrète de certains aspects du règlement.
  • Il peut s'agir d'une personne réelle, comme un testeur de contrôle qualité ou un responsable, ou un bot dans un système CI.
  • La sécurité du système dépend de leur fiabilité. Il est donc important que leurs clés privées soient sécurisées.

Chacun de ces rôles peut représenter une personne individuelle ou une équipe de membres de votre organisation. Dans un environnement de production, ces rôles seraient probablement gérés par des projets Google Cloud Platform (GCP) distincts, et l'accès aux ressources serait partagé entre eux de manière limitée à l'aide de Cloud IAM.

a37eb2ed54b9c2eb.png

Les certificateurs de l'autorisation binaire sont mis en œuvre au-dessus de l'API Cloud Container Analysis. Il est donc important de décrire leur fonctionnement avant de continuer. L'API Container Analysis a été conçue pour vous permettre d'associer des métadonnées à des images de conteneurs spécifiques.

Par exemple, une note peut être créée pour suivre la faille Heartbleed. Les fournisseurs de services de sécurité créent ensuite des analyseurs pour tester les images de conteneurs afin de détecter la faille, puis créent une occurrence associée à chaque conteneur compromis.

208aa5ebc53ff2b3.png

En plus du suivi des failles, Container Analysis a été conçu comme une API de métadonnées générique. L'autorisation binaire utilise Container Analysis pour associer les signatures aux images de conteneurs qu'elles valident**.** Une note Container Analysis est utilisée pour représenter un seul certificateur. Des occurrences sont créées et associées à chaque conteneur approuvé par le certificateur.

L'API Binary Authorization utilise les concepts de "certificateurs" et les "attestations", mais celles-ci sont implémentées à l'aide de notes et d'occurrences correspondantes dans l'API Container Analysis.

63a701bd0057ea17.png

Créer une note du certificateur

Une note du certificateur est simplement un petit bit de données qui sert d’étiquette pour le type de signature appliqué. Par exemple, une note peut indiquer une analyse des failles, tandis qu'une autre peut être utilisée pour l'approbation du contrôle qualité. La note sera référencée lors du processus de signature.

919f997db0ffb881.png

Créer une note

cat > ./vulnz_note.json << EOM
{
  "attestation": {
    "hint": {
      "human_readable_name": "Container Vulnerabilities attestation authority"
    }
  }
}
EOM

Stocker la note

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}"

Vérifier la note

curl -vvv  \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"

Votre note est à présent enregistrée dans l'API Container Analysis.

Créer un certificateur

Les certificateurs sont utilisés pour effectuer le processus de signature d'image et attachent une occurrence de la note à l'image pour une vérification ultérieure. Pour utiliser votre certificateur, vous devez également enregistrer la note avec l'autorisation binaire:

ed05d438c79b654d.png

Créer un certificateur

ATTESTOR_ID=vulnz-attestor

gcloud container binauthz attestors create $ATTESTOR_ID \
    --attestation-authority-note=$NOTE_ID \
    --attestation-authority-note-project=${PROJECT_ID}

Valider le certificateur

gcloud container binauthz attestors list

Notez que la dernière ligne indique NUM_PUBLIC_KEYS: 0. Vous fournirez des clés lors d'une prochaine étape

Notez également que Cloud Build crée automatiquement le certificateur built-by-cloud-build dans votre projet lorsque vous exécutez une compilation qui génère des images. La commande ci-dessus renvoie donc deux certificateurs, vulnz-attestor et built-by-cloud-build. Une fois les images créées, Cloud Build signe et crée automatiquement des attestations pour celles-ci.

Ajouter un rôle IAM

Le compte de service de l'autorisation binaire doit disposer de droits pour afficher les notes d'attestation. Accordez l'accès à l'aide de l'appel d'API suivant :

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

Utiliser le fichier pour créer la stratégie IAM

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"

Ajouter une clé KMS

1e3af7c177f7a311.png

Pour que vous puissiez utiliser ce certificateur, votre autorité doit créer une paire de clés cryptographiques pouvant être utilisée pour signer des images de conteneurs. Pour ce faire, utilisez Google Cloud Key Management Service (KMS).

Commencez par ajouter des variables d'environnement pour décrire la nouvelle clé

KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1

Créer un trousseau pour contenir un ensemble de clés

gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"

Créer une paire de clés de signature asymétrique pour le certificateur

gcloud kms keys create "${KEY_NAME}" \
    --keyring="${KEYRING}" --location="${KEY_LOCATION}" \
    --purpose asymmetric-signing   \
    --default-algorithm="ec-sign-p256-sha256"

Votre clé doit apparaître sur la page KMS de la console Google Cloud.

À présent, associez la clé à votre certificateur via la commande 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}"

Si vous imprimez à nouveau la liste des autorités, vous devriez maintenant voir une clé enregistrée:

gcloud container binauthz attestors list

Créer une attestation signée

À ce stade, vous disposez des fonctionnalités configurées qui vous permettent de signer des images. Utilisez le certificateur que vous avez créé précédemment pour signer l'image de conteneur avec laquelle vous travaillez.

858d7e6feeb6f159.png

Une attestation doit inclure une signature cryptographique indiquant que le certificateur a validé une image de conteneur spécifique et qu'elle peut être exécutée en toute sécurité sur votre cluster. Pour spécifier l'image de conteneur à attester, vous devez déterminer son condensé.

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)')

Vous pouvez maintenant utiliser gcloud pour créer votre attestation. La commande récupère simplement les détails de la clé que vous souhaitez utiliser pour la signature, ainsi que l'image de conteneur spécifique que vous souhaitez approuver.

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}"

Dans le cas de Container Analysis, cela crée une occurrence et l'associe à la note du certificateur. Pour vous assurer que tout a fonctionné comme prévu, vous pouvez lister vos attestations

gcloud container binauthz attestations list \
   --attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}

4. Règles concernant le contrôle des admissions

L'autorisation binaire est une fonctionnalité de GKE et de Cloud Run qui permet de valider des règles avant qu'une image de conteneur ne soit autorisée à s'exécuter. La validation s'exécute sur n'importe quelle requête d'exécution d'une image, que ce soit à partir d'un pipeline CI/CD approuvé ou lorsqu'un utilisateur tente manuellement de déployer une image. Cette fonctionnalité vous permet de sécuriser vos environnements d'exécution plus efficacement que les seules vérifications de pipeline CI/CD.

Pour comprendre cette fonctionnalité, vous allez modifier la stratégie GKE par défaut afin d'appliquer une règle d'autorisation stricte.

Créer le cluster GKE

Créez le cluster GKE avec l'autorisation binaire activée:

gcloud beta container clusters create binauthz \
    --zone us-central1-a  \
    --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE

Autorisez Cloud Build à déployer sur ce cluster:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/container.developer"

Règle "Tout autoriser"

Vérifiez d'abord l'état de la règle par défaut et votre capacité à déployer n'importe quelle image

  1. Examiner les règles existantes
gcloud container binauthz policy export
  1. Notez que la règle d'application est définie sur ALWAYS_ALLOW

evaluationMode: ALWAYS_ALLOW

  1. Déployez un exemple pour vérifier que vous pouvez déployer tout ce que vous voulez
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Vérifier que le déploiement a fonctionné
kubectl get pods

La sortie suivante s'affiche :

161db370d99ffb13.png

  1. Supprimer le déploiement
kubectl delete pod hello-server

Règle "Tout refuser"

Modifiez maintenant la stratégie pour interdire toutes les images.

  1. Exporter la stratégie actuelle dans un fichier modifiable
gcloud container binauthz policy export  > policy.yaml
  1. Modifier les règles

Dans un éditeur de texte, remplacez la valeur du mode d'évaluation ALWAYS_ALLOW par ALWAYS_DENY.

edit policy.yaml

Le fichier YAML de stratégie doit ressembler à ceci :

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_DENY
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy

Cette règle est relativement simple. La ligne globalPolicyEvaluationMode indique que cette règle étend la règle globale définie par Google. Cela permet à tous les conteneurs GKE officiels de s'exécuter par défaut. En outre, la stratégie déclare une règle defaultAdmissionRule indiquant que tous les autres pods seront rejetés. La règle d'admission inclut une ligne enforcementMode, qui indique que tous les pods non conformes à cette règle doivent être bloqués pour s'exécuter sur le cluster.

Pour savoir comment créer des stratégies plus complexes, consultez la documentation sur l'autorisation binaire.

657752497e59378c.png

  1. Ouvrez le terminal, appliquez la nouvelle règle et attendez quelques secondes pour que la modification soit appliquée.
gcloud container binauthz policy import policy.yaml
  1. Tentative de déploiement de l'exemple de charge de travail
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Échec du déploiement avec le message suivant
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

Rétablissez la règle pour tout autoriser

Avant de passer à la section suivante, assurez-vous d'annuler les modifications apportées aux règles

  1. Modifier les règles

Dans un éditeur de texte, remplacez la valeur du mode d'évaluation ALWAYS_DENY par ALWAYS_ALLOW.

edit policy.yaml

Le fichier YAML de stratégie doit ressembler à ceci :

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. Appliquer la règle annulée
gcloud container binauthz policy import policy.yaml

5. Signature d'images numérisées

Vous avez activé la signature d'image et utilisé manuellement le certificateur pour signer votre exemple d'image. En pratique, vous devrez appliquer des attestations au cours de processus automatisés tels que les pipelines CI/CD.

Dans cette section, vous allez configurer Cloud Build pour attester automatiquement les images.

Rôles

Attribuez le rôle "Lecteur des certificateurs de l'autorisation binaire" au compte de service Cloud Build :

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/binaryauthorization.attestorsViewer

Attribuez le rôle "Signataire/Validateur de CryptoKeys Cloud KMS" au compte de service Cloud Build (signature basée sur KMS) :

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/cloudkms.signerVerifier

Attribuez le rôle "Agent d'association de notes Container Analysis" au compte de service Cloud Build :

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/containeranalysis.notes.attacher

Fournir un accès au compte de service Cloud Build

Cloud Build requiert des droits pour accéder à l'API d'analyse à la demande. Accordez l'accès à l'aide des commandes suivantes.

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"

Préparer l'étape de compilation personnalisée Cloud Build

Vous allez utiliser une étape de compilation personnalisée dans Cloud Build pour simplifier le processus d'attestation. Google propose cette étape de compilation personnalisée qui contient des fonctions d'assistance pour simplifier le processus. Avant d'être utilisé, le code de l'étape de compilation personnalisée doit être intégré à un conteneur et transféré vers Cloud Build. Pour ce faire, exécutez les commandes suivantes:

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

Ajouter une étape de signature à votre fichier cloudbuild.yaml

Au cours de cette étape, vous allez ajouter l'étape d'attestation à votre pipeline Cloud Build.

  1. Consultez l'étape de signature ci-dessous.

Avis uniquement. Ne pas copier

#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'
  1. Écrivez un fichier cloudbuild.yaml avec le pipeline complet ci-dessous.
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

Exécuter le build

gcloud builds submit

Examiner la compilation dans l'historique Cloud Build

Ouvrez la console Cloud sur la page Historique Cloud Build, puis examinez la dernière compilation et l'exécution réussie des étapes de compilation.

6. Autoriser les images signées

Dans cette section, vous allez mettre à jour GKE afin d'utiliser l'autorisation binaire pour vérifier que l'image possède une signature générée par l'analyse des failles avant d'autoriser l'exécution de l'image.

d5c41bb89e22fd61.png

Mettre à jour la stratégie GKE pour exiger une attestation

Exiger que les images soient signées par votre certificateur en ajoutant clusterAdmissionRules à votre règle GKE BinAuth

Actuellement, votre cluster exécute une stratégie comportant une seule règle: autoriser les conteneurs provenant de dépôts officiels et refuser tous les autres.

Remplacez la règle par la configuration mise à jour à l'aide de la commande ci-dessous.

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

Vous devriez maintenant disposer d'un nouveau fichier sur le disque, nommé updated_policy.yaml. Désormais, au lieu que la règle par défaut rejette toutes les images, elle vérifie d'abord les validations de votre certificateur.

822240fc0b02408e.png

Importez la nouvelle stratégie vers l'autorisation binaire:

gcloud beta container binauthz policy import binauth_policy.yaml

Déployer une image signée

Obtenir le condensé de l'image de qualité

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)')

Utiliser le condensé dans la configuration 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

Déployer l'application sur GKE

kubectl apply -f deploy.yaml

Examinez la charge de travail dans la console et notez le déploiement de l'image.

7. Images non signées bloquées

Créer une image

Au cours de cette étape, vous allez utiliser un Dockerfile local pour créer l'image dans votre cache local.

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

Transférer l'image non signée vers le dépôt

docker push us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad

Obtenir le condensé de l'image incorrecte

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)')

Utiliser le condensé dans la configuration 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

Essayer de déployer l'application sur GKE

kubectl apply -f deploy.yaml

Examinez la charge de travail dans la console et notez l'erreur indiquant que le déploiement a été refusé:

No attestations found that were valid and signed by a key trusted by the attestor

8. Félicitations !

Félicitations, vous avez terminé cet atelier de programmation.

Points abordés

  • Signature d'images
  • Règles concernant le contrôle des admissions
  • Signature d'images numérisées
  • Autoriser les images signées
  • Images non signées bloquées

Étapes suivantes :

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez chaque ressource individuellement.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Dernière mise à jour: 21/03/2023