Compartir a través de


Firma de imágenes de contenedor con notación y Azure Key Vault mediante un certificado emitido por CA

Firmar y comprobar imágenes de contenedor con un certificado emitido por una entidad de certificación (CA) de confianza es una buena práctica de seguridad. Esta medida de seguridad le ayudará a identificar, autorizar y validar de forma responsable la identidad del editor de la imagen de contenedor y de la imagen en sí. Las entidades de certificación (CA) de confianza, como GlobalSign, DigiCert y otras, desempeñan un papel fundamental en la validación de la identidad de un usuario o una organización, ya que mantienen la seguridad de los certificados digitales y los revocan inmediatamente ante cualquier riesgo o uso indebido.

Estos son algunos componentes esenciales que ayudan a firmar y comprobar imágenes de contenedor con un certificado emitido por una entidad de certificación de confianza:

  • Notation es una herramienta de seguridad de cadena de suministro de código abierto desarrollada por la comunidad Notary Project y respaldada por Microsoft, que permite firmar y comprobar imágenes de contenedor y otros artefactos.
  • Azure Key Vault (AKV), un servicio basado en la nube para administrar claves criptográficas, secretos y certificados, le ayuda a asegurarse de almacenar y administrar un certificado de forma segura con una clave de firma.
  • Complemento azure-kv de AKV para Notation. La extensión de Notation usa las claves almacenadas en Azure Key Vault para firmar y comprobar las firmas digitales de imágenes y artefactos de contenedor.
  • Azure Container Registry (ACR) permite adjuntar estas firmas a la imagen firmada y facilita el almacenamiento y la administración de estas imágenes de contenedor.

Cuando comprueba la imagen, la firma se usa para validar la integridad de la imagen y la identidad del firmante. Esto ayuda a asegurarse de que las imágenes de contenedor no se han manipulado y proceden de un origen de confianza.

En este artículo:

  • Instalación de la CLI de notación y el complemento de AKV
  • Creación o importación de un certificado emitido por una entidad de certificación en AKV
  • Compilación e inserción de una imagen de contenedor con la tarea ACR
  • Firmar una imagen de contenedor con la CLI de notación y el complemento de AKV
  • Comprobación de una firma de imagen de contenedor con la CLI de Notation
  • Marca de tiempo

Requisitos previos

Nota:

Se recomienda crear una instancia de Azure Key Vault para almacenar solo certificados.

Instalación de la CLI de notación y el complemento de AKV

  1. Instale Notation v1.2.0 en un entorno Linux amd64. Siga la guía de instalación de Notation para descargar el paquete para otros entornos.

    # Download, extract and install
    curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v1.2.0/notation_1.2.0_linux_amd64.tar.gz
    tar xvzf notation.tar.gz
    
    # Copy the notation cli to the desired bin directory in your PATH, for example
    cp ./notation /usr/local/bin
    
  2. Instale el complemento Notation Azure Key Vault azure-kv v1.2.0 en un entorno Linux amd64.

    Nota:

    La dirección URL y la suma de comprobación SHA256 para el complemento Notation de Azure Key Vault se pueden encontrar en la página de versión del complemento.

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

    notation plugin ls
    

Configuración de las variables de entorno

Nota:

En esta guía se usan variables de entorno para mayor comodidad cuando se configuran AKV y ACR. Actualice los valores de estas variables de entorno para sus recursos específicos.

  1. Configurar variables de entorno para AKV y certificados

    AKV_SUB_ID=myAkvSubscriptionId
    AKV_RG=myAkvResourceGroup
    AKV_NAME=myakv 
    
    # Name of the certificate created or imported in AKV 
    CERT_NAME=wabbit-networks-io 
    
    # X.509 certificate subject
    CERT_SUBJECT="CN=wabbit-networks.io,O=Notation,L=Seattle,ST=WA,C=US"
    
  2. Configurar variables de entorno para ACR 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 ACR 
    REGISTRY=$ACR_NAME.azurecr.io 
    # Container name inside ACR where image will be stored 
    REPO=net-monitor 
    TAG=v1 
    # Source code directory containing Dockerfile to build 
    IMAGE_SOURCE=https://github.com/wabbit-networks/net-monitor.git#main  
    

Inicio de sesión con la CLI de Azure

az login

Para más información sobre la CLI de Azure y cómo iniciar sesión con ella, consulte Inicio de sesión con la CLI de Azure.

Creación o importación de un certificado emitido por una entidad de certificación en AKV

Requisitos de certificados

Cuando se crean certificados con fines de firma y verificación, esos certificados deben cumplir el requisito de certificado de Notary Project.

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

  • La extensión basicConstraints debe estar presente y marcada como crítica. El campo CA debe establecerse en true.
  • La extensión keyUsage debe estar presente y marcada como critical. DEBEN establecerse las posiciones de bits de keyCertSign.

