使用自我簽署憑證來透過 Notation 和 Azure Key Vault 簽署容器映像
簽署容器映像是確保其真實性和完整性的程序。 這可藉由將數位簽章新增至容器映像,以在部署期間進行驗證。 簽章有助於驗證映像是否來自受信任的發行者,且尚未修改。 標記法是由 Notary Project 社群開發並由 Microsoft 支援的開放原始碼供應鏈工具,可支援對容器映像和其他成品進行簽署和驗證。 Azure Key Vault (AKV) 可用來使用簽署金鑰儲存憑證,[標記法] 可利用該簽署金鑰與標記法 AKV 外掛程式 (azure-kv) 來對容器映像和其他成品進行簽署和驗證。 Azure Container Registry (ACR) 可讓您將簽章附加至容器映像和其他成品,以及檢視這些簽章。
在本教學課程中:
- 安裝標記法 CLI 和 AKV 外掛程式
- 在 AKV 中建立自我簽署的憑證
- 使用 ACR 工作建置和推送容器映像
- 使用標記法 CLI 和 AKV 外掛程式簽署容器映像
- 使用標記法 CLI 根據簽章驗證容器映像
- 時間戳記
必要條件
- 建立或使用 Azure Container Registry 來儲存容器映像和簽章
- 建立或使用 Azure Key Vault 來管理憑證
- 安裝及設定最新的 Azure CLI,或在 Azure Cloud Shell 中執行命令
安裝標記法 CLI 和 AKV 外掛程式
在 Linux amd64 環境上安裝 Notation v1.2.0。 遵循 Notation 安裝指南以下載其他環境的套件。
# 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
在 Linux amd64 環境上安裝 Notation Azure Key Vault 外掛程式
azure-kv
v1.2.0。注意
Notation Azure Key Vault 外掛程式的 URL 和 SHA256 總和檢查碼可以在此外掛程式的發行頁面上找到。
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
列出可用的外掛程式,並確認版本
1.2.0
的azure-kv
外掛程式包含在清單中。notation plugin ls
設定環境變數
注意
若要在教學課程中輕鬆執行命令,請提供 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.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
使用 Azure CLI 登入
az login
若要深入了解 Azure CLI 以及如何將其用來登入,請參閱使用 Azure CLI 登入。
對 ACR 和 AKV 的安全存取權限
使用 ACR 和 AKV 時,請務必授與適當的權限以確保存取既安全且受控制。 您可以根據您的特定案例授權不同實體的存取權,例如使用者主體、服務主體或受控識別。 在本教學課程中,存取權限會指派給登入的 Azure 使用者。
授與 ACR 的存取權
在 ACR 中簽署容器映像需要 AcrPull
和 AcrPush
角色。
設定包含 ACR 資源的訂用帳戶
az account set --subscription $ACR_SUB_ID
指派角色
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"
將存取權授權給 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
重要
此範例說明建立憑證和簽署容器映像所需的最低權限。 視您的需求而定,您可能需要授與其他權限。
在 AKV 中建立自我簽署憑證 (Azure CLI)
下列步驟說明如何建立自我簽署憑證以供測試之用。
建立憑證原則檔案。
一旦憑證原則檔案執行如下,其會建立與 AKV 中 Notary 專案憑證需求相容的有效簽署憑證。
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
使用標記法 CLI 和 AKV 外掛程式簽署容器映像
使用您的個別 Azure 身分識別來向您的 ACR 進行驗證。
az acr login --name $ACR_NAME
重要
如果您的系統上已安裝 Docker,並使用 az acr login
或 docker login
向您的 ACR 進行驗證,則您的認證已儲存並可供 Notation 使用。 在此情況下,您不需要再次執行 notation login
,即可向 ACR 進行驗證。 若要深入了解 Notation 的驗證選項,請參閱使用符合 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
取得簽署金鑰的金鑰識別碼。 AKV 中的憑證可以有多個版本,下列命令會取得最新版本的金鑰識別碼。
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
檢視已簽署映像和相關聯簽章的圖表。
notation ls $IMAGE
使用標記法 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_TYPE
類型的具名信任存放區$STORE_NAME
。 其也假設使用者信任具有 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 摘要。
時間戳記
由於 Notation v1.2.0 版本,Notation 支援符合 RFC 3161 規範的時間戳記。 這項增強功能可藉由信任時間戳記授權單位 (Timestamping Authority, TSA) 來延伸憑證有效性期間內所建立之簽章的信任,即使在憑證到期之後,也能成功驗證簽章。 身為映像簽署者,請確定您有使用受信任的 TSA 所產生的時間戳記來簽署容器映像。 身為映像驗證者,若要驗證時間戳記,請確定您信任映像簽署者和相關聯的 TSA,並透過信任存放區和信任原則來建立信任。 時間戳記可減少成本,不需要定期因為憑證到期而重新簽署映像,這在使用短期憑證時特別重要。 如需有關如何使用時間戳記簽署和驗證的詳細指示,請參閱 Notary Project 時間戳記指南。
下一步
標記法也提供了 Azure Pipeline 和 GitHub Actions 工作流程上的 CI/CD 解決方案:
若要在 AKS 或 Kubernetes 中驗證已簽署的映像部署: