Proteger compilaciones de contenedores

1. Introducción

ead1609267034bf7.png

Las vulnerabilidades de software son debilidades que pueden causar una falla accidental en el sistema o proporcionar a las personas que actúan de mala fe un medio para comprometer el software. Container Analysis proporciona dos tipos de análisis de SO para encontrar vulnerabilidades en los contenedores:

  • La API de On-Demand Scanning te permite analizar manualmente las imágenes de contenedores en busca de vulnerabilidades del SO, ya sea de forma local en tu computadora o de forma remota en Container Registry o Artifact Registry.
  • La API de Container Scanning te permite automatizar la detección de vulnerabilidades del SO y realizar análisis cada vez que envías una imagen a Container Registry o Artifact Registry. Si habilitas esta API, también se habilitarán los análisis de paquetes de lenguajes en busca de vulnerabilidades de Go y Java.

La API de On-Demand Scanning te permite analizar imágenes almacenadas de forma local en tu computadora o de forma remota en Container Registry o Artifact Registry. Esto te brinda un control detallado sobre los contenedores que deseas analizar en busca de vulnerabilidades. Puedes usar On-Demand Scanning para analizar imágenes en tu canalización de CI/CD antes de decidir si quieres almacenarlas en un registro.

Qué aprenderás

En este lab, aprenderá a realizar las siguientes actividades:

  • Compila imágenes con Cloud Build
  • Usa Artifact Registry para contenedores
  • Utiliza los análisis de vulnerabilidades automatizados
  • Configura el análisis a pedido
  • Agrega el análisis de imágenes en CI/CD en Cloud Build

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 el tuyo propio y ver si está disponible. No se puede cambiar después de este paso y se mantendrá mientras dure 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 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.

Configuración del entorno

En Cloud Shell, establece el ID y el número de tu proyecto. 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 

3. Compila imágenes con Cloud Build

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 y cambia a un directorio de trabajo

mkdir vuln-scan && cd vuln-scan

Define una imagen de muestra

Crea un archivo llamado Dockerfile con el siguiente contenido.

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

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: ['-']


EOF

Ejecuta la canalización de CI

Cómo enviar la compilación para su procesamiento

gcloud builds submit

Revisa los detalles de la compilación

Una vez que haya comenzado el proceso de compilación, revise el progreso en el panel de Cloud Build.

  1. Abre Cloud Build en la consola de Cloud.
  2. Haz clic en la compilación para ver el contenido.

4. Artifact Registry para contenedores

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 use tus credenciales de gcloud cuando accedas a Artifact Registry.

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

Actualiza la canalización de Cloud Build

Modifica tu canalización de compilación para enviar la imagen resultante a Artifact Registry

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: ['-']

# push 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']

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

Ejecuta la canalización de CI

Cómo enviar la compilación para su procesamiento

gcloud builds submit

5. Análisis automático de vulnerabilidades

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 sobre vulnerabilidades se actualiza de forma continua cuando se descubren nuevas vulnerabilidades. En esta sección, revisarás la imagen que acabas de compilar y enviar a Artifact Registry para explorar los resultados de vulnerabilidades.

Revisa los detalles de la imagen

Una vez que se haya completado el proceso de compilación anterior, revisa la imagen y los resultados de vulnerabilidades en el panel de Artifact Registry.

  1. Abre Artifact Registry en la consola de Cloud.
  2. Haz clic en Artifact-scanning-repo para ver el contenido.
  3. Haz clic en los detalles de la imagen.
  4. Haz clic en el resumen más reciente de tu imagen.
  5. Una vez que finalice el análisis, haz clic en la pestaña de 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.

361be7b3bf293fca.png

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.

6. Análisis a pedido

Existen varias situaciones en las que es posible que debas realizar un análisis antes de enviar la imagen a un repositorio. A modo de ejemplo, un desarrollador de contenedores puede analizar una imagen y corregir los problemas antes de enviar el código al control de código fuente. En el siguiente ejemplo, compilarás y analizarás la imagen a nivel local antes de actuar en función de los resultados.

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 .

Escanea la imagen

Una vez que se haya compilado la imagen, solicita un análisis de la imagen. 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

Las personas rara vez usan directamente los datos almacenados en el informe. 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 encontraron vulnerabilidades CRÍTICAS.

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 será

Failed vulnerability check for CRITICAL level

7. Análisis en CICD con Cloud Build

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"

Actualiza 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 para su procesamiento y verifica que se interrumpa cuando se encuentre una vulnerabilidad de gravedad CRITICAL.

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 CRÍTICAS.

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

  1. Abre Artifact Registry en la consola de Cloud.
  2. Haz clic en Artifact-scanning-repo para ver el contenido.
  3. Haz clic en los detalles de la imagen.
  4. Haz clic en el resumen más reciente de tu imagen.
  5. Haz clic en la pestaña Vulnerabilidades de la imagen.

8. ¡Felicitaciones!

¡Felicitaciones! Completaste el codelab.

Temas abordados:

  • Compila imágenes con Cloud Build
  • Artifact Registry para contenedores
  • Análisis automático de vulnerabilidades
  • Análisis a pedido
  • Análisis en CICD con Cloud Build

¿Qué sigue?

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