Compartir a través de


Firmar imágenes de contenedores utilizando Notation, Azure Key Vault y un certificado emitido por una CA

Este artículo forma parte de una serie sobre cómo garantizar la integridad y la autenticidad de las imágenes de contenedor y otros artefactos de Open Container Initiative (OCI). Para obtener la imagen completa, comience con la información general, que explica por qué la firma es importante y describe los distintos escenarios.

Firmar y comprobar imágenes de contenedor mediante un certificado de una entidad de certificación (CA) de confianza es una práctica de seguridad valiosa. Le ayuda a identificar, autorizar y validar de forma responsable la identidad del publicador de una imagen de contenedor y la propia imagen de contenedor. Las CA de confianza, como GlobalSign, DigiCert y otros, desempeñan un papel fundamental en:

  • Validar la identidad de un usuario u organización.
  • Mantener la seguridad de los certificados digitales.
  • Revocar certificados inmediatamente después de cualquier riesgo o uso incorrecto.

Estos son algunos componentes esenciales que le ayudan a firmar y comprobar imágenes de contenedor mediante un certificado de una ENTIDAD de certificación de confianza:

  • Notación es una herramienta de seguridad de cadena de suministro de código abierto desarrollada por la comunidad de Notary Project y respaldada por Microsoft. Admite la firma y comprobación de imágenes de contenedor y otros artefactos.
  • Azure Key Vault es un servicio basado en la nube para administrar claves criptográficas, secretos y certificados. Le ayuda a almacenar y administrar de forma segura un certificado con una clave de firma.
  • El complemento Key Vault (notation-azure-kv) es una extensión de Notación. Usa las claves almacenadas en Key Vault para firmar y comprobar las firmas digitales de imágenes y artefactos de contenedor.
  • Azure Container Registry es un registro privado que puede usar para adjuntar firmas a imágenes de contenedor, junto con el almacenamiento y la administración de estas imágenes.

Al comprobar una imagen, la firma se usa para validar la integridad de la imagen y la identidad del firmante. Esta validación ayuda a garantizar que las imágenes de contenedor no se manipulan y proceden de un origen de confianza.

En este artículo aprenderá a:

  • Instale la interfaz de la línea de comandos (CLI) de Notation y el complemento key Vault.
  • Cree o importe un certificado emitido por la ENTIDAD de certificación en Key Vault.
  • Compile e inserte una imagen de contenedor mediante tareas de Container Registry.
  • Firme una imagen de contenedor mediante la CLI de Notación y el complemento Key Vault.
  • Verifique una firma de imagen de contenedor mediante la Notation CLI (Interfaz de Línea de Comandos).
  • Use la marca de tiempo.

Requisitos previos

Instala la CLI de Notation y el complemento de Key Vault

  1. Instale Notation v1.3.2 en un entorno linux AMD64. Para descargar el paquete para otros entornos, siga la guía de instalación de notación.

    # Download, extract, and install
    curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v1.3.2/notation_1.3.2_linux_amd64.tar.gz
    tar xvzf notation.tar.gz
    
    # Copy the Notation CLI to the desired bin directory in PATH, for example
    cp ./notation /usr/local/bin
    
  2. Instale el complemento Key Vault (notation-azure-kv) v1.2.1 en un entorno linux AMD64.

    Nota:

    Puede encontrar la dirección URL y la suma de comprobación SHA256 del complemento en la página de versión del complemento.

    notation plugin install --url https://github.com/Azure/notation-azure-kv/releases/download/v1.2.1/notation-azure-kv_1.2.1_linux_amd64.tar.gz --sha256sum 67c5ccaaf28dd44d2b6572684d84e344a02c2258af1d65ead3910b3156d3eaf5
    
  3. Enumere los complementos disponibles y confirme que el notation-azure-kv complemento con la versión 1.2.1 está incluido en la lista:

    notation plugin ls
    

Configuración de las variables de entorno

