Cómo limitar las implementaciones con autenticación binaria

1. Introducción

La Autorización Binaria es un control de seguridad en la fase de implementación que garantiza que solo se implementen imágenes de contenedor confiables en Google Kubernetes Engine (GKE) o Cloud Run. Con la Autorización Binaria, puedes exigir que autoridades de confianza firmen las imágenes durante el proceso de desarrollo y, luego, aplicar la validación de firma de manera forzosa en el momento de la implementación. Aplicar esta validación permite tener un control más estricto sobre tu entorno de contenedores y asegurarte de que solo las imágenes verificadas se integren en el proceso de compilación y lanzamiento.

En el siguiente diagrama, se muestran los componentes de una configuración de Autorización Binaria y Cloud Build:

Canalización de certificación de Cloud Build y Autorización Binaria.**Figura 1:**Canalización de Cloud Build que crea una certificación de Autorización binaria.

En esta canalización, sucede lo siguiente:

  1. El código para compilar la imagen del contenedor se envía a un repositorio de código fuente, como Cloud Source Repositories.
  2. Una herramienta de integración continua (CI), Cloud Build, compila y prueba el contenedor.
  3. La compilación envía la imagen del contenedor a Container Registry o a otro registro que almacene tus imágenes compiladas.
  4. Cloud Key Management Service, que proporciona administración de claves para el par de claves criptográficas, firma la imagen de contenedor. La firma resultante se almacena en una certificación recién creada.
  5. En el momento de la implementación, el certificador verifica la certificación usando la clave pública del par de claves. La Autorización Binaria aplica la política a través de la solicitud de certificaciones firmadas para implementar la imagen de contenedor.

En este lab, te enfocarás en las herramientas y técnicas para proteger los artefactos implementados. Este lab se enfoca en los artefactos (contenedores) después de que se crearon, pero antes de que se implementen en algún entorno específico.

Qué aprenderás

  • Firma de imágenes
  • Políticas de control de admisión
  • Firma de imágenes analizadas
  • Autorización de imágenes firmadas
  • Bloqueo de imágenes sin firmar

2. Configuración y requisitos

Cómo configurar el entorno a tu propio ritmo

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla en cualquier momento.
  • El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. Por lo general, no importa cuál sea. En la mayoría de los codelabs, deberás hacer referencia al ID del proyecto (suele identificarse como PROJECT_ID). Si no te gusta el ID que se generó, podrías generar otro aleatorio. También puedes probar uno propio y ver si está disponible. No se puede cambiar después de este paso y se usará el mismo durante todo el proyecto.
  • Recuerda que hay un tercer valor, un número de proyecto, que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Para cerrar recursos y evitar que se generen cobros más allá de este instructivo, puedes borrar los recursos que creaste o borrar todo el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.

Configuración del entorno

En Cloud Shell, configura el ID y el número de tu proyecto. Guárdalos como variables PROJECT_ID y PROJECT_ID.

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

Habilita los servicios

Habilita todos los servicios necesarios con el siguiente comando:

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 

Crea un repositorio de Artifact Registry

En este lab, usarás Artifact Registry para almacenar y analizar tus imágenes. Crea el repositorio con el siguiente comando.

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

Configura Docker para que utilice tus credenciales de gcloud cuando accedas a Artifact Registry.

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

Crea un directorio de trabajo y cambia a él

mkdir vuln-scan && cd vuln-scan

Define una imagen de muestra

Crea un archivo llamado Dockerfile con el siguiente contenido.

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

Crea un archivo llamado main.py con el siguiente contenido:

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

Compila y envía la imagen a AR

Usa Cloud Build para compilar y enviar automáticamente tu contenedor a Artifact Registry.

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

3. Firma de imágenes

¿Qué es un certificador?

Certificador

  • Es la persona o proceso responsable de un vínculo en la cadena de confianza del sistema.
  • Tiene una clave criptográfica y firma una imagen si pasa su proceso de aprobación.
  • Mientras que el creador de políticas determina la política a un nivel alto y abstracto, el certificador es responsable de aplicar de forma concreta algún aspecto de la política.
  • Puede ser una persona real, como un verificador de QA o un administrador, o un bot en un sistema de CI.
  • La seguridad del sistema depende de su confiabilidad, por lo que es importante que sus claves privadas se mantengan seguras.

