Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
本文是确保容器映像和 OCI 工件的完整性和真实性的系列文章的一部分。 对于完整情况,请从 概述开始,其中解释了签名为何重要,并提供各种方案。
为容器映像签名是一个确保其真实性和完整性的过程。 这是通过将数字签名添加到容器映像来实现的,该签名可在部署期间进行验证。 签名有助于验证映像是否来自受信任的发布者,并且尚未修改。
Notation 是由 Notary Project 社区开发并由 Microsoft 提供技术支持的一个开源供应链安全工具,它支持对容器映像及其他项目进行签名和验证。 Azure Key Vault (AKV) 用于存储证书,其签名密钥可供支持 Notation AKV 插件 (azure-kv) 的 Notation 用来对容器映像及其他项目进行签名和验证。 Azure 容器注册表 (ACR) 允许将签名附加到容器映像和其他项目,以及查看这些签名。 如果想要在 CI/CD 管道中对容器映像 notation
进行签名,请遵循 Azure Pipeline 或 GitHub Actions 的指南进行操作。
本教程的内容:
- 安装 Notation CLI 和 AKV 插件
- 在 AKV 中创建自签名证书
- 使用 ACR 任务生成并推送容器映像
- 使用 Notation CLI 和 AKV 插件为容器映像签名
- 使用 Notation CLI 根据签名验证容器映像
- Timestamping
Prerequisites
- 创建或使用 Azure 容器注册表来存储容器映像和签名
- 创建或使用 Azure Key Vault 来管理证书
- 安装并配置最新的 Azure CLI。
安装 Notation CLI 和 AKV 插件
在 Linux amd64 环境中安装表示法 v1.3.2。 按照 Notation 安装指南下载适用于其他环境的包。
# 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 binary to the desired bin directory in your $PATH, for example cp ./notation /usr/local/bin
在 Linux amd64 环境中安装 Notation Azure Key Vault 插件
azure-kv
v1.2.1。Note
可以在插件的发布页上找到 Notation Azure Key Vault 插件的 URL 和 SHA256 校验值。
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
列出可用的插件,并确认版本为
azure-kv
的1.2.1
插件是否已包含在列表中。notation plugin ls
配置环境变量
Note
为便于执行教程中的命令,请提供 Azure 资源的值来匹配现有的 ACR 和 AKV 资源。
配置 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
配置 ACR 和映像资源名称。
ACR_SUB_ID=myAcrSubscriptionId ACR_RG=myAcrResourceGroup # Name of the existing registry example: myregistry.azurecr.cn ACR_NAME=myregistry # Existing full domain of the ACR REGISTRY=$ACR_NAME.azurecr.cn # 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
使用 Azure CLI 登录
az cloud set -n AzureChinaCloud
az login
# az cloud set -n AzureCloud //means return to Public Azure.
若要详细了解 Azure CLI 及其登录方式,请参阅使用 Azure CLI 登录。
对 ACR 和 AKV 的安全访问权限
使用 ACR 和 AKV 时,必须授予适当的权限以确保安全性和受控访问。 可以根据特定方案为不同的实体(例如用户主体、服务主体或托管标识)授予访问权限。 在本教程中,访问权限授予给已登录的 Azure 用户。
授予对 ACR 的访问权限
对于启用了 Microsoft Entra 属性访问控制 (ABAC) 的注册表,在 ACR 中生成和签署容器映像需要 Container Registry Repository Reader
和 Container Registry Repository Writer
角色。
对于未启用 ABAC 的注册表,需要 AcrPull
和 AcrPush
角色。
有关 Microsoft Entra ABAC 的详细信息,请参阅 Microsoft Entra 存储库权限。
设置包含 ACR 资源的订阅
az account set --subscription $ACR_SUB_ID
分配角色。 在角色分配中使用的正确角色取决于注册表是否已启用 ABAC。
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"
授予对 AKV 的访问权限
在本部分中,我们将探讨用于授与 AKV 访问权限的两个选项。
使用 Azure RBAC(建议)
使用自签名证书进行签名需要以下角色:
-
Key Vault Certificates Officer
,用于创建和读取证书 -
Key Vault Certificates User
,用于读取现有证书 -
Key Vault Crypto User
,用于签署操作
若要了解有关使用 Azure RBAC 进行 Key Vault 访问的详细信息,请参阅使用 Azure RBAC 管理访问权限。
设置包含 AKV 资源的订阅
az account set --subscription $AKV_SUB_ID
分配角色
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"
在 AKV 中分配访问策略(旧版)
标识需要以下权限:
-
Create
权限,用于创建证书 -
Get
用于读取现有证书的权限 - 拥有
Sign
权限,可执行签名操作
若要详细了解如何将策略分配给主体,请参阅分配访问策略。
设置包含 AKV 资源的订阅:
az account set --subscription $AKV_SUB_ID
在 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
Important
此示例显示了创建证书和对容器映像进行签名所需的最低权限。 根据要求,可能需要授予其他权限。
在 AKV (Azure CLI) 中创建自签名证书
以下步骤演示如何为测试创建自签名证书。
创建证书策略文件。
如下所示,执行证书策略文件后,它会创建与 AKV 中的 Notary Project 证书要求兼容的有效证书。
ekus
的值用于代码签名,但表示法不需要使用它来为工件签名。 主题稍后用作用户在验证期间信任的信任标识。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
创建证书。
az keyvault certificate create -n $CERT_NAME --vault-name $AKV_NAME -p @my_policy.json
使用 Notation CLI 和 AKV 插件为容器映像签名
使用个人 Azure 标识向 ACR 进行身份验证。
az acr login --name $ACR_NAME
Important
如果已在系统上安装 Docker 并使用 az acr login
或 docker login
向 ACR 进行身份验证,则凭据已存储并可用于表示法。 在这种情况下,无需再次运行 notation login
即可向 ACR 进行身份验证。 若要详细了解表示法的身份验证选项,请参阅使用符合 OCI 的注册表进行身份验证。
使用 ACR 任务构建并推送新映像。 始终使用摘要值来标识用于签名的映像,因为标记是可变的,可以覆盖。
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
在本教程中,如果映像已生成并存储在注册表中,为方便起见,标记将用作该映像的标识符。
IMAGE=$REGISTRY/${REPO}:$TAG
获取签名密钥的密钥 ID。 AKV 中的证书可以有多个版本,以下命令获取最新版本的密钥 ID。
KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
使用签名密钥,以 COSE 签名格式为容器映像签名。 若要使用自签名证书进行签名,需要设置插件配置值
self_signed=true
。notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config self_signed=true $IMAGE
若要使用 AKV 进行身份验证,默认将按顺序尝试以下凭据类型(如果已启用):
如果你要指定凭据类型,请使用名为
credential_type
的附加插件配置。 例如,可以将credential_type
显式设置为azurecli
以使用 Azure CLI 凭据,如下所示:notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config self_signed=true --plugin-config credential_type=azurecli $IMAGE
请参阅下表了解各种凭据类型的
credential_type
值。凭据类型 credential_type
的值环境凭据 environment
工作负载标识凭据 workloadid
托管标识凭据 managedid
Azure CLI 凭据 azurecli
Note
自 v1.2.0 起
notation
,默认情况下使用notation
OCI 引用者标记架构 将签名存储在 ACR 中。 如果需要,还可以使用标志启用--force-referrers-tag false
。 除 CMK 加密注册表外,大多数 ACR 功能都支持 OCI 引用器 API。查看已签名映像和相关签名的图。
notation ls $IMAGE
使用 Notation CLI 为容器映像签名
若要验证容器映像,请将对叶证书进行签名的根证书添加到信任存储区,并创建用于验证的信任策略。 对于本教程中使用的自签名证书,根证书是自签名证书本身。
下载公共证书。
az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
将下载的公共证书添加到命名信任存储,以便进行签名验证。
STORE_TYPE="ca" STORE_NAME="wabbit-networks.io" notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
列出要确认的证书。
notation cert ls
在验证之前先配置信任策略。
信任策略允许用户指定经过微调的验证策略。 以下示例配置名为
wabbit-networks-images
的信任策略,该策略适用于$REGISTRY/$REPO
中的所有项目,并使用$STORE_NAME
类型的具名信任存储$STORE_TYPE
。 它还假设用户信任特定身份,其 X.509 主题为$CERT_SUBJECT
。 有关详细信息,请参阅信任存储和信任策略规范。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
使用
notation policy
从我们之前创建的 JSON 文件导入信任策略配置。notation policy import ./trustpolicy.json notation policy show
使用
notation verify
验证容器映像自生成时以来未发生更改。notation verify $IMAGE
使用信任策略成功验证映像后,将在成功输出消息中返回已验证映像的 sha256 摘要。
Timestamping
自从 Notation v1.2.0,Notation 支持符合 RFC 3161 的时间戳功能。 此增强功能通过信任时间戳颁发机构 (TSA) 来延长对证书有效期内创建的签名的信任,即使在证书过期后也能成功进行签名验证。 作为映像签名者,应确保使用受信任的 TSA 生成的时间戳对容器映像进行签名。 作为映像验证者,若要验证时间戳,应确保信任映像签名者和关联的 TSA,并通过信任存储和信任策略来建立信任。 通过避免因证书过期需要定期重新签名映像,使用时间戳会降低成本,这在使用短期证书时特别关键。 有关如何使用时间戳进行签名和验证的详细说明,请参阅公证项目时间戳指南。
后续步骤
表示法在 Azure Pipelines 和 GitHub Actions 上提供 CI/CD 解决方案:
若要在 ADO 管道中对容器映像进行签名和验证,请参阅 在 Azure Pipeline 中使用表示法对容器映像进行签名和验证。
若要使用 GitHub Actions 对容器映像进行签名,请参阅 使用 GitHub Actions 使用表示法对容器映像进行签名。
若要使用 GitHub Actions 验证容器映像,请参阅 使用 GitHub Actions 通过表示法验证容器映像。
为了确保仅在 Azure Kubernetes 服务(AKS)上部署受信任的容器映像:
- 按照在部署到 Azure Kubernetes 服务 (AKS) 群集前使用映像完整性验证已签名映像(预览版)指南使用 Azure Policy 映像完整性(预览版)。
- 使用 Ratify 和 Azure Policy,按照指南 保护 AKS 工作负载:使用 Ratify 和 Azure Policy 验证容器镜像签名。