Skip to content

Firmado y Verificación de Imágenes

Introducción

El firmado y verificación de imágenes son prácticas esenciales para garantizar la autenticidad y la integridad de las imágenes de contenedores. Al firmar una imagen, se puede verificar que no ha sido alterada desde su creación y que proviene de una fuente confiable. Este proceso protege contra ataques de suplantación y garantiza que el software desplegado en un entorno de producción es seguro y confiable.

Beneficios de Firmar Imágenes

  • Autenticidad: La firma confirma que la imagen fue creada por una fuente confiable.

  • Integridad: Verificar la firma asegura que la imagen no ha sido alterada desde que fue firmada.

  • Confianza: Provee una cadena de confianza en la cadena de suministro de software, desde el desarrollador hasta el entorno de producción.

Implementar la firma de imágenes es una práctica de seguridad crítica para proteger los entornos de contenedores contra la manipulación y asegurar que solo se despliegan imágenes legítimas y verificadas.

Docker Content Trust (DCT)

Docker Content Trust (DCT) utiliza Notary para proporcionar un mecanismo de firma y verificación de imágenes. Esto asegura que solo las imágenes firmadas puedan ser ejecutadas, protegiendo contra la ejecución de imágenes no verificadas o comprometidas.

Guía Práctica:

Requisitos Previos

  • Tener Docker instalado en tu sistema.
  • Acceso a Docker Hub o a un registro de contenedores privado.

  • Habilitar Docker Content Trust: Para habilitar Docker Content Trust, establece la variable de entorno DOCKER_CONTENT_TRUST a 1.

    export DOCKER_CONTENT_TRUST=1
    

  • Crear un Dockerfile: Crea un archivo Dockerfile simple. Por ejemplo:
    # Usar la imagen base de Alpine
    FROM alpine:latest
    # Ejecutar un comando simple
    CMD ["echo", "Hello, World!"]
    
  • Construye la imagen Docker desde el Dockerfile, actualiza myrepo por el valor que corresponda segun tu repositorio en Docker Hub.
    docker build -t myrepo/myimage:latest .
    
  • Firmar la Imagen al Pushear a Docker Hub: Cuando pushes la imagen al registro, Docker Content Trust firmará automáticamente la imagen. Si es la primera vez, se te pedirá que crees claves para firmar la imagen.
    [student@student-0-aio ~]$ docker login  -u your-username
    Password: 
    WARNING! Your password will be stored unencrypted in /home/student/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
    
    docker push myrepo/myimage:latest
    
    Durante este proceso, se te pedirá que crees una clave de raíz y una clave de firma delegada. Asegúrate de mantener estas claves seguras.
    You are about to create a new root signing key passphrase. This passphrase
    will be used to protect the most sensitive key in your signing system. Please
    choose a long, complex passphrase and be careful to keep the password and the
    key file itself secure and backed up. It is highly recommended that you use a
    password manager to generate the passphrase and keep it safe. There will be no
    way to recover this key. You can find the key in your config directory.
    Enter passphrase for new root key with ID 2c71e5c:
    Repeat passphrase for new root key with ID 2c71e5c:
    Enter passphrase for new repository key with ID a680863:
    Repeat passphrase for new repository key with ID a680863:
    
  • Verificar la Imagen al Pushear: Docker Content Trust verificará automáticamente la firma cuando intentes pushear la imagen.
    docker pull myrepo/myimage:latest
    
  • Ejecutar la Imagen: Ejecuta el contenedor desde la imagen firmada para asegurarte de que todo funciona correctamente.
    docker run --rm --name myimage myrepo/myimage:latest
    
    La salida debería ser: Hello, World!
  • Limpieza del ambiente:
    docker stop myimage ; docker rm myimage
    
    rm -f Dockerfile
    

Cosign y sigstore para Firmar y Verificar Imágenes

Cosign es una herramienta del proyecto Sigstore que permite firmar, verificar y almacenar firmas de imágenes de contenedores directamente en el registro de contenedores. Esta herramienta facilita la implementación de firmas de imágenes en pipelines CI/CD, mejorando la seguridad y la confianza en la cadena de suministro de software.