Cada uno de estos roles puede representar a una persona individual o a un equipo dentro de tu organización. En un entorno de producción, es probable que estos roles se administren con proyectos separados de Google Cloud (GCP) y que el acceso a los recursos se comparta entre ellos de forma limitada con Cloud IAM.

a37eb2ed54b9c2eb.png

Los certificadores de la Autorización Binaria se implementan sobre la API de Cloud Container Analysis, por lo que es importante describir cómo funciona antes de continuar. La API de Container Analysis se diseñó para permitirte asociar metadatos con imágenes de contenedores específicas.

Por ejemplo, se podría crear una nota para hacer un seguimiento de la vulnerabilidad Heartbleed. Luego, los proveedores de seguridad crearían luego escáneres para analizar las imágenes de contenedor en busca de la vulnerabilidad y generarían una ocurrencia asociada a cada contenedor comprometido.

208aa5ebc53ff2b3.png

Además de hacer un seguimiento de las vulnerabilidades, Container Analysis se diseñó para ser una API de metadatos genérica. La Autorización Binaria utiliza Container Analysis para asociar firmas con las imágenes de contenedor que está verificando**.** Una nota de Container Analysis se usa para representar a un solo certificador, se crean ocurrencias asociadas a cada contenedor que ese certificador haya aprobado.

La API de Autorización Binaria usa los conceptos de "certificadores" y "certificaciones", pero estos se implementan con las notas y las ocurrencias correspondientes en la API de Container Analysis.

63a701bd0057ea17.png

Crea una nota de certificador

Una nota de certificador es básicamente un pequeño fragmento de datos que actúa como una etiqueta para el tipo de firma que se aplica. Por ejemplo, una nota podría indicar un análisis de vulnerabilidades, mientras que otra podría usarse para la aprobación de QA. Esta nota se consultará durante el proceso de firma.

919f997db0ffb881.png

Cómo crear una nota

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

Almacena la nota:

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

Verifica la nota:

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

Tu nota ahora está guardada en la API de Container Analysis.

Crea un certificador

Los certificadores se usan para realizar el proceso de firma de la imagen y adjuntarán una ocurrencia de la nota a la imagen para verificarla más tarde. Para usar tu certificador, también debes registrar la nota con Autorización Binaria:

ed05d438c79b654d.png

Crear certificador

ATTESTOR_ID=vulnz-attestor

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

Verifica el certificador:

gcloud container binauthz attestors list

Ten en cuenta que la última línea indica NUM_PUBLIC_KEYS: 0, ya que proporcionarás las claves en un paso posterior.

Ten en cuenta también que Cloud Build crea automáticamente el certificador built-by-cloud-build en tu proyecto cuando ejecutas una compilación que genera imágenes. Por lo tanto, el comando anterior devuelve dos certificadores: vulnz-attestor y built-by-cloud-build. Una vez que las imágenes se compilan con éxito, Cloud Build firma y crea certificaciones de forma automática para ellas.

Cómo agregar un rol de IAM

La cuenta de servicio de Autorización Binaria necesitará derechos para ver las notas de certificación. Proporciona el acceso con la siguiente llamada a la 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

Usa el archivo para crear la política de 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"

Cómo agregar una clave de KMS

1e3af7c177f7a311.png

Antes de que puedas usar este certificador, tu autoridad debe crear un par de claves criptográficas que se usará para firmar las imágenes de contenedor. Esto se puede hacer a través de Google Cloud Key Management Service (KMS).

Primero, agrega algunas variables de entorno para describir la nueva clave

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

Crea un llavero de claves para almacenar un conjunto de claves

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

Crea un nuevo par de claves de firma asimétricas para el certificador:

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

Deberías ver tu clave en la página de KMS de la consola de Google Cloud.