Los requisitos para los certificados emitidos por una entidad de certificación son los siguientes:

  • Propiedades de los certificados X.509:
    • El firmante debe contener un nombre común (CN), el país (C), el estado o la provincia (ST) y la organización (O). En este tutorial, se usa $CERT_SUBJECT como firmante.
    • La marca de uso de clave de X.509 debe ser solo DigitalSignature.
    • Los usos mejorados de clave (EKU) deben estar vacíos o ser 1.3.6.1.5.5.7.3.3 (para 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.

Nota:

En esta guía se usa la versión 1.0.1 del complemento de AKV. Las versiones anteriores del complemento tenían una limitación que requería un orden 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 una entidad de certificación

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

Importante

Al combinar la solicitud CSR, asegúrese de combinar toda la cadena que recuperó del proveedor de CA.

Importación del certificado en AKV

Para importar el certificado:

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

Nota:

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 en el paso 5 de Firmar una imagen de contenedor con la CLI de notación y el complemento de AKV.

Firmar una imagen de contenedor con la CLI de notación y el complemento de AKV

Al trabajar con ACR y AKV, es esencial conceder los permisos adecuados para garantizar el acceso seguro y controlado. Puede autorizar el acceso a diferentes entidades, como entidades de seguridad de usuario, entidades de servicio o identidades administradas, en función de sus escenarios específicos. En este tutorial, el acceso está autorizado a un usuario de Azure que ha iniciado sesión.

Creación del acceso a ACR

Los roles AcrPull y AcrPush son necesarios para compilar y firmar imágenes de contenedor en ACR.

  1. Configurar la suscripción que contiene el recurso ACR

    az account set --subscription $ACR_SUB_ID
    
  2. Asignar los roles

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "AcrPull" --role "AcrPush" --assignee $USER_ID --scope "/subscriptions/$ACR_SUB_ID/resourceGroups/$ACR_RG/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
    

Compilar e insertar imágenes de contenedor a ACR

  1. Autentíquese en ACR mediante su 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 ACR, las credenciales ya están almacenadas y disponibles para la notación. En este caso, no es necesario volver a ejecutar notation login para autenticarse en ACR. Para más información sobre las opciones de autenticación para la notación, consulte Autenticación con registros compatibles con OCI.

  1. Compile e inserte una nueva imagen con ACR Tasks. Use siempre digest 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 tutorial, si la imagen ya se ha compilado y se almacena en el Registro, la etiqueta sirve como identificador de esa imagen para mayor comodidad.

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

Creación del acceso a AKV

  1. Configurar la suscripción que contiene el recurso AKV

    az account set --subscription $AKV_SUB_ID
    
  2. Asignar 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 Userpara 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 Userpara 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 obtener más información sobre el acceso de Key Vault con RBAC de Azure, consulte Usar RBAC de Azure para administrar el acceso.

Usar la directiva de acceso (heredado)

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

az account set --subscription $AKV_SUB_ID

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

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 entidad de seguridad se le debe conceder el permiso de clave Sign y los permisos de certificado Get. Para conceder estos permisos a la entidad de seguridad:

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 la asignación de directivas a una entidad de seguridad, consulte Asignación de directiva de acceso.

Firmar imágenes de contenedor con el certificado en AKV

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

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv) 
    
  2. Firme la imagen de contenedor con el formato de firma COSE usando el id. 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 CA en un archivo PEM al complemento de AKV. 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 AKV, de manera predeterminada, se intentarán los siguientes tipos de credenciales si está habilitado en orden:

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

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

    Consulte la tabla siguiente para ver 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 las firmas asociadas.

    notation ls $IMAGE
    

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

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

Comprobación de una imagen de contenedor con la CLI de notación

  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 ejemplo siguiente 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. Enumere el certificado raíz para confirmar que $ROOT_CERT se ha agregado correctamente.

    notation cert ls 
    
  3. Configure la directiva de confianza antes de la comprobación.

    Las directivas de confianza permiten a los usuarios especificar directivas de verificación ajustadas. Use el siguiente comando para configurar la directiva de confianza.

    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 trustpolicy.json anterior 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. También supone que el usuario confía en una identidad específica con el asunto X.509 $CERT_SUBJECT. Consulte Especificación de la directiva de confianza y el almacén de confianza para obtener más información.

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

    notation policy import ./trustpolicy.json
    
  5. Muestre la configuración de la directiva de confianza para confirmar que se ha importado correctamente.

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

    notation verify $IMAGE
    

    Una vez verificada correctamente la imagen mediante la directiva de confianza, se devuelve el resumen sha256 de la imagen verificada en un mensaje de salida correcto. Ejemplo de salida:

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

Marca de tiempo

Desde la versión Notation v1.2.0, Notation es compatible con la marca de tiempo RFC 3161. Esta mejora amplía la confianza de las firmas creadas dentro del período de validez del certificado al confiar en una entidad de marca de tiempo (TSA), lo que permite la comprobación correcta de firmas incluso después de que los certificados hayan expirado. Como firmante de imágenes, debe asegurarse de firmar imágenes de contenedor con marcas de tiempo generadas por un TSA de confianza. Como comprobador de imágenes, para comprobar las marcas de tiempo, debe asegurarse de que confía tanto en el firmante de imagen como en el TSA asociado, y establecer la confianza a través de almacenes de confianza y directivas de confianza. La marca de tiempo reduce los costos al eliminar la necesidad de volver a firmar periódicamente las imágenes debido a la expiración del certificado, lo que es especialmente crítico cuando se usan certificados de corta duración. Para obtener instrucciones detalladas sobre cómo firmar y comprobar el uso de la marca de tiempo, consulte la Guía de marcas de tiempo del proyecto de Notary.

Preguntas más frecuentes

  • ¿Qué debo hacer si el certificado ha expirado?

    Si el certificado ha expirado, debe obtener uno nuevo de un proveedor de CA de confianza junto con una nueva clave privada. No se puede usar un certificado expirado para firmar imágenes de contenedor. En el caso de las imágenes firmadas antes de que expire el certificado, es posible que todavía se validen correctamente si se han firmado con la marca de tiempo. Sin la marca de tiempo, se producirá un error en la comprobación de la firma y tendrá que volver a firmar esas imágenes con el nuevo certificado para la comprobación correcta.

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

    Si se revoca el certificado, se invalida la firma. Esto puede ocurrir por varias razones, como si la clave privada queda en peligro o por 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 sean 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.

Pasos siguientes

La notación también proporciona soluciones de CI/CD en Azure Pipeline y el flujo de trabajo de Acciones de GitHub:

Para validar la implementación de imágenes firmadas en AKS o Kubernetes: