内容信任代表团

预计阅读时间:14分钟

Docker Content Trust(DCT)中的委托允许您控制谁可以签名图像标签,也可以不签名。一个代表团将有一对私人和公共代表团钥匙。委派可以包含多对密钥和贡献者,以便a)允许多个用户成为委派的一部分,以及b)支持密钥轮换。

Docker Content Trust中最重要的委托是targets/releases。这被视为受信任图像标签的规范来源,并且如果在此委托下没有贡献者的密钥,则他们将无法对标签进行签名。

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

配置Docker客户端

默认情况下,$ docker trust命令期望公证服务器URL与image标记中指定的注册表URL相同(遵循与类似的逻辑 $ docker push)。使用Docker Hub或DTR时,公证服务器URL与注册表URL相同。但是,对于自托管环境或第三方注册表,您将需要为公证服务器指定备用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
[...]

如果您为公证服务器启用了身份验证,或者正在使用DTR,则需要先登录,然后才能将数据推送到公证服务器。

$ 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

配置公证人客户端

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信任数据和公证服务器URL的位置的信息。

有关如何在Docker Content Trust用例之外使用公证的更多详细信息,请参阅此处的公证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)和包含公钥的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

在公证服务器中管理委托

使用将第一个授权添加到公证服务器后$ docker trust,我们将自动启动存储库的信任数据。这包括创建公证目标和快照密钥,以及旋转要由公证服务器管理的快照密钥。有关这些键的更多信息,请参见 此处。

启动存储库时,您将需要密钥和本地公证人规范根密钥的密码短语。如果您之前没有启动存储库,因此没有公证根密钥,$ docker trust则将为您创建一个。

确保保护和备份您的公证规范根密钥

启动存储库

要将第一个密钥上载到委派,同时启动存储库,可以使用以下$ docker trust signer add命令。这会将贡献者的公钥添加到targets/releases委托中,并创建第二个targets/<name>委托。

对于DCT,在下面的示例中jeff,第二个委托的名称 可以帮助您跟踪密钥的所有者。在公证人的更高级用例中,附加委托用于层次结构。

$ 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命令查看已将每个存储库中的哪些键推送到了公证服务器。

$ 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

检查以证明现在有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 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,则需要targets/releases使用Notary CLI对委托文件进行签名。

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)我们需要从公证服务器获取密钥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 key remove命令通过Notary CLI完成。

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
信任安全委托密钥知识库