Signer des images conteneur avec Notation et Azure Key Vault à l’aide d’un certificat délivré par une autorité de certification
Signer et vérifier des images conteneur avec un certificat émis par une autorité de certification approuvée est une pratique de sécurité utile. Cette mesure de sécurité vous aidera à identifier, autoriser et valider avec discernement l’identité de l’éditeur de l’image conteneur et l’image conteneur elle-même. Les autorités de certification approuvées telles que GlobalSign, DigiCert et d’autres jouent un rôle crucial dans la validation de l’identité d’un utilisateur ou d’une organisation, la gestion de la sécurité des certificats numériques et la révocation immédiate du certificat en cas de risque ou d’utilisation abusive.
Voici quelques composants essentiels qui vous aident à signer et à vérifier des images conteneur avec un certificat émis par une autorité de certification approuvée :
- La Notation est un outil de sécurité de la chaîne logistique open source, développé par la communauté Notary Project et soutenu par Microsoft, qui prend en charge la signature et la vérification d’images conteneur et d’autres artefacts.
- Azure Key Vault (AKV), un service informatique pour la gestion des clés de chiffrement, des secrets et des certificats, vous aide à stocker et gérer en toute sécurité un certificat avec une clé de signature.
- Le plug-in Notation AKV azure-kv, l’extension de Notation, utilise les clés stockées dans Azure Key Vault pour signer et vérifier les signatures numériques des images et artefacts conteneur.
- Azure Container Registry (ACR) vous permet d’attacher ces signatures à l’image signée et vous aide à stocker et à gérer ces images conteneur.
Lorsque vous vérifiez l’image, la signature est utilisée pour valider l’intégrité de l’image et l’identité du signataire. Vous avez donc l’assurance que les images conteneur ne sont pas falsifiées et proviennent d’une source approuvée.
Contenu de cet article :
- Installer l’interface CLI de notation et le plug-in AKV
- Créer ou importer un certificat émis par une autorité de certification dans AKV
- Générer et envoyer (push) une image conteneur avec ACR Task
- Signer une image conteneur avec l'interface CLI de Notation et le plug-in AKV
- Vérifier une signature d’image conteneur avec l’interface CLI Notation
- Horodatage
Prérequis
- Créer ou utiliser un Azure Container Registry pour stocker des images conteneurs et des signatures
- Créer ou utiliser un Azure Key Vault
- Installer et configurer les dernières commandes Azure CLI ou Exécuter dans Azure Cloud Shell
Remarque
Nous vous recommandons de créer un nouveau Azure Key Vault pour le stockage des certificats uniquement.
Installer l’interface CLI de notation et le plug-in AKV
Installez Notation v1.2.0 sur un environnement Linux amd64. Suivez le Guide d’installation de Notation pour télécharger le package pour d’autres environnements.
# 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
Installez le plug-in de notation Azure Key Vault
azure-kv
v1.2.0 sur un environnement Linux amd64.Remarque
L’URL et la somme de contrôle SHA256 du plug-in Notation Azure Key Vault se trouvent dans la page de version du plug-in.
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
Listez les plug-ins disponibles et vérifiez que le plug-in
azure-kv
avec la version1.2.0
est inclus dans la liste.notation plugin ls
Configuration des variables d’environnement
Remarque
Ce guide utilise des variables d’environnement pour des raisons pratiques lors de la configuration d’AKV et d’ACR. Mettez à jour les valeurs de ces variables d’environnement pour vos ressources spécifiques.
Configurez les variables d’environnement pour AKV et les certificats
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"
Configurez les variables d’environnement pour ACR et les images.
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
Se connecter avec Azure CLI
az login
Pour en savoir plus sur Azure CLI et sur la façon de se connecter avec elle, reportez-vous à Se connecter avec Azure CLI.
Créer ou importer un certificat émis par une autorité de certification dans AKV
Configuration requise des certificats
Lors de la création de certificats pour la signature et la vérification, les certificats doivent satisfaire à l’exigence de certificat Notary Project.
Les conditions requises pour les certificats racines et intermédiaires sont les suivantes :
- L’extension
basicConstraints
doit être présente et être marquée comme critique. Le champCA
doit être défini sur la valeurtrue
. - L’extension
keyUsage
doit être présente et être marquée commecritical
. Les positions de bits pourkeyCertSign
DOIVENT être définies.
Les conditions requises pour les certificats émis par une autorité de certification sont les suivantes :
- Propriétés du certificat X.509 :
- L’objet doit contenir le nom commun (
CN
), le pays (C
), l’état ou la province (ST
) et l’organisation (O
). Dans ce tutoriel,$CERT_SUBJECT
est utilisé comme le sujet. - L’indicateur d’utilisation de la clé X.509 doit être uniquement
DigitalSignature
. - Les utilisations améliorées de la clé (EKU) doivent être vides ou
1.3.6.1.5.5.7.3.3
(pour la signature de code).
- L’objet doit contenir le nom commun (
- Propriétés de la clé :
- La propriété
exportable
doit être définie surfalse
. - Sélectionnez un type de clé et une taille pris en charge à partir de la spécification Notary Project.
- La propriété
Important
Pour garantir une intégration réussie à l’intégrité de l’image, le type de contenu du certificat doit être défini sur PEM.
Remarque
Ce guide utilise la version 1.0.1 du plug-in AKV. Les versions antérieures du plug-in présentaient une limitation qui nécessitait un ordre de certificats spécifique dans une chaîne de certificats. La version 1.0.1 du plug-in ne présente pas cette limitation. Il est donc recommandé d’utiliser la version 1.0.1 ou ultérieure.
Créer un certificat émis par une autorité de certification commerciale
Créez une demande de signature de certificat (CSR) en suivant les instructions de Créer une demande de signature de certificat.
Important
Lors de la fusion de la CSR, veillez à fusionner l’ensemble de la chaîne qui a été renvoyée par le fournisseur d’autorité de certification.
Importer le certificat dans AKV
Pour importer le certificat, procédez comme suit :
- Obtenez le fichier de certificat avec l’ensemble de la chaîne de certificats auprès du fournisseur d’autorité de certification.
- Importez le certificat dans Azure Key Vault en suivant les instructions de Importer un certificat.
Remarque
Si le certificat ne contient pas de chaîne de certificats après la création ou l’importation, vous pouvez obtenir les certificats intermédiaires et racines auprès de votre fournisseur d’autorité de certification. Vous pouvez demander à votre fournisseur de vous fournir un fichier PEM qui contient les certificats intermédiaires (le cas échéant) et le certificat racine. Ce fichier peut ensuite être utilisé à l’étape 5 de signer des images conteneur.
Signer une image conteneur avec l'interface CLI de Notation et le plug-in AKV
Quand vous utilisez ACR et AKV, il est essentiel d’octroyer les autorisations appropriées pour garantir un accès sécurisé et contrôlé. Vous pouvez autoriser l’accès à différentes entités, par exemple les principaux d’utilisateur, les principaux de service ou les identités managées, en fonction de vos scénarios spécifiques. Dans ce tutoriel, l’accès est autorisé à un utilisateur Azure connecté.
Autorisation de l’accès à ACR
Les rôles AcrPull
et AcrPush
sont obligatoires pour la création et la signature d’images conteneur dans ACR.
Définir l’abonnement qui contient la ressource ACR
az account set --subscription $ACR_SUB_ID
Attribuer les rôles
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"
Créer et envoyer (push) des images conteneur vers ACR
Authentifiez-vous auprès de votre ACR à l'aide de votre identité Azure individuelle.
az acr login --name $ACR_NAME
Important
Si vous avez installé Docker sur votre système et utilisé az acr login
ou docker login
pour vous authentifier auprès de votre ACR, c'est que vos informations d'identification sont déjà stockées et disponibles dans Notation. Dans ce cas, vous n'avez pas besoin de réexécuter notation login
pour vous authentifier auprès de votre ACR. Pour en savoir plus sur les options d'authentification pour Notation, reportez-vous à Authentifier avec des registres conformes à OCI.
Générez et envoyez (push) une nouvelle image avec ACR Tasks. Utilisez toujours
digest
pour identifier l'image à signer, car les étiquettes sont mutables et peuvent être remplacées.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
Dans ce tutoriel, si l'image a déjà été créée et est stockée dans le registre, l'étiquette sert d'identificateur pour cette image pour plus de commodité.
IMAGE=$REGISTRY/${REPO}@$TAG
Autorisation de l’accès à AKV
Utiliser le contrôle RBAC Azure (recommandé)
Définir l'abonnement qui contient la ressource AKV
az account set --subscription $AKV_SUB_ID
Attribuer les rôles
Si le certificat contient l’intégralité de la chaîne de certificats, le principal doit se voir attribuer les rôles suivants :
Key Vault Secrets User
pour la lecture des secretsKey Vault Certificates User
pour la lecture des certificatsKey Vault Crypto User
pour la signature des opérations
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 le certificat ne contient pas la chaîne, le principal doit se voir attribuer les rôles suivants :
Key Vault Certificates User
pour la lecture des certificatsKey Vault Crypto User
pour la signature des opérations
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"
Pour en savoir plus sur l’accès à Key Vault avec le contrôle RBAC Azure, consultez Utiliser un contrôle d’accès en fonction du rôle (RBAC) Azure pour gérer l’accès.
Utiliser une stratégie d’accès (hérité)
Pour définir l'abonnement qui contient les ressources AKV, exécutez la commande suivante :
az account set --subscription $AKV_SUB_ID
Si le certificat contient l’intégralité de la chaîne de certificats, le principal doit recevoir l’autorisation de clé Sign
, l’autorisation secrète Get
et les autorisations de certificat Get
. Pour accorder ces autorisations au principal, procédez comme suit :
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 le certificat ne contient pas la chaîne, le principal doit recevoir l’autorisation de clé Sign
et les autorisations de certificat Get
. Pour accorder ces autorisations au principal, procédez comme suit :
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
Pour en savoir plus sur l'attribution d'une stratégie à un principal, reportez-vous à Attribuer une stratégie d'accès.
Signer des images conteneur à l’aide du certificat dans AKV
Obtenez l’ID de clé d’un certificat. Un certificat dans AKV peut avoir plusieurs versions. La commande suivante obtient l'ID de clé pour la dernière version certificat
$CERT_NAME
.KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
Signez l'image conteneur avec le format de signature COSE à l'aide de l’ID de clé.
Si le certificat contient l’intégralité de la chaîne de certificats, exécutez la commande suivante :
notation sign --signature-format cose $IMAGE --id $KEY_ID --plugin azure-kv
Si le certificat ne contient pas la chaîne, utilisez le paramètre
--plugin-config ca_certs=<ca_bundle_file>
pour transmettre les certificats d’autorité de certification dans un fichier PEM au plug-in AKV, exécutez la commande suivante :notation sign --signature-format cose $IMAGE --id $KEY_ID --plugin azure-kv --plugin-config ca_certs=<ca_bundle_file>
Pour s'authentifier avec AKV, par défaut, les types d'informations d'identification suivants, s'ils sont activés, seront essayés dans l'ordre :
- Titre Environnement
- Identifiant d'identité de charge de travail
- Identifiant d'identité managé
- Informations d’identification d’Azure CLI
Si vous souhaitez spécifier un type d’informations d’identification, utilisez une configuration de plug-in supplémentaire appelée
credential_type
. Par exemple, vous pouvez définir explicitementcredential_type
surazurecli
pour utiliser les informations d’identification Azure CLI, comme illustré ci-dessous :notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config credential_type=azurecli $IMAGE
Consultez le tableau ci-dessous pour connaître les valeurs de
credential_type
pour différents types d’informations d’identification.Type d'informations d'identification Valeur de credential_type
Informations d’identification de l’environnement environment
Informations d’identification de l’identité de la charge workloadid
Informations d’identification d’identité managée managedid
Informations d’identification d’Azure CLI azurecli
Affichez le graphique des images signées et des signatures associées.
notation ls $IMAGE
Dans l’exemple de sortie suivant, une signature de type
application/vnd.cncf.notary.signature
identifiée par le code de hachagesha256:d7258166ca820f5ab7190247663464f2dcb149df4d1b6c4943dcaac59157de8e
est associée à$IMAGE
.myregistry.azurecr.io/net-monitor@sha256:17cc5dd7dfb8739e19e33e43680e43071f07497ed716814f3ac80bd4aac1b58f └── application/vnd.cncf.notary.signature └── sha256:d7258166ca820f5ab7190247663464f2dcb149df4d1b6c4943dcaac59157de8e
Vérifier une image conteneur avec l'interface CLI de Notation
Ajoutez le certificat racine à un magasin de confiance nommé pour la vérification de la signature. Si vous n’avez pas le certificat racine, vous pouvez l’obtenir auprès de votre autorité de certification. L’exemple suivant ajoute le certificat racine
$ROOT_CERT
au magasin de confiance$STORE_NAME
.STORE_TYPE="ca" STORE_NAME="wabbit-networks.io" notation cert add --type $STORE_TYPE --store $STORE_NAME $ROOT_CERT
Répertoriez le certificat racine pour confirmer que le
$ROOT_CERT
est ajouté avec succès.notation cert ls
Configurez la stratégie de confiance avant la vérification.
Les stratégies d'approbation permettent aux utilisateurs de spécifier des stratégies de vérification affinées. Utilisez la commande suivante pour configurer la stratégie de confiance.
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
Le fichier
trustpolicy.json
ci-dessus définit une stratégie de confiance nomméewabbit-networks-images
. Cette stratégie de confiance s’applique à tous les artefacts stockés dans les référentiels$REGISTRY/$REPO
. Le magasin de confiance nommé$STORE_NAME
de type$STORE_TYPE
contient les certificats racines. Il suppose également que l'utilisateur approuve une identité spécifique avec l'objet X.509$CERT_SUBJECT
. Pour plus d'informations, reportez-vous à Magasin de confiance et spécification de stratégie de confiance.Utilisez
notation policy
pour importer la configuration de la stratégie de confiance à partir detrustpolicy.json
.notation policy import ./trustpolicy.json
Affichez la configuration de la stratégie de confiance pour confirmer que son importation est réussie.
notation policy show
Utilisez
notation verify
pour vérifier l’intégrité de l’image :notation verify $IMAGE
En cas de vérification réussie de l’image à l’aide de la stratégie de confiance, la synthèse sha256 de l’image vérifiée est retournée dans un message de sortie réussi. Voici un exemple de sortie :
Successfully verified signature for myregistry.azurecr.io/net-monitor@sha256:17cc5dd7dfb8739e19e33e43680e43071f07497ed716814f3ac80bd4aac1b58f
Horodatage
Depuis la version v1.2.0, Notation prend en charge l’horodatage conforme RFC 3161. Cette amélioration étend la confiance des signatures créées au cours de la période de validité du certificat en faisant confiance à une autorité d’horodatage (TSA, Timestamping Authority), ce qui permet à la vérification de la signature de réussir même après l’expiration des certificats. En tant que signataire d’image, vous devez veiller à signer les images conteneur avec des horodateurs générés par une TSA de confiance. En tant que vérificateur d’image, pour vérifier les horodateurs, vous devez veiller à faire confiance à la fois au signataire de l’image et à la TSA associée, et à établir la confiance par le biais de magasins de confiance et de stratégies d’approbation. L’horodatage réduit les coûts en éliminant la nécessité de réinscrire régulièrement des images en raison de l’expiration du certificat, ce qui est particulièrement critique lors de l’utilisation de certificats de courte durée. Pour obtenir des instructions détaillées sur la façon de signer et de vérifier à l’aide de l’horodatage, reportez-vous au guide sur l’horodatage du projet notarié.
Forum aux questions
Que dois-je faire si le certificat est expiré ?
Si votre certificat a expiré, vous devez obtenir un nouveau certificat auprès d’un fournisseur d’autorité de certification de confiance ainsi qu’une nouvelle clé privée. Vous ne pouvez pas utiliser un certificat expiré pour signer des images conteneur. Les images signées avant l’expiration du certificat peuvent toujours être validées si elles ont été signées avec un horodatage. Sans horodatage, la vérification de la signature échoue et vous devrez signer à nouveau ces images avec le nouveau certificat pour que la vérification réussisse.
Que dois-je faire si le certificat est révoqué ?
Si votre certificat est révoqué, il invalide la signature. Cela peut se produire pour plusieurs raisons, notamment la compromission de la clé privée ou des modifications apportées à l’affiliation du titulaire du certificat. Pour résoudre ce problème, vous devez d’abord vous assurer que votre code source et votre environnement de génération sont à jour et sécurisés. Ensuite, générez les images conteneur à partir du code source, obtenez un nouveau certificat auprès d’un fournisseur d’autorité de certification de confiance avec une nouvelle clé privée, puis signez les nouvelles images conteneur avec le nouveau certificat en suivant ce guide.
Étapes suivantes
La notation fournit également des solutions CI/CD sur Azure Pipeline et le workflow GitHub Actions :
- Signer et vérifier une image conteneur avec notation dans Azure Pipeline
- Signer et vérifier une image conteneur avec notation dans un workflow GitHub Actions
Pour valider le déploiement d’images signées dans AKS ou Kubernetes :