Firma de imágenes de contenedor con notación y Azure Key Vault mediante un certificado autofirmado
Firmar imágenes de contenedor es un proceso que garantiza su autenticidad e integridad. Esto se logra agregando una firma digital a la imagen de contenedor, que se puede validar durante la implementación. La firma ayuda a comprobar que la imagen procede de un publicador de confianza y no se ha modificado. 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) se usa para almacenar certificados con claves de firma que se puede usar mediante la notación con el complemento AKV de notación (azure-kv) para firmar y comprobar imágenes de contenedor y otros artefactos. El Azure Container Registry (ACR) permite adjuntar firmas a imágenes de contenedor y otros artefactos, así como ver esas firmas.
En este tutorial:
- Instalación de la CLI de notación y el complemento de AKV
- Crear un certificado autofirmado en AKV
- Compile e inserte una imagen de contenedor con ACR Tasks
- Firmar una imagen de contenedor con la CLI de notación y el complemento de AKV
- Validación de una imagen de contenedor en relación con la firma con la CLI de notación
- Marca de tiempo
Requisitos previos
- Crear o usar un Azure Container Registry para almacenar imágenes y firmas de contenedor
- Creación o uso de una instancia de Azure Key Vault para administrar certificados
- Instalación y configuración de la CLI de Azure más reciente o Ejecución de comandos en Azure Cloud Shell
Instalación de la CLI de notación y el complemento de AKV
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 binary to the desired bin directory in your $PATH, for example cp ./notation /usr/local/bin
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
Enumere los complementos disponibles y confirme que el complemento
azure-kv
con la versión1.2.0
está incluido en la lista.notation plugin ls
Configuración de las variables de entorno
Nota
Para facilitar la ejecución de comandos en el tutorial, proporcione valores para que los recursos de Azure coincidan con los recursos de ACR y AKV existentes.
Configure los nombres de recursos de AKV.
AKV_SUB_ID=myAkvSubscriptionId AKV_RG=myAkvResourceGroup # Name of the existing AKV used to store the signing keys AKV_NAME=myakv # Name of the certificate created in AKV CERT_NAME=wabbit-networks-io CERT_SUBJECT="CN=wabbit-networks.io,O=Notation,L=Seattle,ST=WA,C=US" CERT_PATH=./${CERT_NAME}.pem
Configure los nombres de recursos de la imagen y de ACR.
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 IMAGE=$REGISTRY/${REPO}:$TAG # 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.
Protección de los permisos de acceso a ACR y 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.
Autorización del acceso a ACR
Los roles AcrPull
y AcrPush
son necesarios para firmar imágenes de contenedor en ACR.
Configurar la suscripción que contiene el recurso ACR
az account set --subscription $ACR_SUB_ID
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"
Autorizar el acceso a AKV
En esta sección, exploraremos dos opciones para autorizar el acceso a AKV.
Usar RBAC de Azure (recomendado)
Los siguientes roles son necesarios para firmar mediante certificados autofirmados:
Key Vault Certificates Officer
para crear y leer certificadosKey Vault Certificates User
para leer certificados existentesKey Vault Crypto User
para las operaciones de firma
Para más información sobre el acceso de Key Vault con RBAC de Azure, consulte Uso de RBAC de Azure para administrar el acceso.
Configurar la suscripción que contiene el recurso AKV
az account set --subscription $AKV_SUB_ID
Asignar los roles
USER_ID=$(az ad signed-in-user show --query id -o tsv) az role assignment create --role "Key Vault Certificates Officer" --role "Key Vault Crypto User" --assignee $USER_ID --scope "/subscriptions/$AKV_SUB_ID/resourceGroups/$AKV_RG/providers/Microsoft.KeyVault/vaults/$AKV_NAME"
Asignar directiva de acceso en AKV (heredado)
Los permisos siguientes son necesarios para una identidad:
Create
permisos para crear un certificadoGet
permisos para leer certificados existentesSign
permisos para las operaciones de firma
Para obtener más información sobre la asignación de directivas a una entidad de seguridad, consulte Asignación de directiva de acceso.
Establezca la suscripción que contiene el recurso de AKV:
az account set --subscription $AKV_SUB_ID
Establezca la directiva de acceso en AKV:
USER_ID=$(az ad signed-in-user show --query id -o tsv) az keyvault set-policy -n $AKV_NAME --certificate-permissions create get --key-permissions sign --object-id $USER_ID
Importante
En este ejemplo se muestran los permisos mínimos necesarios para crear un certificado y firmar una imagen de contenedor. En función de sus requisitos, es posible que tenga que conceder permisos adicionales.
Crear un certificado autofirmado en AKV (CLI de Azure)
Los siguientes pasos le mostrarán cómo crear un certificado autofirmado para fines de pruebas.
Cree un archivo de directiva de certificados.
Una vez que el archivo de directiva de certificado se ejecuta como se indica a continuación, crea un certificado válido compatible con el requisito de certificado de Notary Project en AKV. El valor de
ekus
es para la firma de código, pero no es necesario para que la notación firme los artefactos. El asunto se usará posteriormente como identidad de confianza en la que confía el usuario durante la verificación.cat <<EOF > ./my_policy.json { "issuerParameters": { "certificateTransparency": null, "name": "Self" }, "keyProperties": { "exportable": false, "keySize": 2048, "keyType": "RSA", "reuseKey": true }, "secretProperties": { "contentType": "application/x-pem-file" }, "x509CertificateProperties": { "ekus": [ "1.3.6.1.5.5.7.3.3" ], "keyUsage": [ "digitalSignature" ], "subject": "$CERT_SUBJECT", "validityInMonths": 12 } } EOF
Crea el certificado.
az keyvault certificate create -n $CERT_NAME --vault-name $AKV_NAME -p @my_policy.json
Firmar una imagen de contenedor con la CLI de notación y el complemento de AKV
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.
Compile e inserte una nueva imagen con ACR Tasks. Use siempre el valor de síntesis del mensaje para identificar la imagen que se quiere 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
Obtenga el identificador de clave de la clave de firma. Un certificado de AKV puede tener varias versiones; el siguiente comando obtiene el identificador de clave de la versión más reciente.
KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
Firme la imagen del contenedor con el formato de firma COSE mediante el id. de clave de firma. Para firmar con un certificado autofirmado, debe configurar el valor e configuración del complemento
self_signed=true
.notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config self_signed=true $IMAGE
Para autenticarse con AKV, de forma predeterminada, se intentarán los siguientes tipos de credenciales si está habilitado en orden:
- Credenciales de entorno
- Credencial de identidad de carga de trabajo
- Credencial de identidad administrada
- Credencial de la CLI de Azure
Si desea especificar un tipo de credencial, use una configuración de complemento adicional llamada
credential_type
. Por ejemplo, puede establecer explícitamentecredential_type
enazurecli
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 self_signed=true --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
Vea el gráfico de imágenes firmadas y las firmas asociadas.
notation ls $IMAGE
Comprobación de una imagen de contenedor con la CLI de notación
Para comprobar la imagen de contenedor, agregue el certificado raíz que firma el certificado hoja al almacén de confianza y cree directivas de confianza para la comprobación. Para el certificado autofirmado que se usa en este tutorial, el certificado raíz es el propio certificado autofirmado.
Descargue el certificado público.
az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
Agregue el certificado público descargado al almacén de confianza con nombre para la comprobación de firmas.
STORE_TYPE="ca" STORE_NAME="wabbit-networks.io" notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
Enumere el certificado que debe confirmarse
notation cert ls
Configure la directiva de confianza antes de la comprobación.
Las directivas de confianza permiten a los usuarios especificar directivas de verificación ajustadas. En el ejemplo siguiente se configura una directiva de confianza denominada
wabbit-networks-images
, que se aplica a todos los artefactos de$REGISTRY/$REPO
y usa el almacén de confianza de$STORE_NAME
de tipo$STORE_TYPE
. 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.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
Use
notation policy
para importar la configuración de la directiva de confianza desde un archivo JSON que creamos previamente.notation policy import ./trustpolicy.json notation policy show
Use
notation verify
para comprobar que la imagen de contenedor no se ha modificado desde el tiempo de compilación.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.
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.
Pasos siguientes
La notación también proporciona soluciones de CI/CD en Azure Pipeline y el flujo de trabajo de Acciones de GitHub:
- Firmar y comprobar una imagen de contenedor con notación en Azure Pipeline
- Firmar y comprobar una imagen de contenedor con notación en el flujo de trabajo de Acciones de GitHub
Para validar la implementación de imágenes firmadas en AKS o Kubernetes: