內容信任的委託
Docker 內容信任(DCT)中的委託允許您控制誰可以和誰不可以對映象標籤進行簽名。一個委託將擁有一對私有和公共委託金鑰。一個委託可以包含多對金鑰和貢獻者,以便 a) 允許多個使用者成為委託的一部分,以及 b) 支援金鑰輪換。
Docker 內容信任中最重要的委託是 targets/releases
。這被視為可信映象標籤的規範來源,如果沒有貢獻者的金鑰在此委託下,他們將無法對標籤進行簽名。
幸運的是,在使用 $ docker trust
命令時,我們會自動初始化一個倉庫,管理倉庫金鑰,並透過 docker trust signer add
將協作者的金鑰新增到 targets/releases
委託中。
配置 Docker 客戶端
預設情況下,$ docker trust
命令期望 notary 伺服器 URL 與映象標籤中指定的 registry URL 相同(遵循與 $ docker push
類似的邏輯)。當使用 Docker Hub 或 DTR 時,notary 伺服器 URL 與 registry URL 相同。然而,對於自託管環境或第三方 registry,您需要為 notary 伺服器指定一個備用 URL。這可以透過以下方式完成:
$ export DOCKER_CONTENT_TRUST_SERVER=https://<URL>:<PORT>
如果您在自託管環境中不匯出此變數,您可能會看到如下錯誤:
$ docker trust signer add --key cert.pem jeff registry.example.com/admin/demo
Adding signer "jeff" to registry.example.com/admin/demo...
<...>
Error: trust data missing for remote repository registry.example.com/admin/demo or remote repository not found: timestamp key trust data unavailable. Has a notary repository been initialized?
$ docker trust inspect registry.example.com/admin/demo --pretty
WARN[0000] Error while downloading remote metadata, using cached timestamp - this might not be the latest version available remotely
<...>
如果您為您的 notary 伺服器啟用了身份驗證,或者正在使用 DTR,您需要在將資料推送到 notary 伺服器之前登入。
$ docker login registry.example.com/user/repo
Username: admin
Password:
Login Succeeded
$ docker trust signer add --key cert.pem jeff registry.example.com/user/repo
Adding signer "jeff" to registry.example.com/user/repo...
Initializing signed repository for registry.example.com/user/repo...
Successfully initialized "registry.example.com/user/repo"
Successfully added signer: jeff to registry.example.com/user/repo
如果您不登入,您會看到:
$ docker trust signer add --key cert.pem jeff registry.example.com/user/repo
Adding signer "jeff" to registry.example.com/user/repo...
Initializing signed repository for registry.example.com/user/repo...
you are not authorized to perform this operation: server returned 401.
Failed to add signer to: registry.example.com/user/repo
配置 Notary 客戶端
DCT 的一些更高階的功能需要 Notary CLI。要安裝和配置 Notary CLI:
下載客戶端並確保它在您的路徑中可用。
在
~/.notary/config.json
建立一個包含以下內容的配置檔案:
{
"trust_dir" : "~/.docker/trust",
"remote_server": {
"url": "https://registry.example.com",
"root_ca": "../.docker/ca.pem"
}
}
新建立的配置檔案包含有關您本地 Docker 信任資料的位置和 notary 伺服器 URL 的資訊。
有關如何在 Docker 內容信任用例之外使用 notary 的更詳細資訊,請參閱此處的 Notary CLI 文件。
建立委託金鑰
新增第一個貢獻者的先決條件是一對委託金鑰。這些金鑰可以本地使用 $ docker trust
生成,也可以由證書頒發機構生成。
使用 Docker Trust 生成金鑰
Docker trust 有一個內建的委託金鑰對生成器,$ docker trust generate <name>
。執行此命令將自動將委託私鑰載入到本地 Docker 信任儲存中。
$ docker trust key generate jeff
Generating key for jeff...
Enter passphrase for new jeff key with ID 9deed25:
Repeat passphrase for new jeff key with ID 9deed25:
Successfully generated and loaded private key. Corresponding public key available: /home/ubuntu/Documents/mytrustdir/jeff.pub
手動生成金鑰
如果您需要手動生成私鑰(RSA 或 ECDSA)和包含公鑰的 X.509 證書,您可以使用本地工具如 openssl 或 cfssl,以及本地或公司範圍的證書頒發機構。
以下是如何生成一個 2048 位 RSA 金鑰的示例(所有 RSA 金鑰必須至少為 2048 位):
$ openssl genrsa -out delegation.key 2048
Generating RSA private key, 2048 bit long modulus
....................................................+++
............+++
e is 65537 (0x10001)
他們應該將 delegation.key
保持私密,因為它用於對標籤進行簽名。
然後他們需要生成一個包含公鑰的 x509 證書,這就是您需要從他們那裡得到的東西。以下是生成 CSR(證書籤名請求)的命令:
$ openssl req -new -sha256 -key delegation.key -out delegation.csr
然後他們可以將其傳送給您信任的任何 CA 來簽署證書,或者他們可以自簽名證書(在此示例中,建立一個有效期為 1 年的證書):
$ openssl x509 -req -sha256 -days 365 -in delegation.csr -signkey delegation.key -out delegation.crt
然後他們需要給您 delegation.crt
,無論是自簽名的還是由 CA 簽名的。
最後,您需要將私鑰新增到您的本地 Docker 信任儲存中。
$ docker trust key load delegation.key --name jeff
Loading key from "delegation.key"...
Enter passphrase for new jeff key with ID 8ae710e:
Repeat passphrase for new jeff key with ID 8ae710e:
Successfully imported key from delegation.key
檢視本地委託金鑰
要列出已匯入到本地 Docker 信任儲存中的金鑰,我們可以使用 Notary CLI。
$ notary key list
ROLE GUN KEY ID LOCATION
---- --- ------ --------
root f6c6a4b00fefd8751f86194c7d87a3bede444540eb3378c4a11ce10852ab1f96 /home/ubuntu/.docker/trust/private
jeff 9deed251daa1aa6f9d5f9b752847647cf8d705da0763aa5467650d0987ed5306 /home/ubuntu/.docker/trust/private
管理 Notary 伺服器中的委託
當使用 $ docker trust
將第一個委託新增到 Notary 伺服器時,我們會自動為該倉庫初始化信任資料。這包括建立 notary 目標和快照金鑰,並將快照金鑰輪換為由 notary 伺服器管理。有關這些金鑰的更多資訊可以在這裡找到。
在初始化倉庫時,您將需要本地 Notary 規範根金鑰的金鑰和密碼。如果您以前沒有初始化過倉庫,因此沒有 Notary 根金鑰,$ docker trust
將為您建立一個。
重要請務必保護和備份您的Notary 規範根金鑰。
初始化倉庫
要將第一個金鑰上傳到委託,同時初始化一個倉庫,您可以使用 $ docker trust signer add
命令。這會將貢獻者的公鑰新增到 targets/releases
委託,並建立第二個 targets/<name>
委託。
對於 DCT,第二個委託的名稱(在下面的例子中是 jeff
)是為了幫助您跟蹤金鑰的所有者。在 Notary 的更高階用例中,會使用額外的委託來實現層次結構。
$ docker trust signer add --key cert.pem jeff registry.example.com/admin/demo
Adding signer "jeff" to registry.example.com/admin/demo...
Initializing signed repository for registry.example.com/admin/demo...
Enter passphrase for root key with ID f6c6a4b:
Enter passphrase for new repository key with ID b0014f8:
Repeat passphrase for new repository key with ID b0014f8:
Successfully initialized "registry.example.com/admin/demo"
Successfully added signer: jeff to registry.example.com/admin/demo
您可以使用 $ docker trust inspect
命令檢視已為每個倉庫推送到 Notary 伺服器的金鑰。
$ docker trust inspect --pretty registry.example.com/admin/demo
No signatures for registry.example.com/admin/demo
List of signers and their keys for registry.example.com/admin/demo
SIGNER KEYS
jeff 1091060d7bfd
Administrative keys for registry.example.com/admin/demo
Repository Key: b0014f8e4863df2d028095b74efcb05d872c3591de0af06652944e310d96598d
Root Key: 64d147e59e44870311dd2d80b9f7840039115ef3dfa5008127d769a5f657a5d7
您也可以使用 Notary CLI 來列出委託和金鑰。在這裡您可以清楚地看到金鑰已附加到 targets/releases
和 targets/jeff
。
$ notary delegation list registry.example.com/admin/demo
ROLE PATHS KEY IDS THRESHOLD
---- ----- ------- ---------
targets/jeff "" <all paths> 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 1
targets/releases "" <all paths> 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 1
新增額外的簽名者
Docker Trust 允許您為每個倉庫配置多個委託,從而管理委託的生命週期。當使用 $ docker trust
新增額外的委託時,協作者的金鑰會再次被新增到 targets/release
角色中。
請注意,您將需要倉庫金鑰的密碼;這應該是在您首次初始化倉庫時配置的。
$ docker trust signer add --key ben.pub ben registry.example.com/admin/demo
Adding signer "ben" to registry.example.com/admin/demo...
Enter passphrase for repository key with ID b0014f8:
Successfully added signer: ben to registry.example.com/admin/demo
檢查以證明現在有兩個委託(簽名者)。
$ docker trust inspect --pretty registry.example.com/admin/demo
No signatures for registry.example.com/admin/demo
List of signers and their keys for registry.example.com/admin/demo
SIGNER KEYS
ben afa404703b25
jeff 1091060d7bfd
Administrative keys for registry.example.com/admin/demo
Repository Key: b0014f8e4863df2d028095b74efcb05d872c3591de0af06652944e310d96598d
Root Key: 64d147e59e44870311dd2d80b9f7840039115ef3dfa5008127d769a5f657a5d7
向現有委託新增金鑰
為了支援金鑰輪換和金鑰過期/退役等操作,您可以為每個委託釋出多個貢獻者金鑰。這裡唯一的先決條件是確保使用相同的委託名稱,在本例中是 jeff
。Docker trust 會自動處理將這個新金鑰新增到 targets/releases
的過程。
注意您將需要倉庫金鑰的密碼;這應該是在您首次初始化倉庫時配置的。
$ docker trust signer add --key cert2.pem jeff registry.example.com/admin/demo
Adding signer "jeff" to registry.example.com/admin/demo...
Enter passphrase for repository key with ID b0014f8:
Successfully added signer: jeff to registry.example.com/admin/demo
檢查以證明該委託(簽名者)現在包含多個金鑰 ID。
$ docker trust inspect --pretty registry.example.com/admin/demo
No signatures for registry.example.com/admin/demo
List of signers and their keys for registry.example.com/admin/demo
SIGNER KEYS
jeff 1091060d7bfd, 5570b88df073
Administrative keys for registry.example.com/admin/demo
Repository Key: b0014f8e4863df2d028095b74efcb05d872c3591de0af06652944e310d96598d
Root Key: 64d147e59e44870311dd2d80b9f7840039115ef3dfa5008127d769a5f657a5d7
移除委託
如果您需要移除一個委託,包括附加到 targets/releases
角色的貢獻者金鑰,您可以使用 $ docker trust signer remove
命令。
注意被移除的委託簽名的標籤需要由一個有效的委託重新簽名。
$ docker trust signer remove ben registry.example.com/admin/demo
Removing signer "ben" from registry.example.com/admin/demo...
Enter passphrase for repository key with ID b0014f8:
Successfully removed ben from registry.example.com/admin/demo
故障排除
如果您看到錯誤提示
targets/releases
中沒有可用的金鑰,您將需要在重新簽名映象之前使用docker trust signer add
新增額外的委託。WARN[0000] role targets/releases has fewer keys than its threshold of 1; it will not be usable until keys are added to it
如果您已經添加了額外的委託,但仍然看到錯誤訊息稱
targets/releases
中沒有有效的簽名,您將需要使用 Notary CLI 重新簽署targets/releases
委託檔案。WARN[0000] Error getting targets/releases: valid signatures did not meet threshold for targets/releases
重新簽署委託檔案是透過
$ notary witness
命令完成的。$ notary witness registry.example.com/admin/demo targets/releases --publish
有關
$ notary witness
命令的更多資訊,請參見此處。
從委託中移除貢獻者的金鑰
作為委託金鑰輪換的一部分,您可能希望移除單個金鑰但保留委託。這可以透過 Notary CLI 完成。
請記住,您必須從 targets/releases
角色和特定於該簽名者的角色 targets/<name>
中都移除該金鑰。
我們需要從 Notary 伺服器獲取金鑰 ID。
$ notary delegation list registry.example.com/admin/demo ROLE PATHS KEY IDS THRESHOLD ---- ----- ------- --------- targets/jeff "" <all paths> 8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9 1 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 targets/releases "" <all paths> 8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9 1 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1
從
targets/releases
委託中移除。$ notary delegation remove registry.example.com/admin/demo targets/releases 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 --publish Auto-publishing changes to registry.example.com/admin/demo Enter username: admin Enter password: Enter passphrase for targets key with ID b0014f8: Successfully published changes for repository registry.example.com/admin/demo
從
targets/<name>
委託中移除。$ notary delegation remove registry.example.com/admin/demo targets/jeff 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 --publish Removal of delegation role targets/jeff with keys [5570b88df0736c468493247a07e235e35cf3641270c944d0e9e8899922fc6f99], to repository "registry.example.com/admin/demo" staged for next publish. Auto-publishing changes to registry.example.com/admin/demo Enter username: admin Enter password: Enter passphrase for targets key with ID b0014f8: Successfully published changes for repository registry.example.com/admin/demo
檢查剩餘的委託列表
$ notary delegation list registry.example.com/admin/demo ROLE PATHS KEY IDS THRESHOLD ---- ----- ------- --------- targets/jeff "" <all paths> 8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9 1 targets/releases "" <all paths> 8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9 1
移除本地委託私鑰
作為輪換委託金鑰的一部分,您可能需要從本地 Docker 信任儲存中移除本地委託金鑰。這可以透過 Notary CLI 使用 $ notary key remove
命令來完成。
我們需要從本地 Docker Trust 儲存中獲取金鑰 ID。
$ notary key list ROLE GUN KEY ID LOCATION ---- --- ------ -------- root f6c6a4b00fefd8751f86194c7d87a3bede444540eb3378c4a11ce10852ab1f96 /home/ubuntu/.docker/trust/private admin 8fb597cbaf196f0781628b2f52bff6b3912e4e8075720378fda60d17232bbcf9 /home/ubuntu/.docker/trust/private jeff 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 /home/ubuntu/.docker/trust/private targets ...example.com/admin/demo c819f2eda8fba2810ec6a7f95f051c90276c87fddfc3039058856fad061c009d /home/ubuntu/.docker/trust/private
從本地 Docker Trust 儲存中移除金鑰。
$ notary key remove 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 Are you sure you want to remove 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 (role jeff) from /home/ubuntu/.docker/trust/private? (yes/no) y Deleted 1091060d7bfd938dfa5be703fa057974f9322a4faef6f580334f3d6df44c02d1 (role jeff) from /home/ubuntu/.docker/trust/private.
從倉庫中移除所有信任資料
您可以使用 Notary CLI 從倉庫中刪除所有信任資料,包括倉庫、目標、快照和所有委託金鑰。
這通常是容器倉庫在刪除特定倉庫之前所要求的。
$ notary delete registry.example.com/admin/demo --remote
Deleting trust data for repository registry.example.com/admin/demo
Enter username: admin
Enter password:
Successfully deleted local and remote trust data for repository registry.example.com/admin/demo
$ docker trust inspect --pretty registry.example.com/admin/demo
No signatures or cannot access registry.example.com/admin/demo