En este artículo se usan variables de entorno para mayor comodidad en la configuración de Key Vault y Container Registry. Actualice los valores de estas variables de entorno para sus recursos específicos.

  1. Configure variables de entorno para Key Vault y certificados:

    AKV_SUB_ID=myAkvSubscriptionId
    AKV_RG=myAkvResourceGroup
    AKV_NAME=myakv 
    
    # Name of the certificate created or imported in Key Vault 
    CERT_NAME=wabbit-networks-io 
    
    # X.509 certificate subject
    CERT_SUBJECT="CN=wabbit-networks.io,O=Notation,L=Seattle,ST=WA,C=US"
    
  2. Configuración de variables de entorno para Container Registry e imágenes:

    ACR_SUB_ID=myAcrSubscriptionId
    ACR_RG=myAcrResourceGroup
    # Name of the existing registry example: myregistry.azurecr.io 
    ACR_NAME=myregistry 
    # Existing full domain of the container registry 
    REGISTRY=$ACR_NAME.azurecr.io 
    # Container name inside the container registry where the image will be stored 
    REPO=net-monitor 
    TAG=v1 
    # Source code directory that contains the Dockerfile to build 
    IMAGE_SOURCE=https://github.com/wabbit-networks/net-monitor.git#main  
    

Inicio de sesión mediante la CLI de Azure

az login

Para más información, consulte Autenticación en Azure mediante la CLI de Azure.

Creación o importación de un certificado emitido por la ENTIDAD de certificación en Key Vault

Descripción de los requisitos de certificado

Al crear certificados para firmar y verificación, los certificados deben cumplir los requisitos del Notary Project.

Los requisitos para los certificados raíz e intermedios son los siguientes:

  • La basicConstraints extensión debe estar presente y marcada como critical. El CA campo debe establecerse en true.
  • La keyUsage extensión debe estar presente y marcada como critical. Las posiciones de bits para keyCertSign deben establecerse.

Estos son los requisitos para los certificados que emite una entidad de certificación:

  • Propiedades de los certificados X.509:
    • El sujeto debe contener el nombre común (CN), el país o la región (C), el estado o la provincia (ST), y la organización (O). En este artículo se usa $CERT_SUBJECT como asunto.
    • La marca de uso de clave de X.509 debe ser solo DigitalSignature.
    • Los usos extendidos de clave (EKU) deben estar vacíos o 1.3.6.1.5.5.7.3.3 (para la firma de código).
  • Propiedades de la clave:

Importante

Para garantizar una integración correcta con integridad de imagen, el tipo de contenido de certificado debe establecerse en PEM.

En esta guía se usa la versión 1.0.1 del complemento key Vault. Las versiones anteriores del complemento tenían una limitación que requería un orden de certificado específico en una cadena de certificados. La versión 1.0.1 del complemento no tiene esta limitación, por lo que se recomienda usar la versión 1.0.1 o posterior.

Creación de un certificado emitido por la ENTIDAD de certificación

Cree una solicitud de firma de certificado (CSR) siguiendo las instrucciones de Creación y combinación de una solicitud de firma de certificado en Key Vault.

Al combinar la CSR, asegúrese de combinar toda la cadena que ha devuelto del proveedor de la entidad de certificación.

Importación del certificado en Key Vault

Para importar el certificado:

  1. Obtenga el archivo de certificado del proveedor de CA con toda la cadena de certificado.
  2. Importe el certificado en Key Vault siguiendo las instrucciones de Importación de un certificado en Azure Key Vault.

Si el certificado no contiene una cadena de certificados después de crearlo o importarlo, puede obtener los certificados intermedios y raíz del proveedor de ca. Puede pedirle al proveedor que le proporcione un archivo PEM que contenga los certificados intermedios (si los hay) y el certificado raíz. Después, puede usar este archivo al firmar imágenes de contenedores.

Firmar una imagen de contenedor utilizando la CLI de Notation y el complemento Key Vault

Cuando trabaja con Container Registry y Key Vault, es esencial conceder los permisos adecuados para ayudar a garantizar el acceso seguro y controlado. Puede autorizar el acceso a varias entidades, como principales de usuario, principales de servicio o identidades administradas, según tus escenarios específicos. En este artículo, el acceso está autorizado para un usuario de Azure que ha iniciado sesión.

Autorización del acceso a Container Registry

Para los registros habilitados para el control de acceso basado en atributos (ABAC) de Microsoft Entra, Container Registry Repository Reader y Container Registry Repository Writer roles son necesarios para construir y firmar imágenes de contenedor en el Registro de Contenedores.

