在线文档教程

Docker中的内容信任 | Content trust in Docker (Engine)

Docker中的内容信任

在联网系统间传输数据时,信任是一个中心问题。特别是,当通过互联网等不可信介质进行通信时,确保系统运行的所有数据的完整性和发布者至关重要。您使用Docker Engine将图像(数据)推送到公共或私有注册表。内容信任使您能够通过任何通道验证从注册表接收的所有数据的完整性和发布者。

理解Docker中的信任

内容信任允许使用远程Docker注册表执行操作,以强制客户端对图像标记进行签名和验证。内容信任提供了使用数字签名来发送和接收远程Docker注册管理机构数据的能力。这些签名允许客户端验证特定图像标签的完整性和发布者。

目前,内容信任被默认禁用。要启用它,请将DOCKER_CONTENT_TRUST环境变量设置为1。请参阅Docker客户端的环境变量和公证配置以获取更多选项。

一旦启用内容信任,图像发布者就可以对其图像进行签名。图像消费者可以确保他们使用的图像被签名。发布者和消费者可以是单独的个人或组织中的个人。Docker的内容信任支持用户和自动化进程,如构建。

图像标签和内容信任

单个图像记录具有以下标识符:

[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]

一个特定的图像REPOSITORY可以有多个标签。例如,latest并且3.1.2都是mongo图像上的标签。图像发布者可以在每次构建时多次更改图像来构建图像和标签组合。

内容信任与TAG图像的一部分相关联。每个图像库都有一组图像发布者用来签署图像标签的密钥。图片发布者可以自行决定签署哪些标签。

图像存储库可以包含一个图像,其中包含一个被签名的标签和另一个不是的标签。例如,考虑Mongo映像存储库。该latest标签可以是无签名的,而3.1.6标签可以被签名。图片发布者有责任决定图片标签是否已签名。在这种表示中,一些图像标签被签名,而另一些则不是:

发布商可以选择是否签署特定标签。因此,未签名标签的内容与具有相同名称的已签名标签的内容可能不匹配。例如,发布商可以推送已标记的图片someimage:latest并对其进行签名。稍后,同一个发布者可以推送未签名的someimage:latest图像。第二次推送替换最后一个未签名标签,latest但不会影响签名latest版本。能够选择他们可以签名的标签,允许发布者在正式签名之前迭代未签名的图像版本。

图片使用者可以启用内容信任以确保他们使用的图像已被签名。如果消费者启用内容信任,则只能使用受信任的映像进行抽取,运行或构建。启用内容信任就像戴着一副玫瑰色的眼镜。消费者“see”只有签名的图像标签,不太理想的,未签名的图像标签对他们来说是“invisible”。

对于尚未启用内容信任的消费者,没有任何关于他们如何使用Docker镜像的更改。无论是否签名,每张图片都可见。

内容信任操作和密钥

启用内容信任时,docker对标记图像执行操作的CLI命令必须具有内容签名或显式内容散列。与内容信任一起运行的命令是:

  • push

  • build

  • create

  • pull

  • run

例如,启用内容信任后,docker pull someimage:latest只有在someimage:latest签名后才能成功。但是,只要存在散列,具有显式内容散列的操作就会始终成功:

$ docker pull someimage@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a

通过使用签名密钥来管理图像标签的信任。首次调用使用内容信任的操作时会创建密钥集。密钥集由以下几类密钥组成:

  • 作为图像标记的内容信任的根的脱机密钥

  • 存储库或标记签名标签的密钥

  • 服务器管理的密钥(例如时间戳密钥),为您的存储库提供新鲜度安全保证

下图描述了各种签名密钥及其关系:

警告:丢失根密钥非常难以恢复。纠正这种损失需要Docker支持人员的干预来重置存储库状态。这种损失还需要所有使用此存储库中的签名标记的使用者在丢失之前进行手动干预

您应该将根密钥备份到安全的地方。鉴于仅需要创建新的存储库,最好将其脱机存储在硬件中。有关保护和备份密钥的详细信息,请务必阅读如何管理密钥以进行内容信任。

典型内容信任操作调查

本节将调查用户使用Docker镜像执行的典型可信操作。具体来说,我们将通过以下步骤来帮助我们实施以下各种可信操作:

  • 构建并推送未签名的图像

  • 拉一个未签名的图像

  • 构建并推送签名图像

  • 拉上面推送的签名图像

  • 拉出上面推送的无符号图像

启用和禁用每个shell或每次调用的内容信任

在shell中,可以通过设置DOCKER_CONTENT_TRUST环境变量来启用内容信任。启用per-shell非常有用,因为您可以为可信操作配置一个shell,为不可信操作配置另一个终端shell。您还可以将此声明添加到您的shell配置文件中,以便默认情况下始终打开它。

若要在bashshell输入以下命令:

export DOCKER_CONTENT_TRUST=1

一旦设置,每个“tag”操作都需要一个可信标签的密钥。

