1. Introducción
Container Analysis proporciona análisis de vulnerabilidades y almacenamiento de metadatos para contenedores. El servicio de análisis realiza análisis de vulnerabilidades en imágenes en Artifact Registry y Container Registry, luego almacena los metadatos resultantes y los pone a disposición para el consumo a través de una API. El almacenamiento de metadatos te permite almacenar información de diferentes fuentes, incluidos el análisis de vulnerabilidades, los servicios de Google Cloud y los proveedores externos.
El análisis de vulnerabilidades puede realizarse de forma automática o según demanda:
- Cuando el análisis automático está habilitado, el análisis se activa automáticamente cada vez que envías una imagen nueva a Artifact Registry o Container Registry. La información de las vulnerabilidades se actualiza de forma continua cuando se descubren nuevas vulnerabilidades.
- Cuando el Análisis a pedido está habilitado, debes ejecutar un comando para analizar una imagen local o una imagen en Artifact Registry o Container Registry. On-Demand Scanning te brinda flexibilidad de análisis de contenedores. Por ejemplo, puedes analizar una imagen creada localmente y corregir vulnerabilidades antes de almacenarla en un registro. Los resultados del análisis están disponibles hasta 48 horas después de que se completa el análisis, y la información de vulnerabilidad no se actualiza después de este.
Con Container Analysis integrado en tu canalización de CI/CD, puedes tomar decisiones basadas en esos metadatos. Por ejemplo, puedes usar la Autorización Binaria para crear políticas de implementación que solo permitan implementaciones de imágenes compatibles de registros de confianza.
Qué aprenderás
- Cómo habilitar el análisis automático
- Cómo realizar análisis a pedido
- Cómo integrar el análisis en una canalización de compilación
- Cómo firmar imágenes aprobadas
- Cómo usar los controladores de admisión de GKE para bloquear imágenes
- Cómo configurar GKE para permitir solo imágenes aprobadas y firmadas
2. Configuración y requisitos
Cómo configurar el entorno a tu propio ritmo
- 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.
- 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 te importa qué es. En la mayoría de los codelabs, deberás hacer referencia al ID del proyecto (por lo general, se identifica como
PROJECT_ID
). Si no te gusta el ID generado, puedes generar otro aleatorio. También puedes probar el tuyo propio y ver si está disponible. No se puede cambiar después de este paso y se mantendrá mientras dure el proyecto. - Para tu información, 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.
- 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 te facture 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.
Inicia el editor de Cloud Shell
Este lab se diseñó y probó para usarse con el editor de Google Cloud Shell. Para acceder al editor,
- accede a tu proyecto de Google en https://console.cloud.google.com.
- En la esquina superior derecha, haz clic en el ícono del editor de Cloud Shell.
- Se abrirá un panel nuevo en la parte inferior de la ventana.
Configuración del entorno
Configura tu ID y número de proyecto en Cloud Shell. Guárdalas 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
Crear 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 use tus credenciales de gcloud cuando accedas a Artifact Registry.
gcloud auth configure-docker us-central1-docker.pkg.dev
3. Análisis automatizado
El análisis de artefactos se activa automáticamente cada vez que envías una imagen nueva a Artifact Registry o Container Registry. La información de las vulnerabilidades se actualiza de forma continua cuando se descubren nuevas vulnerabilidades. En esta sección, enviarás una imagen a Artifact Registry y explorarás los resultados.
Crea y cambia a un directorio de trabajo
mkdir vuln-scan && cd vuln-scan
Define una imagen de muestra
Crea un archivo llamado Dockerfile con los siguientes contenidos.
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
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 RA
Usa Cloud Build para compilar y enviar automáticamente tu contenedor a Artifact Registry. Observa la etiqueta bad
en la imagen. Esto te ayudará a identificarla para pasos posteriores.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
Revisar detalles de la imagen
Una vez que se complete el proceso de compilación, revisa la imagen y los resultados de vulnerabilidades en el panel de Artifact Registry.
- Abre Artifact Registry en la consola de Cloud.
- Haz clic en Artifact-scanning-repo para ver el contenido.
- Haz clic en los detalles de la imagen.
- Haz clic en el resumen más reciente de tu imagen.
- Cuando termine el análisis, haz clic en la pestaña Vulnerabilidades de la imagen.
En la pestaña de vulnerabilidades, verás los resultados del análisis automático de la imagen que acabas de compilar.
La automatización del análisis está habilitada de forma predeterminada. Explora la configuración de Artifact Registry para ver cómo puedes activar o desactivar el análisis automático.
4. On-Demand Scanning
Existen varios casos en los que quizás debas ejecutar un análisis antes de enviar la imagen a un repositorio. Por ejemplo, un desarrollador de contenedores puede analizar una imagen y corregir los problemas antes de enviar código al control de origen. En el siguiente ejemplo, compilarás y analizarás la imagen a nivel local antes de actuar en función de los resultados.
Cómo crear 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 .
Analizar la imagen
Una vez que se haya compilado la imagen, solicita un análisis. Los resultados del análisis se almacenan en un servidor de metadatos. El trabajo se completa con una ubicación de los resultados en el servidor de metadatos.
gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--format="value(response.scan)" > scan_id.txt
Revisa el archivo de salida
Tómate un momento para revisar el resultado del paso anterior, que se almacenó en el archivo scan_id.txt. Observa la ubicación del informe de los resultados del análisis en el servidor de metadatos.
cat scan_id.txt
Revisa los resultados detallados del análisis
Para ver los resultados reales del análisis, usa el comando list-vulnerabilities
en la ubicación del informe anotada en el archivo de salida.
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt)
El resultado contiene una cantidad significativa de datos sobre todas las vulnerabilidades de la imagen.
Marcar problemas críticos
Los seres humanos rara vez usan los datos almacenados en el informe directamente. Por lo general, los resultados se utilizan mediante un proceso automatizado. Usa los siguientes comandos para leer los detalles del informe y registrar si se encontró alguna vulnerabilidad CRÍTICA.
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
El resultado de este comando
Failed vulnerability check for CRITICAL level
5. Compilar análisis de canalizaciones
En esta sección, crearás una canalización de compilación automatizada que compilará tu imagen de contenedor, la analizará y, luego, evaluará los resultados. Si no se encuentran vulnerabilidades CRÍTICAS, se enviará la imagen al repositorio. Si se encuentran vulnerabilidades CRÍTICAS, la compilación fallará y se cerrará.
Proporciona acceso a la cuenta de servicio de Cloud Build
Cloud Build necesitará derechos para acceder a la API de análisis a pedido. 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"
Crea la canalización de Cloud Build
El siguiente comando creará un archivo cloudbuild.yaml en tu directorio que se usará para el proceso automatizado. Para este ejemplo, los pasos se limitan al proceso de compilación del contenedor. Sin embargo, en la práctica, incluirías instrucciones y pruebas específicas de la aplicación además de los pasos del contenedor.
Crea el archivo con el siguiente comando.
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
Ejecuta la canalización de CI
Envía la compilación a procesamiento para verificar las fallas de compilación cuando se encuentre una vulnerabilidad de gravedad CRÍTICA.
gcloud builds submit
Revisar error de compilación
La compilación que acabas de enviar fallará porque la imagen contiene vulnerabilidades CRITICAL.
Revisa la falla de compilación en la página Historial de Cloud Build.
Corrige la vulnerabilidad
Actualiza el Dockerfile para usar una imagen base que no contenga vulnerabilidades CRITICAL.
Reemplaza el Dockerfile para usar la imagen de Debian 10 con el siguiente comando:
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
Ejecuta el proceso de CI con la imagen correcta
Envía la compilación para que se procese y verifique que se realice de forma correcta cuando no se encuentren vulnerabilidades de gravedad CRÍTICA.
gcloud builds submit
Revisa la compilación exitosa
La compilación que acabas de enviar se realizará correctamente porque la imagen actualizada no contiene vulnerabilidades CRÍTICAS.
Revisa el éxito de la compilación en la página Historial de Cloud Build.
Revisa los resultados del análisis
Revisa la imagen de calidad en Artifact Registry
- Abre Artifact Registry en la consola de Cloud.
- Haz clic en Artifact-scanning-repo para ver el contenido.
- Haz clic en los detalles de la imagen.
- Haz clic en el resumen más reciente de tu imagen.
- Haz clic en la pestaña Vulnerabilidades de la imagen.
6. Firma de imágenes
Crea una nota de certificador
Una nota del certificador es solo una pequeña porción de datos que actúa como una etiqueta para el tipo de firma que se aplica. Por ejemplo, una nota puede indicar un análisis de vulnerabilidades, mientras que otra podría usarse para la aprobación del control de calidad. Se hará referencia a la nota durante el proceso de firma.
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}"
Crea un certificador
Los certificadores se usan para realizar el proceso real de firma de imágenes y adjuntarán un caso de la nota a la imagen para su posterior verificación. Crea el certificador para usarlo más adelante.
Crear certificador
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
Verificar certificador
gcloud container binauthz attestors list
Ten en cuenta que la última línea indica NUM_PUBLIC_KEYS: 0
, ya que proporcionarás claves en un paso posterior.
Además, ten en cuenta 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 muestra dos certificadores, vulnz-attestor
y built-by-cloud-build
. Una vez que las imágenes se compilan correctamente, Cloud Build las firma y crea automáticamente certificaciones.
Agrega un rol de IAM
La cuenta de servicio de Autorización Binaria necesitará derechos para ver las notas de la 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"
Agrega una clave de KMS
El certificador necesita claves criptográficas para adjuntar la nota y proporcionar firmas verificables. En este paso, crearás y almacenarás claves en KMS para que Cloud Build pueda acceder a ellas más tarde.
Primero, agrega algunas variables de entorno para describir la clave nueva
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
Crea un llavero de claves que contenga un conjunto de claves
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
Crea un nuevo par de claves de firma asimétrica 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 el certificador a través del comando de 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 vuelves a imprimir la lista de autoridades, ahora deberías ver una clave registrada:
gcloud container binauthz attestors list
Crea una certificación firmada
En este punto, tienes las funciones configuradas que te permiten firmar imágenes. Usar el certificador que creaste anteriormente para firmar la imagen de contenedor con la que trabajaste
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 la certificación. El comando simplemente toma los detalles de la clave que deseas usar para firmar y la imagen del contenedor específica que deseas 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, se creará un caso nuevo y se adjuntará a la nota de tu certificador. Para asegurarte de que todo funcione según lo esperado, puedes enumerar tus certificaciones.
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. Firma con Cloud Build
Habilitaste la firma de imágenes y usaste el certificador de forma manual para firmar tu imagen de muestra. En la práctica, se recomienda aplicar 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 la función 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 la función de 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
Prepara el paso de compilación personalizada de Cloud Build
Usarás un paso de compilación personalizada en Cloud Build para simplificar el proceso de certificación. Google proporciona este paso de Compilación personalizada que contiene funciones auxiliares para optimizar el proceso. Antes de usarlo, el código para el paso de compilación personalizado debe compilarse en un contenedor y enviarse 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 que compilaste antes.
- Revisa el nuevo paso que agregarás.
Solo 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'
- Reemplaza tu archivo cloudbuild.yaml por la canalización completa actualizada.
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, ve a 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.
8. Políticas de control de admisión
La Autorización Binaria es una función de GKE y Cloud Run que proporciona la capacidad de validar reglas antes de que se permita la ejecución de una imagen de contenedor. La validación se ejecuta en cualquier solicitud para ejecutar una imagen, ya sea desde una canalización de CI/CD confiable o cuando un usuario intenta implementar una imagen de forma manual. Esta capacidad te permite proteger los entornos de ejecución de forma más eficaz que las verificaciones de canalización de CI/CD solas.
Para comprender esta capacidad, modificarás la política de GKE predeterminada para aplicar una regla de autorización estricta.
Crea el clúster de GKE
Crea el clúster de GKE:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
Permite que Cloud Build se implemente en este clúster:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
Permitir todas las políticas
Primero, verifica el estado de la política predeterminada y tu capacidad para implementar cualquier imagen
- Revisar la política existente
gcloud container binauthz policy export
- Ten en cuenta que la política de aplicación está establecida en
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- Implementa la muestra para verificar que puedes implementar lo que quieras
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Verifica que la implementación funcionó
kubectl get pods
Verás el siguiente resultado:
- Borrar implementación
kubectl delete pod hello-server
Rechazar todas las políticas
Ahora, actualiza la política para inhabilitar todas las imágenes.
- Exporta la política actual a un archivo editable
gcloud container binauthz policy export > policy.yaml
- Cambiar la política.
En un editor de texto, cambia evaluateMode 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
- 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
- Intento de implementación de carga de trabajo de muestra
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- 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
Revertir la política para permitir todos
Antes de pasar a la siguiente sección, asegúrate de revertir los cambios en la política.
- Cambiar la política.
En un editor de texto, cambia el modo de evaluación 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
- Aplicar la política revertida
gcloud container binauthz policy import policy.yaml
9. Bloquea vulnerabilidades en GKE
En esta sección, combinarás lo que aprendiste hasta ahora implementando una canalización de CI/CD con Cloud Build que analice las imágenes y, luego, verifique si hay vulnerabilidades antes de firmarlas y, luego, intentar implementarlas. GKE usará la autorización binaria para validar que la imagen tenga una firma del análisis de vulnerabilidades antes de permitir que se ejecute.
Actualizar la política de GKE para requerir certificación
Agrega clusterAdmissionRules a tu política de BinAuth de GKE para exigir que las imágenes estén firmadas por tu certificador
Usa el siguiente comando para reemplazar la política por la configuración actualizada.
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
Aplica la política
gcloud beta container binauthz policy import binauth_policy.yaml
Intenta implementar la imagen sin firmar
Crea un descriptor de implementación para la aplicación que compilaste antes con el siguiente comando. La imagen que se usa aquí es la imagen que compilaste antes que contiene vulnerabilidades críticas y NO contiene la certificación firmada.
Los controladores de admisión de GKE deben conocer la imagen exacta que se implementará para validar la firma de forma coherente. Para lograr esto, usa el resumen de la imagen en lugar de una etiqueta simple.
Obtén el resumen de la imagen defectuosa
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 observa el error que indica que se rechazó la implementación:
No attestations found that were valid and signed by a key trusted by the attestor
Implementa una imagen firmada
Obtén el resumen de la imagen defectuosa
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
Implementar la app en GKE.
kubectl apply -f deploy.yaml
Revisa la carga de trabajo en la consola y observa que la imagen se implementó correctamente.
10. ¡Felicitaciones!
¡Felicitaciones! Completaste el codelab.
Temas abordados:
- Cómo habilitar el análisis automático
- Cómo realizar análisis a pedido
- Cómo integrar el análisis en una canalización de compilación
- Cómo firmar imágenes aprobadas
- Cómo usar los controladores de admisión de GKE para bloquear imágenes
- Cómo configurar GKE para permitir solo imágenes aprobadas y firmadas
¿Qué sigue?
- Protege las implementaciones de imágenes en Cloud Run y Google Kubernetes Engine | Documentación de Cloud Build
- Guía de inicio rápido: Configura una política de Autorización Binaria con GKE | Google Cloud
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.