En el caso de los registros no habilitados para ABAC, se requieren los roles AcrPull y AcrPush.

Para obtener más información sobre ABAC, consulte Control de acceso basado en atributos de Microsoft Entra para permisos de repositorio.

  1. Establezca la suscripción que contiene el recurso de Container Registry:

    az account set --subscription $ACR_SUB_ID
    
  2. Asigne los roles:

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    ROLE1="Container Registry Repository Reader" # For ABAC-enabled registries. Otherwise, use "AcrPull" for non-ABAC-enabled registries.
    ROLE2="Container Registry Repository Writer" # For ABAC-enabled registries. Otherwise, use "AcrPush" for non-ABAC-enabled registries.
    az role assignment create --role "$ROLE1" --role "$ROLE2" --assignee $USER_ID --scope "/subscriptions/$ACR_SUB_ID/resourceGroups/$ACR_RG/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
    

Compilación e inserción de imágenes de contenedor en Container Registry

  1. Autentíquese en el registro de contenedor mediante la identidad de Azure individual:

    az acr login --name $ACR_NAME
    

    Importante

    Si tiene Docker instalado en el sistema y ha usado az acr login o docker login para autenticarse en el registro de contenedor, las credenciales ya están almacenadas y disponibles para notación. En este caso, no es necesario volver a ejecutar notation login para autenticarse en el registro de contenedor. Para más información sobre las opciones de autenticación para notación, consulte Autenticación con registros compatibles con OCI.

  2. Compile e inserte una nueva imagen mediante tareas de Container Registry. digest Use siempre para identificar la imagen para firmar, ya que las etiquetas son mutables y se pueden sobrescribir.

    DIGEST=$(az acr build -r $ACR_NAME -t $REGISTRY/${REPO}:$TAG $IMAGE_SOURCE --no-logs --query "outputImages[0].digest" -o tsv)
    IMAGE=$REGISTRY/${REPO}@$DIGEST
    

    En este artículo, si la imagen ya está compilada y se almacena en el Registro, la etiqueta actúa como identificador para esa imagen para mayor comodidad:

    IMAGE=$REGISTRY/${REPO}@$TAG
    

Autorización del acceso a Key Vault

En esta sección se exploran dos opciones para autorizar el acceso a Key Vault.

  1. Establezca la suscripción que contiene el recurso de Key Vault:

    az account set --subscription $AKV_SUB_ID
    
  2. Asigne los roles.

    Si el certificado contiene toda la cadena de certificados, la entidad de seguridad debe asignarse con los siguientes roles:

    • Key Vault Secrets User para leer secretos
    • Key Vault Certificates User para leer certificados
    • Key Vault Crypto User para las operaciones de firma
    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "Key Vault Secrets User" --role "Key Vault Certificates User" --role "Key Vault Crypto User" --assignee $USER_ID --scope "/subscriptions/$AKV_SUB_ID/resourceGroups/$AKV_RG/providers/Microsoft.KeyVault/vaults/$AKV_NAME"
    

    Si el certificado no contiene la cadena, la entidad de seguridad debe asignarse con los roles siguientes:

    • Key Vault Certificates User para leer certificados
    • Key Vault Crypto User para las operaciones de firma
    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "Key Vault Certificates User" --role "Key Vault Crypto User" --assignee $USER_ID --scope "/subscriptions/$AKV_SUB_ID/resourceGroups/$AKV_RG/providers/Microsoft.KeyVault/vaults/$AKV_NAME"
    

Para más información sobre el acceso a Key Vault con el control de acceso basado en rol (RBAC) de Azure, consulte Proporcionar acceso a claves, certificados y secretos de Key Vault mediante el control de acceso basado en rol de Azure.

Uso de una directiva de acceso (heredada)

Para establecer la suscripción que contiene los recursos de Key Vault, ejecute el siguiente comando:

az account set --subscription $AKV_SUB_ID

Si el certificado contiene toda la cadena de certificados, al sujeto principal se le debe conceder el permiso de clave Sign, el permiso secreto Get y el permiso de certificado Get. Para conceder estos permisos a la entidad de seguridad, use este comando:

USER_ID=$(az ad signed-in-user show --query id -o tsv)
az keyvault set-policy -n $AKV_NAME --key-permissions sign --secret-permissions get --certificate-permissions get --object-id $USER_ID

