高级配置选项

笔记

Mac、Linux 和 Windows (Hyper-V) 上的 Docker Desktop 版本 4.27(及更高版本)提供此功能。对于具有 WSL 2 的 Windows,此功能需要 Docker Desktop 4.28 及更高版本。

本页介绍启用 ECI 后的 ECI 可选高级配置。

Docker 套接字挂载权限

默认情况下,启用 ECI 后,Docker Desktop 不允许将 Docker Engine 套接字绑定挂载到容器中:

$ docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock docker:cli
docker: Error response from daemon: enhanced container isolation: docker socket mount denied for container with image "docker.io/library/docker"; image is not in the allowed list; if you wish to allow it, configure the docker socket image list in the Docker Desktop settings.

这可以防止恶意容器获得对 Docker 引擎的访问权限,因为此类访问可能允许它们执行供应链攻击(例如,构建恶意映像并将其推送到组织的存储库中)或类似攻击。

然而,一些合法的用例要求容器有权访问 Docker Engine 套接字。例如,流行的 Testcontainers 框架有时会将 Docker Engine 套接字绑定安装到容器中以管理它们或执行测试后清理。

从 Docker Desktop 4.27 开始,管理员可以选择配置 ECI,以允许将 Docker 引擎套接字绑定安装到容器中,但以受控方式。

这可以通过文件来完成admin-settings.json,如 设置管理中所述。例如:

{
  "configurationFileVersion": 2,
  "enhancedContainerIsolation": {
    "locked": true,
    "value": true,
    "dockerSocketMount": {
      "imageList": {
        "images": [
          "docker.io/localstack/localstack:*",
          "docker.io/testcontainers/ryuk:*",
          "docker:cli"
        ]
      },
      "commandList": {
        "type": "deny",
        "commands": ["push"]
      }
    }
  }
}

如上所示,有两种配置可以将 Docker 套接字绑定安装到容器中:imageListcommandList.这些将在下面描述。

图片列表

imageList是允许绑定安装 Docker 套接字的容器映像的列表。默认情况下,该列表为空(即,当启用 ECI 时,不允许任何容器绑定挂载 Docker 套接字)。但是,管理员可以使用以下任一格式将图像添加到列表中:

图像参考格式描述
<image_name>[:<tag>]图像的名称,带有可选标签。如果省略该标签,则:latest使用该标签。如果标签是通配符*,则表示“该图像的任何标签”。
<image_name>@<digest>图像的名称,带有特定的存储库摘要(例如,如 所报告的docker buildx imagetools inspect <image>)。这意味着仅允许与该名称和摘要匹配的图像。

镜像名称遵循标准约定,因此它可以指向任何注册表和存储库。

在上面的示例中,图像列表配置了三个图像:

"imageList": {
  "images": [
    "docker.io/localstack/localstack:*",
    "docker.io/testcontainers/ryuk:*",
    "docker:cli"
  ]
}

这意味着在启用 ECI 时,允许使用docker.io/localstack/localstackdocker.io/testcontainers/ryuk镜像(带有任何标签)或docker:cli 镜像的容器绑定挂载 Docker 套接字。因此,可以进行以下工作:

$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock docker:cli sh
/ #

提示

对您允许的图像进行限制,如 下面的建议中所述。

一般来说,使用标记通配符格式(例如<image-name>:*)指定图像更容易,因为imageList每当使用新版本的图像时都不需要更新。或者,您可以使用不可变标签(例如:latest),但它并不总是像通配符一样有效,因为例如,Testcontainers 使用图像的特定版本,不一定是最新版本。

启用 ECI 后,Docker Desktop 会定期从适当的注册表下载允许的映像的映像摘要并将其存储在内存中。然后,当使用 Docker 套接字绑定安装启动容器时,Docker Desktop 会检查容器的映像摘要是否与允许的摘要之一匹配。如果是,则允许容器启动,否则将被阻止。

请注意,由于上一段中提到的摘要比较,无法通过将不允许的映像重新标记为允许的映像的名称来绕过 Docker 套接字安装权限。换句话说,如果用户这样做:

$ docker image rm <allowed_image>
$ docker tag <disallowed_image> <allowed_image>
$ docker run -v /var/run/docker.sock:/var/run/docker.sock <allowed_image>

那么标记操作成功,但docker run命令失败,因为不允许的图像的图像摘要与存储库中允许的图像摘要不匹配。

命令列表

当启用 ECI 时,限制commandList容器可以通过绑定安装的 Docker 套接字发出的 Docker 命令。它充当补充安全机制imageList(即,像第二道防线)。