Ahora, asocia la clave con tu certificador a través del comando binauthz de gcloud:

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 vuelves a imprimir la lista de autoridades, debería aparecer una clave registrada:

gcloud container binauthz attestors list

Crea una certificación firmada

En este momento, las funciones que te permiten firmar imágenes ya están configuradas. Usa el certificador que creaste anteriormente para firmar la imagen de contenedor con la que has estado trabajando.

858d7e6feeb6f159.png

Una certificación debe incluir una firma criptográfica para indicar que el certificador verificó una imagen de contenedor en particular y que es seguro ejecutarla en tu clúster. Para especificar qué imagen de contenedor vas a certificar, debes determinar su resumen.

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

Ahora, puedes usar gcloud para crear tu certificación. El comando simplemente recibe los detalles de la clave que quieres usar para la firma y la imagen de contenedor específica que quieres aprobar.

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

En términos de Container Analysis, esto creará una nueva ocurrencia y la adjuntará a la nota de tu certificador. Para asegurarte de que todo funcionó como se esperaba, puedes listar tus certificaciones

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

4. Políticas de control de admisión

La Autorización Binaria es una función de GKE y Cloud Run que permite validar reglas antes de que se ejecute una imagen de contenedor. La validación se realiza en cualquier solicitud para ejecutar una imagen, ya sea desde una canalización de CI/CD confiable o cuando un usuario intenta implementarla de forma manual. Esta capacidad te permite proteger tus entornos de ejecución de manera más eficaz que únicamente con las verificaciones de canalización de CI/CD.

Para comprender esta capacidad, modificarás la política predeterminada de GKE y aplicarás una regla de autorización estricta.

Crea el clúster de GKE

Crea un clúster de GKE con Autorización Binaria habilitada:

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

Permite que Cloud Build implemente en este clúster:

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

Política de permitir todo

Primero, verifica el estado de la política predeterminada y tu capacidad para implementar cualquier imagen.

  1. Revisa la política existente
gcloud container binauthz policy export
  1. Ten en cuenta que la política de aplicación está configurada en ALWAYS_ALLOW

evaluationMode: ALWAYS_ALLOW

  1. Implementa la muestra para verificar que puedes implementar cualquier imagen
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Verifica que la implementación haya funcionado
kubectl get pods

Verás el siguiente resultado:

161db370d99ffb13.png

  1. Borrar implementación
kubectl delete pod hello-server

Política de rechazar todo

Ahora, actualiza la política para no permitir ninguna imagen.

  1. Exporta la política actual a un archivo editable
gcloud container binauthz policy export  > policy.yaml
  1. Cambiar la política.

En un editor de texto, cambia evaluationMode de ALWAYS_ALLOW a ALWAYS_DENY.

edit policy.yaml

El archivo de políticas en formato YAML debe aparecer de la siguiente manera:

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

Esta política es relativamente sencilla. La línea globalPolicyEvaluationMode declara que esta política amplía la política global definida por Google. Esto permite que todos los contenedores oficiales de GKE se ejecuten de forma predeterminada. Además, la política declara una defaultAdmissionRule que indica que todos los demás pods serán rechazados. La regla de admisión incluye una línea enforcementMode, que indica que todos los pods que no cumplan con esta regla deben ser bloqueados para ejecutarse en el clúster.

Para obtener instrucciones sobre cómo crear políticas más complejas, consulta la documentación sobre Autorización Binaria.

657752497e59378c.png

  1. Abre la terminal, aplica la política nueva y espera unos segundos para que se propague el cambio.
gcloud container binauthz policy import policy.yaml
  1. Intenta implementar una carga de trabajo de muestra
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. La implementación falla con el siguiente mensaje
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

Revierte la política para permitir todo

Antes de pasar a la siguiente sección, asegúrate de revertir los cambios en la política.

  1. Cambiar la política.

En un editor de texto, cambia evaluationMode de ALWAYS_DENY a ALWAYS_ALLOW.

edit policy.yaml

El archivo de políticas en formato YAML debe aparecer de la siguiente manera:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. Aplica la política revertida
gcloud container binauthz policy import policy.yaml