Si el certificado no contiene la cadena, a la principal se le debe conceder el permiso de clave y el Sign permiso de certificado Get. Para conceder estos permisos a la entidad de seguridad, use este comando:

USER_ID=$(az ad signed-in-user show --query id -o tsv)
az keyvault set-policy -n $AKV_NAME --key-permissions sign --certificate-permissions get --object-id $USER_ID

Para obtener más información sobre cómo asignar una directiva a un principal, consulte Asignar una política de acceso de Key Vault (heredada).

Firmar imágenes de contenedor mediante el certificado en Key Vault

  1. Obtenga el identificador de clave de un certificado. Un certificado de Key Vault puede tener varias versiones. El comando siguiente obtiene el identificador de clave de la versión más reciente del $CERT_NAME certificado:

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv) 
    
  2. Firme la imagen del contenedor con el formato de firma y cifrado de objetos (COSE) de CBOR utilizando el identificador de clave.

    Si el certificado contiene toda la cadena de certificados, ejecute el siguiente comando:

    notation sign --signature-format cose $IMAGE --id $KEY_ID --plugin azure-kv 
    

    Si el certificado no contiene la cadena, use el parámetro --plugin-config ca_certs=<ca_bundle_file> para pasar los certificados de la Autoridad de Certificación en un archivo PEM al plugin de Key Vault. Ejecute el siguiente comando:

    notation sign --signature-format cose $IMAGE --id $KEY_ID --plugin azure-kv --plugin-config ca_certs=<ca_bundle_file> 
    

    Para autenticarse con Key Vault, de forma predeterminada, se intentan los siguientes tipos de credenciales (si están habilitados):

    Si desea especificar un tipo de credencial, use una configuración adicional de complemento denominada credential_type. Por ejemplo, puede establecer credential_type explícitamente en azurecli para usar una credencial de la CLI de Azure, como se muestra en este ejemplo:

    notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config credential_type=azurecli $IMAGE
    

    En la siguiente tabla se muestran los valores de credential_type para varios tipos de credenciales.

    Tipo de credencial Valor para credential_type
    Credenciales de entorno environment
    Credencial de identidad de carga de trabajo workloadid
    Credenciales de identidad administrada managedid
    Credencial de la CLI de Azure azurecli
  3. Vea el gráfico de imágenes firmadas y firmas asociadas:

    notation ls $IMAGE
    

    En la salida del ejemplo siguiente, una firma de tipo application/vnd.cncf.notary.signature, identificada por el resumen sha256:d7258166ca820f5ab7190247663464f2dcb149df4d1b6c4943dcaac59157de8e, se asocia a $IMAGE.

    myregistry.azurecr.io/net-monitor@sha256:17cc5dd7dfb8739e19e33e43680e43071f07497ed716814f3ac80bd4aac1b58f
    └── application/vnd.cncf.notary.signature
        └── sha256:d7258166ca820f5ab7190247663464f2dcb149df4d1b6c4943dcaac59157de8e
    

Nota:

Desde Notation v1.2.0, Notation usa el esquema de etiquetas de referencia de OCI para almacenar la firma en el Registro de Contenedores de forma predeterminada. También puede habilitar la API de referencias de OCI mediante la marca --force-referrers-tag false, si es necesario. Las características de Container Registry admiten la API de referencias de OCI, excepto el registro cifrado mediante claves administradas por el cliente (CMK).