Requisitos Previos

  • Tener Docker instalado en tu sistema.
  • Tener Cosign instalado. Puedes descargar Cosign desde el repositorio oficial de Cosign.
  • Acceso a Docker Hub o a un registro de contenedores privado.

  • Descargar Cosign:

    sudo curl -L https://github.com/sigstore/cosign/releases/download/v1.2.1/cosign-linux-amd64 -o /usr/local/bin/cosign
    
    sudo chmod +x /usr/local/bin/cosign
    

  • Generar un Par de Claves: Cosign utiliza claves públicas y privadas para firmar y verificar imágenes.
    cosign generate-key-pair
    
    Enter password for private key: 
    Enter password for private key again: 
    Private key written to cosign.key
    Public key written to cosign.pub
    
    Este comando generará cosign.key (clave privada) y cosign.pub (clave pública) en el directorio actual. Asegúrate de mantener estas claves seguras.
  • Crear un Dockerfile: Crea un archivo Dockerfile simple. Por ejemplo:
    # Usar la imagen base de Alpine
    FROM alpine:latest
    # Ejecutar un comando simple
    CMD ["echo", "Hello, World!"]
    
  • Construir la Imagen: Construye la imagen Docker desde el Dockerfile y hacer Push a Docker Hub
    docker build -t mydockerhubusername/mysecureapp:latest .
    
    docker push mydockerhubusername/mysecureapp:latest
    
  • Firmar la Imagen con Cosign: Usa la clave privada generada para firmar la imagen.
    cosign sign --key cosign.key mydockerhubusername/mysecureapp:latest
    
    Esto almacenará la firma junto con la imagen en el registro de contenedores.
  • Verificar la Firma de la Imagen: Usa la clave pública para verificar la firma de la imagen.
    cosign verify --key cosign.pub mydockerhubusername/mysecureapp:latest
    
    Si la imagen está correctamente firmada, la verificación será exitosa y mostrará información sobre la firma.
    Verification for mydockerhubusername/mysecureapp:latest --
    The following checks were performed on each of these signatures:
      - The cosign claims were validated
      - The signatures were verified against the specified public key
      - Any certificates were verified against the Fulcio roots.
    [{"critical":{"identity":{"docker-reference":"index.docker.io/mydockerhubusername/mysecureapp"},"image":{"docker-manifest-digest":"sha256:94aa7a4b03663a5a9e82ad4f149e62c3e4101b3ee957f3d956d16aae3eea03d7"},"type":"cosign container image signature"},"optional":null}]
    
  • Rotar Claves de Firma: Si necesitas rotar las claves (por ejemplo, si una clave ha sido comprometida), puedes generar un nuevo par de claves y firmar nuevamente la imagen.
    cosign generate-key-pair
    
    Enter password for private key: 
    Enter password for private key again: 
    Private key written to cosign.key
    Public key written to cosign.pub
    
    cosign sign --key cosign.key mydockerhubusername/mysecureapp:latest
    
  • Ejecutar la Imagen Firmada: Ejecuta el contenedor desde la imagen firmada para asegurarte de que todo funciona correctamente.
    docker run --rm --name secureapp mydockerhubusername/mysecureapp:latest
    
    La salida debería ser: Hello, World!
  • Eliminar Contenedores y Imágenes: Después de las pruebas, limpia tu entorno eliminando los contenedores y las imágenes creadas.
    docker stop secureapp ; docker rm secureapp
    
    docker rmi mydockerhubusername/mysecureapp:latest
    
  • Eliminar Claves Generadas: Si ya no necesitas las claves generadas para la prueba, elimínalas de tu sistema.
    rm cosign.key cosign.pub
    
  • Eliminar archivos geenrados
    rm -f Dockerfile
    

Resumen

Firmar y verificar imágenes de contenedores es crucial para la seguridad en la cadena de suministro de software. Herramientas como Docker Content Trust, Notary y Cosign proporcionan mecanismos robustos para asegurar que solo se ejecuten imágenes confiables. Implementar estas prácticas en el desarrollo y despliegue de contenedores mejora significativamente la seguridad del entorno Kubernetes.