Docker 中的内容信任
在网络系统之间传输数据时,信任是一个核心问题。在 特别是,当通过不受信任的介质(如 Internet)进行通信时,它会 对于确保系统所有数据的完整性和发布者至关重要 操作 on。您可以使用 Docker Engine 将镜像(数据)推送和拉取到 公共或私有注册表。内容信任使您能够验证两者 从 Registry 接收的所有数据的完整性和发布者 任何频道。
关于 Docker Content Trust (DCT)
Docker 内容信任 (DCT) 提供了将数字签名用于 发送到远程 Docker 注册表和从远程 Docker 注册表接收的数据。这些签名允许 客户端或运行时验证特定 image 标签。
通过 DCT,镜像发布者可以对其镜像进行签名,镜像使用者可以 确保他们提取的镜像已签名。出版商可以是个人 或组织手动签署其内容或自动软件供应 链对内容进行签名作为其发布过程的一部分。
镜像标记和 DCT
单个镜像记录具有以下标识符:
[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
一个特定的镜像可以有多个标签。例如,和 都是镜像上的标记。镜像发布者可以构建镜像
和标签组合多次更改镜像。REPOSITORY
latest
3.1.2
mongo
DCT 与镜像的部分相关联。每个镜像仓库都有
镜像发布者用于对镜像标记进行签名的一组密钥。图片发布者
可以自行决定他们签署哪些标签。TAG
镜像存储库可以包含具有一个已签名标记和另一个标记的镜像
标签。例如,考虑 Mongo 镜像
存储库。标记可以未签名,而标记可以签名。它是
图片发布者负责决定图片标签是否已签名,或者
不。在此表示形式中,一些镜像标记已签名,而其他镜像标记则未签名:latest
3.1.6
发布者可以选择是否对特定标记进行签名。因此,内容
unsigned 标签和同名 signed 标签的标签可能不匹配。为
例如,发布者可以推送标记的镜像并对其进行签名。
稍后,同一发布者可以推送未签名的镜像。这第二个
push 替换最后一个 unsigned 标签,但不会影响 signed 版本。
选择他们可以签名的标签的能力允许出版商迭代
正式签名之前镜像的未签名版本。someimage:latest
someimage:latest
latest
latest
镜像使用者可以启用 DCT 以确保他们使用的镜像已签名。如果 consumer 启用 DCT,则他们只能使用可信镜像拉取、运行或构建。 启用 DCT 有点像将 “filter” 应用于您的注册表。消费者 “看到” 只有已签名的镜像标签和不太理想的未签名镜像标签是 对他们来说“不可见”。
对于尚未启用 DCT 的使用者,无需了解他们如何使用 Docker 镜像更改。每张镜像都是可见的,无论它是签名的还是 不。
Docker 内容信任密钥
镜像标记的信任通过使用签名密钥进行管理。密钥集是 在首次调用使用 DCT 的操作时创建。密钥集包括 以下键类的密钥:
- 作为镜像标签的 DCT 根的离线密钥
- 对标签进行签名的仓库或标记键
- 服务器管理的密钥,例如时间戳密钥,它提供新鲜度 仓库的安全保证
下图描述了各种签名密钥及其关系:
警告
根密钥一旦丢失,将无法恢复。如果您丢失了任何其他密钥,请向 Docker Hub Support 发送电子邮件。这种损失还需要每个 在丢失之前使用此存储库中的签名标记的使用者。
您应该将根密钥备份到安全的地方。鉴于它是必需的 要创建新的存储库,最好将其离线存储在硬件中。 有关保护和备份密钥的详细信息,请确保您 了解如何管理 DCT 的密钥。
使用 Docker Content Trust 对镜像进行签名
在 Docker CLI 中,我们可以使用命令语法对容器镜像进行签名和推送。这是建立在 Notary 功能之上的
设置。有关更多信息,请参阅 Notary GitHub 存储库。$ docker trust
对镜像进行签名的先决条件是使用 Notary 服务器的 Docker Registry attached (如 Docker Hub )。说明 可以在此处找到建立自托管环境。
要对 Docker 镜像进行签名,您需要一个委托密钥对。这些键
可以在本地使用 或 生成
由证书颁发机构提供。$ docker trust key generate
首先,我们将委托私钥添加到本地 Docker 信任中
存储 库。(默认情况下,它存储在 中)。如果你是
使用 生成委托密钥 ,私有密钥
会自动添加到本地信任存储中。如果要导入单独的
键,您将需要使用该命令。~/.docker/trust/
$ docker trust key generate
$ docker trust key load
$ 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
或者,如果你有现有的密钥:
$ docker trust key load key.pem --name jeff
Loading key from "key.pem"...
Enter passphrase for new jeff key with ID 8ae710e:
Repeat passphrase for new jeff key with ID 8ae710e:
Successfully imported key from key.pem
接下来,我们需要将委托公钥添加到 Notary 服务器; 这特定于 Notary 中的特定镜像存储库,称为全局 唯一名称 (GUN)。如果这是您第一次向该 repository 中,此命令还将使用本地 Notary 启动 repository 规范根键。要了解有关启动存储库的更多信息,以及 委托的角色,前往 内容信任的委托。
$ docker trust signer add --key cert.pem jeff registry.example.com/admin/demo
Adding signer "jeff" to registry.example.com/admin/demo...
Enter passphrase for new repository key with ID 10b5e94:
最后,我们将使用委托私钥对特定标签进行签名,并且 将其推送到注册表。
$ docker trust sign registry.example.com/admin/demo:1
Signing and pushing trust data for local image registry.example.com/admin/demo:1, may overwrite remote trust data
The push refers to repository [registry.example.com/admin/demo]
7bff100f35cb: Pushed
1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528
Signing and pushing trust metadata
Enter passphrase for signer key with ID 8ae710e:
Successfully signed registry.example.com/admin/demo:1
或者,导入密钥后,可以通过导出 DCT 环境变量,使用命令推送镜像。$ docker push
$ export DOCKER_CONTENT_TRUST=1
$ docker push registry.example.com/admin/demo:1
The push refers to repository [registry.example.com/admin/demo:1]
7bff100f35cb: Pushed
1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528
Signing and pushing trust metadata
Enter passphrase for signer key with ID 8ae710e:
Successfully signed registry.example.com/admin/demo:1
可以通过以下命令查看标签或仓库的远程信任数据:$ docker trust inspect
$ docker trust inspect --pretty registry.example.com/admin/demo:1
Signatures for registry.example.com/admin/demo:1
SIGNED TAG DIGEST SIGNERS
1 3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e jeff
List of signers and their keys for registry.example.com/admin/demo:1
SIGNER KEYS
jeff 8ae710e3ba82
Administrative keys for registry.example.com/admin/demo:1
Repository Key: 10b5e94c916a0977471cc08fa56c1a5679819b2005ba6a257aa78ce76d3a1e27
Root Key: 84ca6e4416416d78c4597e754f38517bea95ab427e5f95871f90d460573071fc
可以通过以下命令删除标签的 Remote Trust 数据:$ docker trust revoke
$ docker trust revoke registry.example.com/admin/demo:1
Enter passphrase for signer key with ID 8ae710e:
Successfully deleted signature for registry.example.com/admin/demo:1
使用 Docker Content Trust 执行客户端
默认情况下,内容信任在 Docker 客户端中处于禁用状态。要启用
it,请将环境变量设置为 。这可以防止
用户无法使用标记的镜像,除非它们包含签名。DOCKER_CONTENT_TRUST
1
在 Docker 客户端中启用 DCT 后,对
标记的镜像必须具有内容签名或显式内容哈希。
使用 DCT 操作的命令包括:docker
push
build
create
pull
run
例如,启用 DCT 后,仅
如果已签名,则成功。但是,具有显式
只要 hash 存在,content hash 就总是成功的:docker pull someimage:latest
someimage:latest
$ docker pull registry.example.com/user/image:1
Error: remote trust data does not exist for registry.example.com/user/image: registry.example.com does not have trust data for registry.example.com/user/image
$ docker pull registry.example.com/user/image@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a
sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1: Pulling from user/image
ff3a5c916c92: Pull complete
a59a168caba3: Pull complete
Digest: sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1
Status: Downloaded newer image for registry.example.com/user/image@sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1