Verifique una imagen de contenedor utilizando la CLI de Notation

  1. Agregue el certificado raíz a un almacén de confianza con nombre para la comprobación de firmas. Si no tiene el certificado raíz, puede obtenerlo de la entidad de certificación. En el siguiente ejemplo, se agrega el certificado raíz $ROOT_CERT al almacén de confianza $STORE_NAME.

    STORE_TYPE="ca" 
    STORE_NAME="wabbit-networks.io" 
    notation cert add --type $STORE_TYPE --store $STORE_NAME $ROOT_CERT  
    
  2. Para enumerar el certificado raíz y confirmar que $ROOT_CERT se ha agregado correctamente:

    notation cert ls 
    
  3. Configure una directiva de confianza antes de la comprobación. Las directivas de confianza permiten a los usuarios especificar directivas de comprobación optimizadas. Use el siguiente comando:

    cat <<EOF > ./trustpolicy.json
    {
        "version": "1.0",
        "trustPolicies": [
            {
                "name": "wabbit-networks-images",
                "registryScopes": [ "$REGISTRY/$REPO" ],
                "signatureVerification": {
                    "level" : "strict" 
                },
                "trustStores": [ "$STORE_TYPE:$STORE_NAME" ],
                "trustedIdentities": [
                    "x509.subject: $CERT_SUBJECT"
                ]
            }
        ]
    }
    EOF
    

    El archivo anterior trustpolicy.json define una directiva de confianza denominada wabbit-networks-images. Esta directiva de confianza se aplica a todos los artefactos almacenados en los repositorios de $REGISTRY/$REPO. El almacén de confianza con nombre $STORE_NAME de tipo $STORE_TYPE contiene los certificados raíz. Esta política también supone que el usuario confía en una identidad específica con el sujeto X.509 $CERT_SUBJECT. Para obtener más información, consulte la especificación del almacén de confianza y la directiva de confianza.

  4. Use notation policy para importar la configuración de la directiva de confianza desde trustpolicy.json:

    notation policy import ./trustpolicy.json
    
  5. Mostrar la configuración de la directiva de confianza para confirmar su importación correcta:

    notation policy show
    
  6. Use notation verify para comprobar la integridad de la imagen:

    notation verify $IMAGE
    

    Tras la comprobación correcta de la imagen a través de la directiva de confianza, el resumen SHA256 de la imagen verificada se devuelve en un mensaje de salida correcto. A continuación, presentamos un ejemplo de la salida:

    Successfully verified signature for myregistry.azurecr.io/net-monitor@sha256:17cc5dd7dfb8739e19e33e43680e43071f07497ed716814f3ac80bd4aac1b58f

Use la marca de tiempo

Desde la versión Notation v1.2.0, Notation admite la marca de tiempo compatible con RFC 3161. Esta mejora amplía la confianza de las firmas creadas dentro del período de validez del certificado mediante la confianza en una autoridad de sello de tiempo (TSA). Esta confianza permite la comprobación correcta de firmas incluso después de que expiren los certificados.

Como firmante de imágenes, debe asegurarse de que las imágenes de contenedores se firmen con marcas de tiempo generadas por una TSA de confianza. Como verificador de imágenes, debe asegurarse de que confía tanto en el firmante de imágenes como en el TSA asociado, y establecer la confianza a través de almacenes de confianza y políticas de confianza.

La marca de tiempo reduce los costos eliminando la necesidad de volver a firmar periódicamente las imágenes debido a la expiración del certificado. Esta capacidad es especialmente crítica cuando se usan certificados de corta duración. Para obtener instrucciones detalladas sobre cómo firmar y comprobar imágenes mediante la marca de tiempo, consulte la guía de marcas de tiempo del proyecto notario.

Preguntas más frecuentes

  • ¿Qué debo hacer si expira el certificado?

    Si el certificado expira, debe obtener uno nuevo de un proveedor de ca de confianza, junto con una nueva clave privada. No puede usar un certificado expirado para firmar imágenes de contenedor.

    Las imágenes firmadas antes de que el certificado expirara podrían validarse correctamente si se firmaban con la marca de tiempo. Sin la marca de tiempo, la verificación de la firma falla, y necesita volver a firmar esas imágenes con el nuevo certificado para una verificación correcta.

  • ¿Qué debo hacer si se revoca el certificado?

    La revocación del certificado invalida la firma. Esta situación puede ocurrir por varias razones, como el compromiso de la clave privada o los cambios en la afiliación del titular del certificado.

    Para resolver este problema, primero debe asegurarse de que el código fuente y el entorno de compilación estén actualizados y seguros. A continuación, compile imágenes de contenedor desde el código fuente, obtenga un nuevo certificado de un proveedor de CA de confianza junto con una nueva clave privada y firme nuevas imágenes de contenedor con el nuevo certificado siguiendo esta guía.

Notación proporciona soluciones de integración continua y entrega continua (CI/CD) en Azure Pipelines y GitHub Actions.

Para garantizar que solo se despliegan imágenes de contenedor de confianza en Azure Kubernetes Service (AKS):