內容信任委派

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

  1. 下載 用戶端

新建立的設定檔包含有關您本機 Docker 信任資料位置和 notary 伺服器 URL 的資訊。

有關如何在 Docker 內容信任用例之外使用 notary 的更詳細資訊,請參閱 Notary CLI 文件 此處建立委派金鑰

新增您的第一個貢獻者的先決條件是一對委派金鑰。這些金鑰可以使用 `$ docker trust` 在本機產生,也可以由憑證授權單位產生。

使用 Docker Trust 產生金鑰

Docker trust 有一個內建的委派金鑰對產生器,`$ docker trust generate <名稱>`。執行此命令將自動將委派私鑰載入到本機 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)和包含公鑰的 x509 憑證,您可以使用 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 target 和 snapshots 密鑰,以及輪替 snapshot 密鑰以由 notary 伺服器管理。更多關於這些密鑰的資訊可以在這裡找到。

初始化儲存庫時,您將需要本機 Notary Canonical Root Key 的密鑰和通行片語。如果您之前沒有初始化儲存庫,因此沒有 Notary 根密鑰,$ docker trust 將會為您建立一個。

重要

請務必保護並備份您的Notary Canonical Root Key

初始化儲存庫

要將第一個密鑰上傳到委派,同時初始化儲存庫,您可以使用 $ 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/releasestargets/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

檢查以證明現在有 2 個委派(簽署者)。

$ 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

故障排除

  1. 如果您看到錯誤訊息指出 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
  2. 如果您已經新增了額外的委派,並且看到錯誤訊息指出 targest/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> 中移除密鑰。

  1. 我們需要從 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    
    
  2. 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
    
  3. 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
    
  4. 檢查剩餘的委派列表。

    $ 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 命令完成。

  1. 我們需要從本機 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
    
  2. 從本機 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