内容信任的委托

Docker 内容信任 (DCT) 中的委托允许您控制谁可以签名和谁不能签名镜像标签。一个委托将拥有一对委托私钥和公钥。一个委托可能包含多对密钥和多个贡献者,以便 a) 允许多个用户参与委托,以及 b) 支持密钥轮换。

Docker 内容信任中最重要的委托是 targets/releases。这被视为受信任镜像标签的权威来源,如果没有贡献者的密钥在此委托下,他们将无法签名标签。

幸运的是,当使用 `$ docker trust` 命令时,我们会自动初始化一个仓库,管理仓库密钥,并通过 docker trust signer add 将协作者的密钥添加到 targets/releases 委托中。

配置 Docker 客户端

默认情况下,$ docker trust 命令期望 notary server URL 与镜像标签中指定的 registry URL 相同(遵循与 $ docker push 类似的逻辑)。当使用 Docker Hub 或 DTR 时,notary server URL 与 registry URL 相同。然而,对于自托管环境或第三方 registry,您需要为 notary server 指定一个备用 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 server 启用了认证,或者正在使用 DTR,您需要在推送数据到 notary server 之前登录。

$ 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. 下载客户端并确保其在您的路径中可用。

  2. ~/.notary/config.json 创建一个配置文件,其内容如下

{
  "trust_dir" : "~/.docker/trust",
  "remote_server": {
    "url": "https://registry.example.com",
    "root_ca": "../.docker/ca.pem"
  }
}

新创建的配置文件包含有关本地 Docker 信任数据位置和 notary server 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)以及包含公钥的 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 Server 中管理委托

当使用 `$ docker trust` 将第一个委托添加到 Notary Server 时,我们会自动初始化仓库的信任数据。这包括创建 notary target 和 snapshots 密钥,并将 snapshot 密钥轮换为由 notary server 管理。有关这些密钥的更多信息,请参见此处

初始化仓库时,您需要本地 Notary Canonical Root Key 的密钥和密码短语。如果您之前未初始化过仓库,因此没有 Notary root key,则 `$ docker trust` 会为您创建一个。

重要提示

请务必保护和备份您的 Notary Canonical Root Key

初始化仓库

要将第一个密钥上传到委托,并同时初始化仓库,可以使用 `$ docker trust signer add` 命令。这将把贡献者的公钥添加到 targets/releases 委托中,并创建第二个 targets/ 委托。

对于 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 server。

$ 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

检查以证明现在有两个委托 (Signer)。

$ 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

检查以证明委托 (Signer) 现在包含多个 Key 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. 如果您已经添加了附加委托,并且看到错误消息,提示 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/ 中移除该密钥。

  1. 我们需要从 Notary Server 中获取 Key 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/ 委托中移除

    $ 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 存储中获取 Key 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 从仓库中移除所有信任数据,包括仓库、target、snapshot 和所有委托密钥。

在删除特定仓库之前,容器 Registry 通常会要求执行此操作。

$ 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
页面选项