DOCKER_CONTENT_TRUST设置的环境中,您可以使用此--disable-content-trust标志按需在不带内容信任的情况下对标记图像运行单个操作。

考虑使用不受信任父映像的以下Dockerfile:

$ cat Dockerfile FROM docker/trusttest:latest RUN echo

为了使用这个Dockerfile成功构建一个容器,可以这样做:

$ docker build --disable-content-trust -t <username>/nottrusttest:latest . Sending build context to Docker daemon 42.84 MB ... Successfully built f21b872447dc

所有其他命令也是如此,例如pullpush

$ docker pull --disable-content-trust docker/trusttest:latest ... $ docker push --disable-content-trust <username>/nottrusttest:latest ...

无论是否DOCKER_CONTENT_TRUST设置变量或如何设置,都要启用启用内容信任的命令:

$ docker build --disable-content-trust=false -t <username>/trusttest:testing .

所有受信任的操作都支持该--disable-content-trust标志。

推送可信内容

要为特定图像标记创建签名内容,只需启用内容信任并推送标记的图像即可。如果这是您第一次在系统上使用内容信任推送图像,则会话如下所示:

$ docker push <username>/trusttest:testing The push refers to a repository [docker.io/<username>/trusttest] (len: 1) 9a61b6b1315e: Image already exists 902b87aaaec9: Image already exists latest: digest: sha256:d02adacee0ac7a5be140adb94fa1dae64f4e71a68696e7f8e7cbf9db8dd49418 size: 3220 Signing and pushing trust metadata You are about to create a new root signing key passphrase. This passphrase will be used to protect the most sensitive key in your signing system. Please choose a long, complex passphrase and be careful to keep the password and the key file itself secure and backed up. It is highly recommended that you use a password manager to generate the passphrase and keep it safe. There will be no way to recover this key. You can find the key in your config directory. Enter passphrase for new root key with id a1d96fb: Repeat passphrase for new root key with id a1d96fb: Enter passphrase for new repository key with id docker.io/<username>/trusttest (3a932f1): Repeat passphrase for new repository key with id docker.io/<username>/trusttest (3a932f1): Finished initializing "docker.io/<username>/trusttest"

当您启用启用内容信任的第一个标记图像时,docker客户端会认识到这是您的第一次推送,并且:

  • 提醒您它将创建一个新的根密钥

  • 请求根密钥的密码

  • ~/.docker/trust目录中生成一个根密钥

  • 请求存储库密钥的密码

  • ~/.docker/trust目录中生成一个存储库密钥

您为根密钥和存储库密钥对选择的密码应随机生成并存储在密码管理器中

注意:如果您省略testing标签,则跳过内容信任。即使启用了内容信任,即使这是您的第一次推送,情况也是如此。

$ docker push <username>/trusttest The push refers to a repository [docker.io/<username>/trusttest] (len: 1) 9a61b6b1315e: Image successfully pushed 902b87aaaec9: Image successfully pushed latest: digest: sha256:a9a9c4402604b703bed1c847f6d85faac97686e48c579bd9c3b0fa6694a398fc size: 3220 No tag specified, skipping trust metadata push

它被跳过,因为消息指出,你没有提供图像TAG值。在Docker内容信任中,签名与标签相关联。

一旦在系统上拥有root密钥,您创建的后续图像存储库就可以使用相同的根密钥:

$ docker push docker.io/<username>/otherimage:latest The push refers to a repository [docker.io/<username>/otherimage] (len: 1) a9539b34a6ab: Image successfully pushed b3dbab3810fc: Image successfully pushed latest: digest: sha256:d2ba1e603661a59940bfad7072eba698b79a8b20ccbb4e3bfb6f9e367ea43939 size: 3346 Signing and pushing trust metadata Enter key passphrase for root key with id a1d96fb: Enter passphrase for new repository key with id docker.io/<username>/otherimage (bb045e3): Repeat passphrase for new repository key with id docker.io/<username>/otherimage (bb045e3): Finished initializing "docker.io/<username>/otherimage"

新图像具有自己的存储库密钥和时间戳密钥。该latest标签与这两个签名。

提取图片内容

消费图像的常用方式就是pull它。启用内容信任后,Docker客户端仅允许docker pull检索已签名的图像。让我们试着拉你之前签名和推送的图片:

$ docker pull <username>/trusttest:testing Pull (1 of 1): <username>/trusttest:testing@sha256:d149ab53f871 ... Tagging <username>/trusttest@sha256:d149ab53f871 as docker/trusttest:testing

在以下示例中,该命令没有指定标签,因此系统latest默认再次使用该标签,并且该docker/trusttest:latest标签未被签名。

$ docker pull docker/trusttest Using default tag: latest no trust data available

由于标记docker/trusttest:latest不可信,因此pull失败。

相关信息

  • 管理内容信任的密钥

  • 内容信任的自动化

  • 内容信任代表团

  • 在内容信任沙箱中播放

内容信任安全docker文档