例如,假设imageList配置为允许映像docker:cli挂载 Docker 套接字,并使用它启动容器:

$ docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock sh
/ #

默认情况下,这允许容器通过该 Docker 套接字发出任何命令(例如,构建镜像并将其推送到组织的存储库),这通常是不可取的。

为了提高安全性,commandList可以配置为限制容器内的进程可以在绑定安装的 Docker 套接字上发出的命令。commandList可以根据您的偏好将其配置为“拒绝”列表(默认)或“允许”列表。

列表中的每个命令均按其名称指定,如报告所示docker --help(例如“ps”、“build”、“pull”、“push”等)。此外,允许使用以下命令通配符来阻止整个组命令数:

命令通配符描述
“容器*”指所有“docker 容器...”命令
“图像*”指所有“docker image ...”命令
“体积*”指所有“docker volume ...”命令
“网络*”指所有“docker network ...”命令
“建造*”指所有“docker build ...”命令
“系统*”指所有“docker system ...”命令

例如,以下配置会阻止Docker 套接字上的build和命令:push

"commandList": {
  "type": "deny",
  "commands": ["build", "push"]
}

因此,如果在容器内部,您在绑定安装的 Docker 套接字上发出这些命令中的任何一个,它们将被阻止:

/ # docker push myimage
Error response from daemon: enhanced container isolation: docker command "/v1.43/images/myimage/push?tag=latest" is blocked; if you wish to allow it, configure the docker socket command list in the Docker Desktop settings or admin-settings.

相似地:

/ # curl --unix-socket /var/run/docker.sock -XPOST http://localhost/v1.43/images/myimage/push?tag=latest
Error response from daemon: enhanced container isolation: docker command "/v1.43/images/myimage/push?tag=latest" is blocked; if you wish to allow it, configure the docker socket command list in the Docker Desktop settings or admin-settings.

请注意,如果commandList已配置为“允许”列表,则效果将相反:仅允许列出的命令。是否将该列表配置为允许列表或拒绝列表取决于用例。

建议

  • 限制允许绑定安装 Docker 套接字的容器映像列表(即imageList)。一般来说,只允许对绝对需要且您信任的图像执行此操作。

  • imageList 如果可能,请在(例如)中使用标记通配符格式<image_name>:*,因为这样就无需 admin-settings.json因图像标记更改而更新文件。

  • 在 中commandList,阻止您不希望容器执行的命令。例如,对于本地测试(例如,Testcontainers),绑定安装 Docker 套接字的容器通常会创建/运行/删除容器、卷和网络,但通常不会构建映像或将它们推送到存储库中(尽管有些可能合法)做这个)。允许或阻止哪些命令取决于用例。

    • 请注意,容器通过绑定安装的 Docker 套接字发出的所有“docker”命令也将在增强的容器隔离下执行(即,生成的容器使用 Linux 用户命名空间,敏感系统调用经过审查等)

注意事项和限制

  • 当 Docker Desktop 重新启动时,允许挂载 Docker 套接字的映像可能会被意外阻止。当远程存储库中的图像摘要发生更改(例如,更新了“:latest”图像)并且该图像的本地副本(例如,来自先前的docker pull)不再与远程存储库中的摘要匹配时,可能会发生这种情况。在这种情况下,请删除本地映像并再次拉取它(例如,docker rm <image>docker pull <image>)。

  • 不可能允许 Docker 套接字绑定安装到不在注册表上的映像(例如,本地构建但尚未推送到注册表的映像)。这是因为 Docker Desktop 从注册表中提取允许的映像的摘要,然后使用它与映像的本地副本进行比较。

  • commandList配置适用于所有允许绑定安装 Docker 套接字的容器。因此不能对每个容器进行不同的配置。

  • 尚不支持以下命令commandList

不支持的命令描述
撰写Docker组成
开发者Docker 开发环境
扩大管理 Docker 扩展
反馈向 Docker 发送反馈
在里面创建 Docker 相关的启动文件
显现管理 Docker 镜像清单
插件管理插件
斯博姆查看软件物料清单 (SBOM)
扫描码头扫描
侦察Docker Scout
相信管理对 Docker 镜像的信任

笔记

当运行“真正的”Docker-in-Docker 时(即在容器内运行 Docker 引擎时),Docker 套接字挂载权限不适用。在这种情况下,主机的 Docker 套接字不会绑定安装到容器中,因此容器不存在利用主机 Docker 引擎的配置和凭据来执行恶意活动的风险。增强的容器隔离能够安全地运行 Docker-in-Docker,而无需在 Docker 桌面虚拟机中授予外部容器真正的 root 权限。