在内容信任沙盒中玩耍

本页面解释了如何设置和使用沙盒进行信任实验。 沙盒允许您在本地配置和尝试信任操作,而不会影响您的生产镜像。

在开始这个沙盒之前,你应该已经阅读过信任概述

先决条件

这些说明假设您在Linux或macOS上运行。您可以在本地机器或虚拟机上运行此沙盒。您需要拥有在本地机器或虚拟机中运行docker命令的权限。

此沙箱要求您安装两个Docker工具:Docker Engine >= 1.10.0 和 Docker Compose >= 1.6.0。要安装Docker Engine,请从支持的平台列表中选择。要安装Docker Compose,请参阅这里的详细说明

沙盒里有什么?

如果您只是使用开箱即用的信任功能,您只需要您的Docker Engine客户端和访问Docker Hub的权限。沙盒模拟了一个生产信任环境,并设置了这些额外的组件。

ContainerDescription
trustsandboxA container with the latest version of Docker Engine and with some preconfigured certificates. This is your sandbox where you can use the docker client to test trust operations.
Registry serverA local registry service.
Notary serverThe service that does all the heavy-lifting of managing trust

这意味着您需要运行自己的内容信任(Notary)服务器和注册表。 如果您只与Docker Hub合作,您将不需要这些组件。 它们已经内置在Docker Hub中供您使用。然而,对于沙盒环境,您需要构建自己的完整模拟生产环境。

trustsandbox容器中,您与本地注册表交互,而不是Docker Hub。这意味着您日常使用的镜像仓库不会被使用。在您玩耍时,它们受到保护。

当你在沙盒中玩耍时,你也会创建根密钥和仓库密钥。沙盒被配置为将所有密钥和文件存储在trustsandbox容器内。由于你在沙盒中创建的密钥仅供玩耍使用,销毁容器也会销毁它们。

通过使用trustsandbox容器的docker-in-docker镜像,您也不会用推送和拉取的任何镜像污染真实的Docker守护进程缓存。这些镜像存储在与该容器连接的匿名卷中,并且可以在销毁容器后销毁。

构建沙盒

在本节中,您将使用 Docker Compose 来指定如何设置并连接 trustsandbox 容器、Notary 服务器和 Registry 服务器。

  1. 创建一个新的trustsandbox目录并切换到该目录。

     $ mkdir trustsandbox
     $ cd trustsandbox
    
  2. 使用您喜欢的编辑器创建一个名为compose.yml的文件。例如,使用vim:

     $ touch compose.yml
     $ vim compose.yml
    
  3. 将以下内容添加到新文件中。

     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
    
  4. 保存并关闭文件。

  5. 在您的本地系统上运行容器。

     $ docker compose up -d
    

    第一次运行时,docker-in-docker、Notary服务器和注册表镜像将从Docker Hub下载。

在沙盒中玩耍

现在一切都已经设置好了,你可以进入你的trustsandbox容器并开始测试Docker内容信任。从你的主机上,获取trustsandbox容器中的shell。

$ docker container exec -it trustsandbox sh
/ #

测试一些信任操作

现在,从trustsandbox容器中拉取一些图像。

  1. 下载一个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
    
  2. 标记它以推送到我们的沙盒注册表:

     / # docker tag docker/trusttest sandboxregistry:5000/test/trusttest:latest
    
  3. 启用内容信任。

     / # export DOCKER_CONTENT_TRUST=1
    
  4. 识别信任服务器。

     / # export DOCKER_CONTENT_TRUST_SERVER=https://notaryserver:4443
    

    此步骤仅在沙箱使用其自己的服务器时才是必要的。 通常情况下,如果您使用的是Docker公共中心,则不需要此步骤。

  5. 拉取测试镜像。

     / # 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上尚不存在。

  6. 推送并签署可信镜像。

     / # 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 会创建新的根密钥和仓库密钥,并要求你输入用于加密它们的密码短语。如果你之后再次推送,它只会要求你输入仓库密码短语,以便解密密钥并再次签名。

  7. 尝试拉取你刚刚推送的镜像:

     / # 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并篡改一些数据。然后,您尝试提取它。

  1. 保持 trustsandbox shell 和容器运行。

  2. 从您的主机打开一个新的交互式终端,并获取进入sandboxregistry容器的shell。

    $ docker container exec -it sandboxregistry bash
    root@65084fc6f047:/#
    
  3. 列出你推送的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
    
  4. 更改到其中一个层的注册表存储(这在一个不同的目录中):

    root@65084fc6f047:/# cd /var/lib/registry/docker/registry/v2/blobs/sha256/aa/aac0c133338db2b18ff054943cee3267fe50c75cdee969aed88b1992539ed042
    
  5. 将恶意数据添加到trusttest层之一:

    root@65084fc6f047:/# echo "Malicious data" > data
    
  6. 返回到您的 trustsandbox 终端。

  7. 列出 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
    
  8. 从我们的本地缓存中移除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 尝试从注册表下载被篡改的镜像并拒绝它,因为它是无效的。

  9. 再次拉取镜像。这将从注册表下载镜像,因为我们没有缓存它。

    / # 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