5. Firma de imágenes analizadas

Habilitaste la firma de imágenes y usaste manualmente el certificador para firmar tu imagen de muestra. En la práctica, querrás aplicar las certificaciones durante los procesos automatizados, como las canalizaciones de CI/CD.

En esta sección, configurarás Cloud Build para certificar imágenes automáticamente.

Funciones

Agrega el rol de visualizador de certificadores de Autorización Binaria a la cuenta de servicio de Cloud Build:

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

Agrega la función de verificador y firmante de CryptoKey de Cloud KMS a la cuenta de servicio de Cloud Build (firma basada en KMS):

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

Agrega el rol Vinculador de notas de Container Analysis a la cuenta de servicio de Cloud Build:

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

Proporciona acceso para la cuenta de servicio de Cloud Build

Cloud Build necesitará derechos para acceder a la API de On-Demand Scanning. Proporciona acceso con los siguientes comandos.

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"

Prepara el paso de compilación personalizado de Cloud Build

Vas a usar un paso de compilación personalizado en Cloud Build para simplificar el proceso de certificación. Google proporciona este paso de compilación personalizado que contiene funciones auxiliares para optimizar el proceso. Antes de usarlo, el código para el paso de compilación personalizado se debe compilar en un contenedor y enviar a Cloud Build. Para ello, ejecuta los siguientes comandos:

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

Agrega un paso de firma a tu archivo cloudbuild.yaml

En este paso, agregarás el paso de certificación a tu canalización de Cloud Build.

  1. Revisa el paso de firma a continuación.

Solo para revisión. No copiar

#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. Escribe un archivo cloudbuild.yaml con la canalización completa que se muestra a continuación.
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

Ejecuta la compilación

gcloud builds submit

Revisa la compilación en el historial de Cloud Build

Abre la consola de Cloud en la página Historial de Cloud Build y revisa la compilación más reciente y la ejecución correcta de los pasos de compilación.

6. Autorización de imágenes firmadas

En esta sección, actualizarás GKE para usar Autorización Binaria y validar que la imagen tenga una firma del análisis de vulnerabilidades antes de permitir que se ejecute.

d5c41bb89e22fd61.png

Actualiza la política de GKE para que requiera la certificación

Requiere que las imágenes estén firmadas por tu certificador agregando clusterAdmissionRules a tu política de Autorización Binaria de GKE

Actualmente, tu clúster ejecuta una política con una regla: permitir contenedores de repositorios oficiales y rechazar todos los demás.

Reemplaza la política con la configuración actualizada usando el siguiente comando.

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

Ahora deberías tener un nuevo archivo en el disco llamado updated_policy.yaml. Ahora, en lugar de que la regla predeterminada rechace todas las imágenes, primero comprueba con tu certificador para ver si hay verificaciones.

822240fc0b02408e.png

Sube la nueva política a Autorización Binaria:

gcloud beta container binauthz policy import binauth_policy.yaml

Implementa una imagen firmada

Obtén el resumen de la imagen válida

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

Usa el resumen en la configuración de 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

Implementa la app en GKE

kubectl apply -f deploy.yaml

Revisa la carga de trabajo en la consola y toma nota de la implementación correcta de la imagen.

7. Bloqueo de imágenes sin firmar

Compila una imagen

En este paso, usarás Docker local para compilar la imagen en tu caché local.

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

Envía la imagen sin firmar al repositorio

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

Obtén el resumen de la imagen no válida

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

Usa el resumen en la configuración de 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

Intenta implementar la app en GKE

kubectl apply -f deploy.yaml

Revisa la carga de trabajo en la consola y toma nota del error que indica que se denegó la implementación:

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

8. ¡Felicitaciones!

¡Felicitaciones! Completaste el codelab.

Temas abordados:

  • Firma de imágenes
  • Políticas de control de admisión
  • Firma de imágenes analizadas
  • Autorización de imágenes firmadas
  • Bloqueo de imágenes sin firmar

Pasos siguientes:

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Borra el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Última actualización: 21/3/23