在内容信任沙箱中演练
本页面介绍了如何设置和使用沙箱来试验信任。通过沙箱,您可以在本地配置和尝试信任操作,而不会影响生产镜像。
在使用此沙箱之前,您应该已阅读过信任概述。
前提条件
这些说明假设您正在 Linux 或 macOS 环境中运行。您可以在本地机器或虚拟机上运行此沙箱。您需要在本地机器或虚拟机中拥有运行 docker 命令的权限。
此沙箱要求您安装两个 Docker 工具:Docker Engine >= 1.10.0 和 Docker Compose >= 1.6.0。要安装 Docker Engine,请从支持的平台列表中选择。要安装 Docker Compose,请参阅此处详细说明。
沙箱中有什么?
如果您只是开箱即用地使用信任,您只需要 Docker Engine 客户端并访问 Docker Hub。此沙箱模拟生产信任环境,并设置了这些额外的组件。
容器 | 说明 |
---|---|
trustsandbox | 一个包含最新版本 Docker Engine 并预配置了一些证书的容器。这是您的沙箱,您可以在其中使用 docker 客户端测试信任操作。 |
注册表服务器 | 一个本地注册表服务。 |
Notary 服务器 | 执行所有信任管理繁重工作的服务 |
这意味着您运行自己的内容信任 (Notary) 服务器和注册表。如果您只使用 Docker Hub,则无需这些组件。它们已内置在 Docker Hub 中。然而,对于此沙箱,您构建了完整的模拟生产环境。
在 trustsandbox
容器内,您与本地注册表交互,而不是 Docker Hub。这意味着您日常使用的镜像仓库不会被使用。在您演练时,它们受到保护。
在沙箱中演练时,您还会创建根密钥和仓库密钥。沙箱配置为将所有密钥和文件存储在 trustsandbox
容器内。由于您在沙箱中创建的密钥仅用于演练,因此销毁容器也会销毁它们。
通过为 trustsandbox
容器使用 docker-in-docker 镜像,您也不会用您推送和拉取的任何镜像污染真实的 Docker 守护进程缓存。这些镜像存储在此容器附加的匿名卷中,可以在销毁容器后销毁。
构建沙箱
在本节中,您将使用 Docker Compose 指定如何设置并连接 trustsandbox
容器、Notary 服务器和注册表服务器。
创建一个新的
trustsandbox
目录并进入其中。$ mkdir trustsandbox $ cd trustsandbox
使用您喜欢的编辑器创建一个名为
compose.yaml
的文件。例如,使用 vim$ touch compose.yaml $ vim compose.yaml
将以下内容添加到新文件中。
version: "2" services: notaryserver: image: dockersecurity/notary_autobuilds:server-v0.5.1 volumes: - notarycerts:/var/lib/notary/fixtures networks: - sandbox environment: - NOTARY_SERVER_STORAGE_TYPE=memory - NOTARY_SERVER_TRUST_SERVICE_TYPE=local sandboxregistry: image: registry:2.4.1 networks: - sandbox container_name: sandboxregistry trustsandbox: image: docker:dind networks: - sandbox volumes: - notarycerts:/notarycerts privileged: true container_name: trustsandbox entrypoint: "" command: |- sh -c ' cp /notarycerts/root-ca.crt /usr/local/share/ca-certificates/root-ca.crt && update-ca-certificates && dockerd-entrypoint.sh --insecure-registry sandboxregistry:5000' volumes: notarycerts: external: false networks: sandbox: external: false
保存并关闭文件。
在您的本地系统上运行容器。
$ docker compose up -d
首次运行此命令时,将从 Docker Hub 下载 docker-in-docker、Notary 服务器和注册表镜像。
在沙箱中演练
现在一切都已设置好,您可以进入 trustsandbox
容器并开始测试 Docker 内容信任。从您的宿主机,在 trustsandbox
容器中获取一个 shell。
$ docker container exec -it trustsandbox sh
/ #
测试一些信任操作
现在,从 trustsandbox
容器内部拉取一些镜像。
下载一个
docker
镜像进行测试。/ # docker pull docker/trusttest docker pull docker/trusttest Using default tag: latest latest: Pulling from docker/trusttest b3dbab3810fc: Pull complete a9539b34a6ab: Pull complete Digest: sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a Status: Downloaded newer image for docker/trusttest:latest
给它打标签,以便推送到我们的沙箱注册表
/ # docker tag docker/trusttest sandboxregistry:5000/test/trusttest:latest
启用内容信任。
/ # export DOCKER_CONTENT_TRUST=1
标识信任服务器。
/ # export DOCKER_CONTENT_TRUST_SERVER=https://notaryserver:4443
此步骤仅在沙箱使用其自己的服务器时需要。通常,如果您使用 Docker Public Hub,则无需此步骤。
拉取测试镜像。
/ # docker pull sandboxregistry:5000/test/trusttest Using default tag: latest Error: remote trust data does not exist for sandboxregistry:5000/test/trusttest: notaryserver:4443 does not have trust data for sandboxregistry:5000/test/trusttest
您会看到错误,因为此内容尚不存在于
notaryserver
上。推送并签署受信任的镜像。
/ # docker push sandboxregistry:5000/test/trusttest:latest The push refers to a repository [sandboxregistry:5000/test/trusttest] 5f70bf18a086: Pushed c22f7bc058a9: Pushed latest: digest: sha256:ebf59c538accdf160ef435f1a19938ab8c0d6bd96aef8d4ddd1b379edf15a926 size: 734 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 27ec255: Repeat passphrase for new root key with ID 27ec255: Enter passphrase for new repository key with ID 58233f9 (sandboxregistry:5000/test/trusttest): Repeat passphrase for new repository key with ID 58233f9 (sandboxregistry:5000/test/trusttest): Finished initializing "sandboxregistry:5000/test/trusttest" Successfully signed "sandboxregistry:5000/test/trusttest":latest
由于您是首次推送此仓库,Docker 会创建新的根密钥和仓库密钥,并要求您输入用于加密它们的密码短语。如果之后再次推送,它只要求您输入仓库密码短语,以便解密密钥并再次签名。
尝试拉取您刚推送的镜像
/ # docker pull sandboxregistry:5000/test/trusttest Using default tag: latest Pull (1 of 1): sandboxregistry:5000/test/trusttest:latest@sha256:ebf59c538accdf160ef435f1a19938ab8c0d6bd96aef8d4ddd1b379edf15a926 sha256:ebf59c538accdf160ef435f1a19938ab8c0d6bd96aef8d4ddd1b379edf15a926: Pulling from test/trusttest Digest: sha256:ebf59c538accdf160ef435f1a19938ab8c0d6bd96aef8d4ddd1b379edf15a926 Status: Downloaded newer image for sandboxregistry:5000/test/trusttest@sha256:ebf59c538accdf160ef435f1a19938ab8c0d6bd96aef8d4ddd1b379edf15a926 Tagging sandboxregistry:5000/test/trusttest@sha256:ebf59c538accdf160ef435f1a19938ab8c0d6bd96aef8d4ddd1b379edf15a926 as sandboxregistry:5000/test/trusttest:latest
使用恶意镜像测试
数据损坏且您在启用信任的情况下尝试拉取时会发生什么?在本节中,您将进入 sandboxregistry
并篡改一些数据。然后,您尝试拉取它。
保持
trustsandbox
shell 和容器运行。从您的宿主机打开一个新的交互式终端,并获取进入
sandboxregistry
容器的 shell。$ docker container exec -it sandboxregistry bash root@65084fc6f047:/#
列出您推送的
test/trusttest
镜像的层root@65084fc6f047:/# ls -l /var/lib/registry/docker/registry/v2/repositories/test/trusttest/_layers/sha256 total 12 drwxr-xr-x 2 root root 4096 Jun 10 17:26 a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 drwxr-xr-x 2 root root 4096 Jun 10 17:26 aac0c133338db2b18ff054943cee3267fe50c75cdee969aed88b1992539ed042 drwxr-xr-x 2 root root 4096 Jun 10 17:26 cc7629d1331a7362b5e5126beb5bf15ca0bf67eb41eab994c719a45de53255cd
切换到其中一个层的注册表存储目录(这在一个不同的目录中)
root@65084fc6f047:/# cd /var/lib/registry/docker/registry/v2/blobs/sha256/aa/aac0c133338db2b18ff054943cee3267fe50c75cdee969aed88b1992539ed042
向
trusttest
的其中一个层添加恶意数据root@65084fc6f047:/# echo "Malicious data" > data
返回您的
trustsandbox
终端。列出
trusttest
镜像。/ # docker image ls | grep trusttest REPOSITORY TAG IMAGE ID CREATED SIZE docker/trusttest latest cc7629d1331a 11 months ago 5.025 MB sandboxregistry:5000/test/trusttest latest cc7629d1331a 11 months ago 5.025 MB sandboxregistry:5000/test/trusttest <none> cc7629d1331a 11 months ago 5.025 MB
从本地缓存中删除
trusttest:latest
镜像。/ # docker image rm -f cc7629d1331a Untagged: docker/trusttest:latest Untagged: sandboxregistry:5000/test/trusttest:latest Untagged: sandboxregistry:5000/test/trusttest@sha256:ebf59c538accdf160ef435f1a19938ab8c0d6bd96aef8d4ddd1b379edf15a926 Deleted: sha256:cc7629d1331a7362b5e5126beb5bf15ca0bf67eb41eab994c719a45de53255cd Deleted: sha256:2a1f6535dc6816ffadcdbe20590045e6cbf048d63fd4cc753a684c9bc01abeea Deleted: sha256:c22f7bc058a9a8ffeb32989b5d3338787e73855bf224af7aa162823da015d44c
Docker 不会重新下载已缓存的镜像,但我们希望 Docker 尝试从注册表下载被篡改的镜像,并因其无效而拒绝。
再次拉取镜像。由于我们没有缓存该镜像,这将从注册表下载它。
/ # docker pull sandboxregistry:5000/test/trusttest Using default tag: latest Pull (1 of 1): sandboxregistry:5000/test/trusttest:latest@sha256:35d5bc26fd358da8320c137784fe590d8fcf9417263ef261653e8e1c7f15672e sha256:35d5bc26fd358da8320c137784fe590d8fcf9417263ef261653e8e1c7f15672e: Pulling from test/trusttest aac0c133338d: Retrying in 5 seconds a3ed95caeb02: Download complete error pulling image configuration: unexpected EOF
拉取未完成,因为信任系统无法验证镜像。
在沙箱中进一步演练
现在,您在本地系统上拥有了一个完整的 Docker 内容信任沙箱,请随意使用并查看其行为。如果您发现 Docker 的任何安全问题,请随时通过电子邮件发送给我们:security@docker.com。
清理沙箱
完成后,如果您想清理已启动的所有服务以及创建的所有匿名卷,只需在您创建 Docker Compose 文件的目录中运行以下命令
$ docker compose down -v