你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
注意
本文引用了 CentOS,这是一个处于生命周期结束 (EOL) 状态的 Linux 发行版。 请相应地考虑你的使用和规划。 有关详细信息,请参阅 CentOS 生命周期结束指南。
本文详细介绍适用于以下实现的 Docker 主机的配置设置:
- [预览版]:Linux 计算机应满足 Docker 主机的 Azure 安全基线要求
- Azure 安全中心应修复计算机上安全配置中的漏洞
有关详细信息,请参阅了解 Azure Policy 的来宾配置功能和 Azure 安全基准概述 (V2)。
常规安全控件
名称 (CCEID) |
详细信息 | 修正检查 |
---|---|---|
Docker 清单信息 (0.0) |
说明:无 | 无 |
确保已为容器创建单独的分区 (1.01) |
说明:Docker 依赖 /var/lib/docker 作为默认目录,所有与 Docker 相关的文件(包括映像)都存储在该目录中。 此目录可能会快速填满,很快 Docker 和主机可能会变得不可用。 因此,建议创建一个单独的分区(逻辑卷),用于存储 Docker 文件。 | 对于新安装,请为 /var/lib/docker 装入点创建一个单独的分区。 对于以前安装的系统,请使用逻辑卷管理器 (LVM) 创建分区。 |
确保 Docker 版本是最新版本 (1.03) |
说明:使用最新的 Docker 版本将确保主机的安全 | 按照 Docker 文档操作以升级版本 |
确保为 Docker 守护程序配置了审核 (1.05) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核 Docker 守护程序。 Docker 守护程序使用根目录特权运行。 因此,必须审核其活动和使用情况。 | 将行 -w /usr/bin/docker -k docker 添加到 /etc/audit/audit.rules 文件中。 然后,运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件和目录 (/var/lib/docker) 配置了审核 (1.06) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 /var/lib/docker 就是其中一个目录。 该目录包含有关容器的所有信息。 必须对其进行审核。 | 将行 -w /var/lib/docker -k docker 添加到 /etc/audit/audit.rules 文件中。 然后,运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件和目录 (/etc/docker) 配置了审核 (1.07) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 /etc/docker 就是其中一个目录。 该目录包含用于在 Docker 守护程序和 Docker 客户端之间进行 TLS 通信的各种证书和密钥。 必须对其进行审核。 | 将行 -w /etc/docker -k docker 添加到 /etc/audit/audit.rules 文件中。 然后,运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件 (docker.service) 和目录配置了审核 (1.08) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 Docker.service 就是其中一个文件。 如果管理员更改了守护程序参数,则可能存在 docker.service 文件。 该文件包含 Docker 守护程序的各种参数。 如果适用,必须对其进行审核。 | 运行以下命令以查找“docker.service”文件位置,并将行 -w {docker.service file location} -k docker 添加到 /etc/audit/audit.rules 文件中,其中 {docker.service file location} 是之前找到的文件路径:systemctl show -p FragmentPath docker.service 。 运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件 (docker.socket) 和目录配置了审核 (1.09) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 Docker.socket 就是其中一个文件。 该文件包含 Docker 守护程序套接字的各种参数。 如果适用,必须对其进行审核。 | 运行以下命令以查找“docker.socket”文件位置,并将行 -w {docker.socket file location} -k docker 添加到 /etc/audit/audit.rules 文件中,其中 {docker.socket file location} 是之前找到的文件路径:systemctl show -p FragmentPath docker.socket 。 运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件 (/etc/default/docker) 和目录配置了审核 (1.10) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 /etc/default/docker 就是其中一个文件。 该文件包含 Docker 守护程序的各种参数。 如果适用,必须对其进行审核。 | 将行 -w /etc/default/docker -k docker 添加到 /etc/audit/audit.rules 文件中。 然后,运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件 (/etc/docker/daemon.json) 和目录配置了审核 (1.11) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 /etc/docker/daemon.json 就是其中一个文件。 该文件包含 Docker 守护程序的各种参数。 如果适用,必须对其进行审核。 | 将行 -w /etc/docker/daemon.json -k docker 添加到 /etc/audit/audit.rules 文件中。 然后,运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件 (/usr/bin/docker-containerd) 和目录配置了审核 (1.12) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 /usr/bin/docker-containerd 就是其中一个文件。 Docker 现在依靠 containerd 和 runC 来生成容器。 如果适用,必须对其进行审核。 | 将行 -w /usr/bin/docker-containerd -k docker 添加到 /etc/audit/audit.rules 文件中。 然后,运行以下命令以重启审核守护程序:service auditd restart |
确保为 Docker 文件 (/usr/bin/docker-runc) 和目录配置了审核 (1.13) |
说明:除了审核常规 Linux 文件系统和系统调用外,还需审核所有与 Docker 相关的文件和目录。 Docker 守护程序使用根目录特权运行。 其行为取决于一些关键文件和目录。 /usr/bin/docker-runc 是其中一个文件。 Docker 现在依靠 containerd 和 runC 来生成容器。 如果适用,必须对其进行审核。 | 将行 -w /usr/bin/docker-runc -k docker 添加到 /etc/audit/audit.rules 文件中。 然后,运行以下命令以重启审核守护程序:service auditd restart |
确保默认网桥上容器之间的网络流量受到限制 (2.01) |
说明:默认网桥上的容器间通信将被禁用。 如果需要在同一主机上的容器之间进行任何通信,则需要使用容器链接显式定义它,或者必须定义自定义网络。 | 在守护程序模式下运行 Docker,并将 --icc=false 作为参数传递,或在 daemon.json 文件中将“icc”设置设置为 false。 此外,也可按照 Docker 文档创建自定义网络,并仅加入需要与该自定义网络通信的容器。 --icc 参数仅适用于默认 Docker 网桥,如果使用的是自定义网络,则应改为采用网络分段方法。 |
确保日志记录级别设置为“信息”。 (2.02) |
说明:设置适当的日志级别,将 Docker 守护程序配置为稍后要查看的日志事件。 info 及以上的基本日志级别将捕获除调试日志之外的所有日志。 除非需要,否则不应在 debug 日志级别运行 Docker 守护程序。 |
按如下所示运行 Docker 守护程序:dockerd --log-level info |
确保允许 Docker 对 iptables 进行更改 (2.03) |
说明:如果选择这样做,则 Docker 将永远不会对系统 iptables 规则进行更改。 如果允许这样做,Docker 服务器将根据为容器选择网络选项的方式自动对 iptables 进行所需的更改。 建议让 Docker 服务器自动对 iptables 进行更改,以避免出现可能阻碍容器间及容器与外界通信的网络错误配置。 此外,每次选择运行容器或修改网络选项时,它都会省去更新 iptable 的麻烦。 |
不要使用 --iptables=false 参数运行 Docker 守护程序。 例如,不要按如下所示启动 Docker 守护程序:dockerd --iptables=false |
确保使用安全的注册表 (2.04) |
说明:不应在生产环境中使用任何不安全的注册表。 不安全的注册表可能会被篡改,从而可能危及生产系统。 | 从 dockerd start 命令中删除 --insecure-registry 标志 |
Docker 守护程序不应使用“aufs”存储驱动程序 (2.05) |
说明:“aufs”存储驱动程序是最早的存储驱动程序。 它基于不太可能合并到主 Linux 内核中的 Linux 内核补丁集。 众所周知,aufs 驱动程序会导致一些严重的内核故障。 aufs 仅具有 Docker 提供的旧式支持。 最重要的是,在许多使用最新 Linux 内核的 Linux 发行版中,aufs 并非受支持的驱动程序 | 应将“aufs”存储驱动程序替换为其他存储驱动程序,建议使用“overlay2” |
确保为 Docker 守护程序配置了 TLS 身份验证 (2.06) |
说明:默认情况下,Docker 守护程序绑定到未联网的 Unix 套接字并使用 root 特权运行。 如果将默认的 Docker 守护程序绑定更改为 TCP 端口或任何其他 Unix 套接字,则有权访问该端口或套接字的任何人对 Docker 守护程序和主机系统都具有完整的访问权限。 因此,不应将 Docker 守护程序绑定到其他 IP/端口或 Unix 套接字。 如果必须通过网络套接字公开 Docker 守护程序,请为守护程序和 Docker Swarm API(如果使用)配置 TLS 身份验证。 这会将通过网络与 Docker 守护程序建立的连接限制为可通过 TLS 成功进行身份验证的有限数量的客户端。 |
按照 Docker 文档或其他参考资料中所述的步骤操作。 |
确保正确配置了默认 ulimits (2.07) |
说明:如果未正确设置 ulimits,则可能无法实现所需的资源控件,也可能会使系统不可用。 | 在守护程序模式下运行 Docker,并在环境中按需将 --default-ulimit 作为参数传递给相应的 ulimits。 此外,也可以通过在环境中使用 --ulimit 参数及其相应的 ulimits,根据需要为每个容器分别设置特定的资源限制。 |
启用用户命名空间支持 (2.08) |
说明:Docker 守护程序中的 Linux 内核用户命名空间支持为 Docker 主机系统提供了额外的安全性。 它允许容器具有唯一的用户和组 ID 范围,这些 ID 超出了主机系统使用的传统用户和组的范围。 例如,根用户将在容器内部具有预期的管理权限,但可以有效地映射到主机系统上的非特权 UID。 | 请查看 Docker 文档,了解可根据你的要求进行配置的各种方式。 步骤也可能会因平台而异 - 例如,在 Red Hat 上,无法自动创建子 UID 和子 GID 映射。 你必须创建自己的映射。 但是,概要步骤如下所示:步骤 1:确保文件 /etc/subuid 和 /etc/subgid 存在。touch /etc/subuid /etc/subgid 步骤 2:使用 --userns-remap 标志 dockerd --userns-remap=default 启动 Docker 守护程序 |
确保不更改基本设备大小(除非需要) (2.10) |
说明:增加基本设备大小可使所有将来的映像和容器具有新的基本设备大小,这可能会导致由于文件系统被过度分配或已满而遭受拒绝服务攻击。 | 除非需要,否则请从 dockerd start 命令中删除 --storage-opt dm.basesize 标志 |
确保启用了 Docker 客户端命令的授权 (2.11) |
说明:Docker 现成的授权模型要么授予全部权限,要么不授权。 任何有权访问 Docker 守护程序的用户均可运行任何 Docker 客户端命令。 对于使用 Docker 的远程 API 联系守护程序的调用方,也是如此。 如果你需要更精细的访问控制,则可以创建授权插件并将其添加到 Docker 守护程序配置。 通过使用授权插件,Docker 管理员可以配置精细的访问策略,用于管理对 Docker 守护程序的访问权限。 Docker 的第三方集成可以实现他们自己的授权模型,以要求在 Docker 的本机授权插件(即 Kubernetes、Cloud Foundry、OpenShift)之外使用 Docker 守护程序进行授权。 | 步骤 1:安装/创建授权插件。 步骤 2:根据需要配置授权策略。 步骤 3:按如下所示启动 Docker 守护程序:dockerd --authorization-plugin= |
确保配置了集中式和远程日志记录 (2.12) |
说明:集中式和远程日志记录可确保,在发生灾难性事件的情况下,所有重要的日志记录都是安全的。 Docker 现在支持各种此类日志记录驱动程序。 使用最适合你的环境的日志记录驱动程序。 | 步骤 1:按照其文档设置所需的日志驱动程序。 步骤 2:使用该日志记录驱动程序启动 Docker 守护程序。 例如 dockerd --log-driver=syslog --log-opt syslog-address=tcp://192.xxx.xxx.xxx |
确保实时还原处于“已启用”状态 (2.14) |
说明:重要的安全三要素之一是可用性。 在 Docker 守护程序中设置 --live-restore 标志可确保在 Docker 守护程序不可用时容器执行不会中断。 这也意味着现在可以更轻松地更新和修补 Docker 守护程序,而无需执行停机。 |
在守护程序模式下运行 Docker,并将 --live-restore 作为参数传递。 例如:dockerd --live-restore |
确保 Userland 代理处于“已禁用”状态 (2.15) |
说明:Docker 引擎提供了两种用于将端口从主机转发到容器的方法:回环 NAT 和 userland 代理。 在大多数情况下,首选回环 NAT 模式,因为它可提高性能并利用原生 Linux iptables 功能,而不是附加组件。 如果回环 NAT 可用,则应在启动时禁用 userland 代理,以减少安装时的攻击面。 | 按如下所示运行 Docker 守护程序:dockerd --userland-proxy=false |
确保在生产环境中避免实验性功能 (2.17) |
说明:实验性现在是运行时 Docker 守护程序标志,而不是单独的生成。 将 --experimental 作为运行时标志传递给 Docker 守护程序,并激活实验性功能。 现已将实验性视为稳定版本,但有一些功能可能尚未经过测试,无法保证 API 的稳定性。 |
不要将 --experimental 作为运行时参数传递给 Docker 守护程序。 |
确保容器受到限制,无法获取新特权。 (2.18) |
说明:进程可在内核中设置 no_new_priv 位。 它在分支、克隆和执行中持续存在。 no_new_priv 位可确保进程或其子进程不会通过 suid 或 sgid 位获得任何其他特权。 这样一来,许多不安全的操作变得更加安全了,因为不可能破坏特权二进制文件。 在守护程序级别设置此项,这可确保在默认情况下所有新容器都将受到限制,无法获取新特权。 |
按如下所示运行 Docker 守护程序:dockerd --no-new-privileges |
确保将 docker.service 文件所有权设置为 root:root。 (3.01) |
说明:docker.service 文件包含可能更改 Docker 守护程序行为的敏感参数。 因此,该文件应该由 root 拥有并由组拥有,以保持文件的完整性。 |
步骤 1: 了解文件位置: systemctl show -p FragmentPath docker.service 步骤 2: 如果文件不存在,则此建议不适用。 如果该文件存在,请使用正确的文件路径执行以下命令,将文件的所有权和组所有权设置为 root 。 例如 chown root:root /usr/lib/systemd/system/docker.service |
确保将 docker .service 文件权限设置为 644 或更严格 (3.02) |
说明:docker.service 文件包含可能更改 Docker 守护程序行为的敏感参数。 因此,该文件不应由除了 root 之外的任何其他用户写入,以保持文件的完整性。 |
步骤 1: 了解文件位置: systemctl show -p FragmentPath docker.service 步骤 2: 如果文件不存在,则此建议不适用。 如果该文件存在,请使用正确的文件路径执行以下命令,将文件权限设置为 644 。 例如 chmod 644 /usr/lib/systemd/system/docker.service |
确保将 docker.socket 文件所有权设置为 root:root。 (3.03) |
说明:docker.socket 文件包含可能更改 Docker 远程 API 行为的敏感参数。 因此,该文件应该由 root 拥有并由组拥有,以保持文件的完整性。 |
步骤 1: 了解文件位置: systemctl show -p FragmentPath docker.socket 步骤 2: 如果文件不存在,则此建议不适用。 如果该文件存在,请使用正确的文件路径执行以下命令,将文件的所有权和组所有权设置为 root 。 例如 chown root:root /usr/lib/systemd/system/docker.socket |
确保将 docker.socket 文件权限设置为 644 或更严格(3.04) |
说明:docker.socket 文件包含可能更改 Docker 守护程序行为的敏感参数。 因此,该文件不应由除了 root 之外的任何其他用户写入,以保持文件的完整性。 |
步骤 1: 了解文件位置: systemctl show -p FragmentPath docker.socket 步骤 2: 如果文件不存在,则此建议不适用。 如果该文件存在,请使用正确的文件路径执行以下命令,将文件权限设置为 644 。 例如 chmod 644 /usr/lib/systemd/system/docker.service |
确保将 /etc/docker 目录的所有权设置为 root:root 。(3.05) |
说明:/etc/docker 目录不仅各种敏感文件,还包含证书和密钥。 因此,该目录应该由 root 拥有并由组拥有,以保持目录的完整性。 |
chown root:root /etc/docker 这会将目录的所有权和组所有权设置为 root 。 |
确保将 /etc/docker 目录权限设置为 755 或更严格(3.06) |
说明:/etc/docker 目录不仅各种敏感文件,还包含证书和密钥。 因此,该目录只能由 root 写入,以保持目录的完整性。 |
chmod 755 /etc/docker 这会将目录的权限设置为 755 。 |
确保将注册表证书文件所有权设置为 root:root (3.07) |
说明:/etc/docker/certs.d/ 目录包含 Docker 注册表证书。 这些证书文件必须由 root 拥有并由组拥有,以保持证书的完整性。 |
chown root:root /etc/docker/certs.d//* 这会将注册表证书文件的所有权和组所有权设置为 root 。 |
确保将注册表证书文件权限设置为 444 或更严格(3.08) |
说明:/etc/docker/certs.d/ 目录包含 Docker 注册表证书。 这些证书文件必须具有 444 权限才能保持证书的完整性。 |
chmod 444 /etc/docker/certs.d//* 这会将注册表证书文件的权限设置为 444 。 |
确保将 TLS CA 证书文件所有权设置为 root:root (3.09) |
说明:应保护 TLS CA 证书文件免受任何篡改。 该文件用于基于给定的 CA 证书对 Docker 服务器进行身份验证。 因此,该文件必须由 root 拥有并由组拥有,以保持 CA 证书的完整性。 |
chown root:root 这会将 TLS CA 证书文件的所有权和组所有权设置为 root 。 |
确保将 TLS CA 证书文件权限设置为 444 或更严格(3.10) |
说明:应保护 TLS CA 证书文件免受任何篡改。 该文件用于基于给定的 CA 证书对 Docker 服务器进行身份验证。 因此,该文件必须具有 444 权限才能保持 CA 证书的完整性。 |
chmod 444 这会将 TLS CA 文件的文件权限设置为 444 。 |
确保将 Docker 服务器证书文件所有权设置为 root:root (3.11) |
说明:应保护 Docker 服务器证书文件免受任何篡改。 该文件用于基于给定的服务器证书对 Docker 服务器进行身份验证。 因此,该文件必须由 root 拥有并由组拥有,以保持证书的完整性。 |
chown root:root 这会将 Docker 服务器证书文件的所有权和组所有权设置为 root 。 |
确保将 Docker 服务器证书文件权限设置为 444 或更严格(3.12) |
说明:应保护 Docker 服务器证书文件免受任何篡改。 该文件用于基于给定的服务器证书对 Docker 服务器进行身份验证。 因此,该文件必须具有 444 权限才能保持证书的完整性。 |
chmod 444 这会将 Docker 服务器文件的文件权限设置为 444 。 |
确保将 Docker 服务器证书密钥文件所有权设置为 root:root (3.13) |
说明:应保护 Docker 服务器证书密钥文件免受任何篡改或不必要的读取。 该文件包含 Docker 服务器证书的私钥。 因此,该文件必须由 root 拥有并由组拥有,以保持 Docker 服务器证书的完整性。 |
chown root:root 这会将 Docker 服务器证书密钥文件的所有权和组所有权设置为 root 。 |
确保将 Docker 服务器证书密钥文件权限设置为 400 (3.14) |
说明:应保护 Docker 服务器证书密钥文件免受任何篡改或不必要的读取。 该文件包含 Docker 服务器证书的私钥。 因此,该文件必须具有 400 权限才能保持 Docker 服务器证书的完整性。 |
chmod 400 这会将 Docker 服务器证书密钥文件权限设置为 400 。 |
确保将 Docker 套接字文件所有权设置为 root:docker (3.15) |
说明:Docker 守护程序作为 root 运行。 因此,默认的 Unix 套接字必须由 root 所有。 如果任何其他用户或进程拥有此套接字,则该非特权用户或进程可以与 Docker 守护程序进行交互。 此外,此类非特权用户或进程可能会与容器进行交互。 此行为既不安全,也非必需。 此外,Docker 安装程序将创建名为 docker 的 Unix 组。 将用户添加到该组后,这些用户将能够读取和写入默认的 Docker Unix 套接字。 docker 组的成员身份由系统管理员严格控制。 如果任何其他组拥有此套接字,则该组的成员可以与 Docker 守护程序进行交互。 此外,此类组可能不像 docker 组那样受到严格控制。 此行为既不安全,也非必需。 因此,默认的 Docker Unix 套接字文件必须由 root 拥有并由 docker 组拥有,以保持套接字文件的完整性。 |
chown root:docker /var/run/docker.sock 这会将默认 Docker 套接字文件的所有权设置为 root 并将组所有权设置为 docker 。 |
确保将 Docker 套接字文件权限设置为 660 或更严格(3.16) |
说明:仅允许 root 和 docker 组的成员读取和写入默认的 Docker Unix 套接字。 因此,Docket 套接字文件必须具有 660 或更严格的权限。 |
chmod 660 /var/run/docker.sock 这会将 Docker 套接字文件的文件权限设置为 660 。 |
确保将 daemon.json 文件所有权设置为 root:root (3.17) |
说明:daemon.json 文件包含可能更改 Docker 守护程序行为的敏感参数。 因此,该文件应该由 root 拥有并由组拥有,以保持文件的完整性。 |
chown root:root /etc/docker/daemon.json 这会将文件的所有权和组所有权设置为 root 。 |
确保将 daemon.json 文件权限设置为 644 或更严格 (3.18) |
说明:daemon.json 文件包含可能更改 Docker 守护程序行为的敏感参数。 因此,该文件只能由 root 写入,以保持文件的完整性。 |
chmod 644 /etc/docker/daemon.json 这会将该文件的文件权限设置为 644 。 |
确保将 /etc/default/docker 文件所有权设置为 root:root (3.19) |
说明:/etc/default/docker 文件包含可能更改 Docker 守护程序行为的敏感参数。 因此,该文件应该由 root 拥有并由组拥有,以保持文件的完整性。 |
chown root:root /etc/default/docker 这会将文件的所有权和组所有权设置为 root 。 |
确保将 /etc/default/docker 文件权限设置为 644 或更严格 (3.20) |
说明:/etc/default/docker 文件包含可能更改 Docker 守护程序行为的敏感参数。 因此,该文件只能由 root 写入,以保持文件的完整性。 |
chmod 644 /etc/default/docker 这会将该文件的文件权限设置为 644 。 |
确保已创建容器的用户 (4.01) |
说明:如果可能,最好以非根用户身份运行容器。 虽然用户命名空间映射现已可用,但如果已在容器映像中定义了用户,则容器默认以该用户身份运行,并且不需要特定的用户命名空间重新映射。 | 确保容器映像的 Dockerfile 包含 USER {username or ID} ,其中用户名或 ID 是指可在容器基础映像中找到的用户。 如果在容器基础映像中没有创建特定用户,需在 USER 指令前面添加用于添加特定用户的 useradd 命令。 |
确保已将 HEALTHCHECK 指令添加到容器映像中 (4.06) |
说明:重要的安全三要素之一是可用性。 将 HEALTHCHECK 指令添加到容器映像中,这可确保 Docker 引擎根据该指令定期检查正在运行的容器实例,以确保实例仍在工作。 基于报告的运行状况状态,随后 Docker 引擎可以退出非工作容器并实例化新容器。 |
遵循 Docker 文档,并使用 HEALTHCHECK 指令重新生成容器映像。 |
确保根据需要启用 SELinux 或 AppArmor (5.01-2) |
说明:AppArmor 通过强制实施安全策略(也称为 AppArmor 配置文件)来保护 Linux OS 和应用程序免受各种威胁。 可为容器创建自己的 AppArmor 配置文件,也可使用 Docker 的默认 AppArmor 配置文件。 这将在配置文件中定义的容器上强制实施安全策略。 SELinux 提供了一个强制访问控制 (MAC) 系统,该系统可极大地增强默认的自由访问控制 (DAC) 模型。 因此,可通过在 Linux 主机上启用 SELinux(如果适用)来添加额外的安全性。 | 为发行版启用相关的强制访问控制插件后,将 Docker 守护程序作为 docker run --interactive --tty --security-opt="apparmor:PROFILENAME" centos /bin/bash (对于 AppArmor)或 docker run --interactive --tty --security-opt label=level:TopSecret centos /bin/bash (对于 SELinux)运行。 |
确保 Linux 内核功能在容器内受到限制 (5.03) |
说明:Docker 支持添加和删除功能,并允许使用非默认配置文件。 这可能会通过删除功能使 Docker 更安全,或者通过添加功能来降低安全性。 因此,建议删除除容器进程显式需要的功能之外的所有功能。 例如,容器进程通常不需要以下功能:NET_ADMIN SYS_ADMIN SYS_MODULE |
执行以下命令以添加所需的功能(例如 docker run --interactive --tty --cap-add={"NET_ADMIN","SYS_ADMIN"} centos:latest /bin/bash ):$> docker run --cap-add={"Capability 1","Capability 2"} 。执行以下命令以删除不需要的功能(例如 docker run --interactive --tty --cap-drop={"SETUID","SETGID"} centos:latest /bin/bash ):$> docker run --cap-drop={"Capability 1","Capability 2"} 。此外,你也可以选择删除所有功能并仅添加所需的功能(例如 docker run --interactive --tty --cap-drop=all --cap-add={"NET_ADMIN","SYS_ADMIN"} centos:latest /bin/bash ):$> docker run --cap-drop=all --cap-add={"Capability 1","Capability 2"} |
确保不使用特权容器 (5.04) |
说明:--privileged 标志为容器提供了所有功能,它还解除了设备 cgroup 控制器强制实施的所有限制。 也就是说,容器几乎可以执行主机可执行的所有操作。 存在此标志以允许特殊用例,例如在 Docker 中运行 Docker。 |
不要运行带有 --privileged 标志的容器。 例如,不要按如下所示启动容器:docker run --interactive --tty --privileged centos /bin/bash |
确保没有在容器上装载敏感的主机系统目录 (5.05) |
说明:如果敏感目录是以读写模式装载的,则可以对这些敏感目录中的文件进行更改。 这些更改可能会减少安全隐患或使 Docker 主机处于被盗用状态的不必要更改。 | 不要在容器上装载主机敏感目录,尤其是在读写模式下。 |
确保主机的网络命名空间不共享 (5.09) |
说明:这可能具有潜在危险。 它允许容器进程像任何其他 root 进程一样打开低编号的端口。 它还允许容器访问 Docker 主机上的 D-bus 等网络服务。 因此,容器进程可能会执行一些意外的操作,例如关闭 Docker 主机。 不应使用此选项。 |
启动容器时,不要跳过 --net=host 选项。 |
确保容器的内存使用情况受到限制 (5.10) |
说明:默认情况下,容器可以使用主机上的所有内存。 可使用内存限制机制来防止由于一个容器消耗了主机的所有资源而导致的拒绝服务,从而使同一主机上的其他容器无法执行其预期功能。 如果对内存没有限制,这可能会导致一个容器很容易使整个系统不稳定并因此不可用的问题。 | 仅使用所需内存量运行容器。 始终使用 --memory 参数运行容器。 例如,可以按如下所示运行容器:docker run --interactive --tty --memory 256m centos /bin/bash 。在上述示例中,该容器启动时的内存限制为 256 MB。 注意:请注意,如果内存限制到位,以下命令的输出将以科学记数法返回值。 docker inspect --format='{{.Config.Memory}}' 7c5a2d4c7fe0 例如,如果上述容器实例的内存限制设置为 256 MB ,则上述命令的输出将为 2.68435456e+08 而不是 256m。 你应该使用科学计算器或编程方法转换此值。 |
确保容器的根文件系统是以只读方式装载的 (5.12) |
说明:启用此选项后,将强制容器在运行时显式定义其数据写入策略,以持久保存或不持久保存其数据。 这也可减少安全攻击途径,因为容器实例的文件系统不能被篡改或写入,除非它对其文件系统文件夹和目录具有显式的读写权限。 | 在容器的运行时添加 --read-only 标志,以强制将容器的根文件系统装载为只读。docker run --read-only 管理员应使用在容器运行时启用 --read-only 选项,以强制容器的可执行进程在容器运行时期间仅将容器数据写入显式存储位置。 在容器运行时期间,显式存储位置的示例包括但不限于:1. 使用 --tmpfs 选项装载临时文件系统,以进行非持久性数据写入。 docker run --interactive --tty --read-only --tmpfs "/run" --tmpfs "/tmp" centos /bin/bash 2. 在容器运行时启用 Docker rw 装载,以将容器数据直接持久保存在 Docker 主机文件系统上。 docker run --interactive --tty --read-only -v /opt/app/data:/run/app/data:rw centos /bin/bash 3. 利用 Docker 共享存储卷插件为 Docker 数据卷持久保存容器数据。 docker volume create -d convoy --opt o=size=20GB my-named-volume``````docker run --interactive --tty --read-only -v my-named-volume:/run/app/data centos /bin/bash 4. 在容器运行时期间,将容器数据传输到 Docker 外部,以便持久保存容器数据。 示例包括托管数据库、网络文件共享和 API。 |
确保将传入的容器流量绑定到特定的主机接口 (5.13) |
说明:如果主机上有多个网络接口,则容器可以接受任何网络接口上已公开端口上的连接。 此操作并非必需,也可能不受保护。 很多时候,特定的接口在外部公开,各种服务(例如入侵检测、入侵防御、防火墙、负载均衡等)在这些接口上运行,以屏蔽传入的公共流量。 因此,不应接受任何接口上的传入连接。 应仅允许来自特定外部接口的传入连接。 | 将容器端口绑定到所需主机端口上的特定主机接口。 例如,docker run --detach --publish 10.2.3.4:49153:80 nginx 。在上面的示例中,容器端口 80 绑定到 49153 上的主机端口,并且仅接受来自 10.2.3.4 外部接口的传入连接。 |
确保将“故障时”容器重启策略设置为“5”或更低 (5.14) |
说明:如果你无限期地尝试启动容器,这可能会导致主机遭受拒绝服务攻击。 执行分布式拒绝服务攻击可能是一种简单的方法,尤其是当同一主机上有多个容器时。 此外,忽略容器的退出状态并 always 尝试重启容器,这将导致无法调查容器终止背后的根本原因。 如果容器被终止,应调查其背后的原因,而不是仅仅尝试无限期地对其进行重启。 因此,建议使用 on-failure 重启策略并将其限制为最多 5 次重启尝试。 |
如需自行重启容器,例如,可以按如下所示启动容器:docker run --detach --restart=on-failure:5 nginx |
确保主机的进程命名空间不共享 (5.15) |
说明:PID 命名空间提供进程分离。 PID 命名空间将删除系统进程的视图,并允许重用进程 ID,包括 PID 1 。 如果主机的 PID 命名空间与容器共享,则基本上允许容器内的进程查看主机系统上的所有进程。 这可削减主机和容器之间的进程级隔离带来的好处。 有权访问容器的用户最终将知道主机系统上运行的所有进程,甚至可以在容器内终止主机系统进程。 这可能会引发灾难性事件。 因此,不要与容器共享主机的进程命名空间。 |
不要使用 --pid=host 参数启动容器。 例如,不要按如下所示启动容器:docker run --interactive --tty --pid=host centos /bin/bash |
确保主机的 IPC 命名空间不共享 (5.16) |
说明:IPC 命名空间提供主机和容器之间的 IPC 分离。 如果主机的 IPC 命名空间与容器共享,则基本上允许容器内的进程查看主机系统上的所有 IPC。 这可削减主机和容器之间的 IPC 级别隔离带来的好处。 有权访问容器的用户最终可以操作主机 IPC。 这可能会引发灾难性事件。 因此,不要与容器共享主机的 IPC 命名空间。 | 不要使用 --ipc=host 参数启动容器。 例如,不要按如下所示启动容器:docker run --interactive --tty --ipc=host centos /bin/bas |
确保不会将主机设备直接公开给容器 (5.17) |
说明:此选项 --device 向容器公开主机设备,因此容器可以直接访问此类主机设备。 容器无需在 privileged 模式下运行,即可访问和操作主机设备。 默认情况下,容器将能够读取、写入和 mknod 这些设备。 此外,容器还可以从主机中删除成组设备。 因此,不要将主机设备直接公开给容器。 如果要将主机设备公开给容器,请适当地使用共享权限:- r - read only - w - writable - m - mknod allowed |
不要将主机设备直接公开给容器。 如果要将主机设备公开给容器,请使用正确的权限集:例如,不要按如下所示启动容器:docker run --interactive --tty --device=/dev/tty0:/dev/tty0:rwm --device=/dev/temp_sda:/dev/temp_sda:rwm centos bash 。例如,使用正确的权限共享主机设备:docker run --interactive --tty --device=/dev/tty0:/dev/tty0:rw --device=/dev/temp_sda:/dev/temp_sda:r centos bash |
确保挂载传播模式未设置为共享 (5.19) |
说明:共享装载将在所有装载处复制,并且在任何装入点所做的更改都将传播到所有装载。 如果在共享模式下装载卷,将不会限制任何其他容器装载和更改该卷。 如果安装的卷对所做的更改很敏感,这可能会引发灾难性事件。 除非需要,否则不要将装载传播模式设置为共享。 | 不要在共享模式传播中装载卷。 例如,不要按如下所示启动容器:docker run --volume=/hostPath:/containerPath:shared |
确保主机的 UTS 命名空间不共享 (5.20) |
说明:与主机共享 UTS 命名空间,这为容器提供了更改主机的主机名的完整权限。 此行为不安全,不应该被允许。 | 不要使用 --uts=host 参数启动容器。 例如,不要按如下所示启动容器:docker run --rm --interactive --tty --uts=host rhel7.2 |
确保确认了 cgroup 使用情况 (5.24) |
说明:系统管理员通常会定义应在其中运行容器的 cgroup。 即使系统管理员没有显式定义 cgroup,容器也默认在 docker cgroup 下运行。 在运行时,可以附加到与所需使用的 cgroup 不同的 cgroup。 应监视和确认此使用情况。 通过附加到与所需 cgroup 不同的 cgroup,可能会向容器授予过多的权限和资源,因此可能会被证明是不安全的。 |
除非需要,否则不要在 docker run 命令中使用 --cgroup-parent 选项。 |
确保容器受到限制,无法获取其他权限 (5.25) |
说明:进程可在内核中设置 no_new_priv 位。 它在分支、克隆和执行中持续存在。 no_new_priv 位可确保进程或其子进程不会通过 suid 或 sgid 位获得任何其他特权。 这样一来,许多不安全的操作变得更加安全了,因为不可能破坏特权二进制文件。 |
例如,应按如下所示启动容器:docker run --rm -it --security-opt=no-new-privileges ubuntu bash |
确保在运行时检查了容器运行状况 (5.26) |
说明:重要的安全三要素之一是可用性。 如果所使用的容器映像没有预定义的 HEALTHCHECK 指令,请使用 --health-cmd 参数在运行时检查容器运行状况。 基于报告的运行状况状态,可执行必要的操作。 |
使用 --health-cmd 和其他参数运行容器。 例如 docker run -d --health-cmd='stat /etc/passwd || exit 1' nginx |
确保使用了 PIDs cgroup 限制 (5.28) |
说明:攻击者可以在容器内使用单个命令引爆 fork 炸弹。 此 fork 炸弹可以使整个系统故障,需要重启主机才能使系统再次正常运行。 PIDs cgroup --pids-limit 将通过限制在给定时间内在容器内部可能发生的分支数量来防止此类攻击。 |
在使用适当的值启动容器时,请使用 --pids-limit 标志。 例如,docker run -it --pids-limit 100 。在上面的示例中,允许在任何给定时间内运行的进程数设置为 100。 在达到 100 个并发运行进程的限制后,Docker 将限制任何新进程的创建。 |
确保不使用 Docker 的默认网桥 docker0 (5.29) |
说明:Docker 将在桥接模式下创建的虚拟接口连接到名为 docker0 的通用网桥。 由于没有应用筛选,因此此默认网络模型很容易遭到 ARP 欺骗和 MAC 淹没攻击。 |
遵循 Docker 文档并设置用户定义的网络。 运行定义网络中的所有容器。 |
确保主机的用户命名空间不共享 (5.30) |
说明:用户命名空间可确保将容器内的根进程映射到容器外的非根进程。 因此,如果与容器共享主机的用户命名空间,这不会将主机上的用户与容器上的用户隔离开来。 | 不要在主机和容器之间共享用户命名空间。 例如,不要按如下所示运行容器:docker run --rm -it --userns=host ubuntu bash |
确保 Docker 套接字未装载到任何容器中 (5.31) |
说明:如果 Docker 套接字装载到了容器中,它将允许容器内运行的进程执行 Docker 命令,从而有效地对主机进行完全掌控。 | 确保没有容器作为卷装载 docker.sock 。 |
确保将 Swarm 服务绑定到了特定的主机接口 (7.03) |
说明:初始化 Swarm 时,--listen-addr 标志的默认值为 0.0.0.0:2377 ,这意味着 swarm 服务将侦听主机上的所有接口。 如果主机具有多个网络接口,则不建议这样做,因为它可能会将 Docker Swarm 服务公开给不参与 Swarm 操作的网络。 通过将特定的 IP 地址传递给 --listen-addr ,可以指定特定的网络接口以限制此公开。 |
对此操作的修正需要重新初始化为 --listen-addr 参数指定特定接口的 Swarm。 |
确保容器之间交换的数据在覆盖网络上的不同节点上进行加密 (7.04) |
说明:默认情况下,在覆盖网络上的不同节点上的容器之间交换的数据未加密。 这可能会公开容器节点之间的流量。 | 使用 --opt encrypted 标志创建覆盖网络。 |
确保 Swarm 管理器在自动锁定模式下运行 (7.06) |
说明:当 Docker 重新启动时,用于加密 Swarm 节点之间通信的 TLS 密钥以及用于加密和解密磁盘上的 Raft 日志的密钥均加载到每个管理器节点的内存中。 你应该保护双向 TLS 加密密钥以及用于静态加密和解密 Raft 日志的密钥。 可通过使用 --autolock 标志初始化 Swarm 来启用此保护。 启用 --autolock 后,当 Docker 重新启动时,必须先解锁 Swarm,使用在初始化 Swarm 时由 Docker 生成的密钥加密密钥。 |
如果正在初始化 Swarm,请使用以下命令: docker swarm init --autolock 。如果要在现有的 Swarm 管理器节点上设置 --autolock ,请使用以下命令:docker swarm update --autolock |
注意
Azure Policy 来宾配置设置的具体可用情况在 Azure 政府和其他国家云中可能会有所不同。
后续步骤
有关 Azure Policy 和来宾配置的其他文章:
- [了解 Azure Policy 的来宾配置功能]了解 Azure Policy 的来宾配置功能 ((../../machine-configuration/overview.md)。
- 法规符合性概述。
- 在 Azure Policy 示例中查看其他示例。
- 查看了解策略效果。
- 了解如何修正不符合的资源。