Docker 守护进程(dockerd)以 root 权限运行并控制所有容器操作,通过 /etc/docker/daemon.json、TLS 证书、用户命名空间重映射和网络限制对其进行加固,是防止权限提升、横向移动和容器逃逸的关键。
适用场景
- 在环境中部署或配置 Docker 守护进程加固能力时
- 建立符合合规要求的安全控制时
- 构建或改进该领域的安全架构时
- 开展需要此实现的安全评估时
前提条件
- 已安装 Docker Engine 24.0+
- 对 Docker 主机拥有 root 或 sudo 权限
- 用于生成 TLS 证书的 OpenSSL
- 了解 Linux 命名空间与 cgroups
核心加固的 daemon.json (配置内容见官方资料,包括 icc、userns-remap、no-new-privileges、log-driver、storage-driver、live-restore、userland-proxy、default-ulimits、seccomp-profile、default-address-pools、iptables、ip-forward、ip-masq、experimental、metrics-addr、max-concurrent-downloads、max-concurrent-uploads、default-runtime、runtimes 等字段,此处不重复代码。)
逐项说明
- 禁用容器间通信(ICC):设置 "icc": false,阻止默认桥接网络上的容器互相通信,容器须使用显式 --link 或带发布端口的用户自定义网络。
- 启用用户命名空间重映射:"userns-remap": "default" 将容器 root(UID 0)映射到主机上的高编号非特权 UID,防止容器逃逸后在主机获得 root。可通过查看 /etc/subuid 与 /etc/subgid(如 dockremap:100000:65536)验证,运行 docker run --rm alpine id 时容器内显示 uid=0,但主机 UID 为 100000 以上。
- 禁用新权限提升:"no-new-privileges": true,防止容器进程通过 setuid/setgid 二进制或能力提升获得额外权限。
- 启用实时恢复:"live-restore": true,守护进程停机期间保持容器运行,支持升级守护进程而无需重启容器。
- 禁用用户态代理:"userland-proxy": false,使用 iptables 规则而非 docker-proxy 进行端口转发,减少攻击面并提升性能。
远程 Docker API 的 TLS 配置 生成 CA 与服务器证书(命令包括 openssl genrsa、openssl req、openssl x509 等,创建 ca-key.pem、ca.pem、server-key.pem、server.csr、server-cert.pem,并用 extfile 指定 SAN 与 serverAuth),生成客户端证书(key.pem、client.csr、cert.pem,extendedKeyUsage 为 clientAuth),设置权限(chmod 0400 对私钥,0444 对证书),将 ca.pem、server-cert.pem、server-key.pem 放入 /etc/docker/tls/。 在 daemon.json 中配置 TLS:"tls": true、"tlsverify": true、"tlscacert"、"tlscert"、"tlskey" 指向上述文件,hosts 包含 unix:///var/run/docker.sock 与 tcp://0.0.0.0:2376。 客户端连接示例:docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=tcp://docker-host:2376 version。
Docker 套接字保护
- 限制套接字所有权:chown root:docker /var/run/docker.sock,chmod 660 /var/run/docker.sock
- 审计套接字访问:auditctl -w /var/run/docker.sock -k docker-socket
- 切勿将 Docker 套接字挂载进容器(如 docker run -v /var/run/docker.sock:/var/run/docker.sock ... 属于不良做法)
无根 Docker 安装 rootless 脚本(curl -fsSL https://get.docker.com/rootless | sh),配置 PATH 与 DOCKER_HOST 环境变量,使用 systemctl --user start docker 与 enable 启动并启用无根守护进程,通过 docker info | grep -i rootless 验证(Rootless: true)。
内容信任(镜像签名) 设置 export DOCKER_CONTENT_TRUST=1 后,docker pull library/alpine:3.18 会在镜像未签名时失败;使用 docker trust sign myregistry/myapp:1.0 签名并推送镜像。
Seccomp 配置
- 查看默认 seccomp:docker info --format '{{.SecurityOptions}}'
- 使用自定义 seccomp:docker run --security-opt seccomp=/etc/docker/seccomp/custom.json alpine
- 验证:docker inspect --format='{{.HostConfig.SecurityOpt}}' container_name
AppArmor 配置
- 检查状态:aa-status
- 使用自定义配置:docker run --security-opt apparmor=docker-custom alpine
- 加载配置:apparmor_parser -r /etc/apparmor.d/docker-custom
验证命令
- 检查守护进程配置:docker info
- 验证 userns-remap:docker info --format '{{.SecurityOptions}}'
- 检查 ICC 设置:docker network inspect bridge --format '{{.Options}}'
- 使用 Docker Bench 审计:docker run --rm --net host --pid host -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc:ro docker/docker-bench-security
最佳实践
- 绝不在无 TLS 情况下暴露 Docker 守护进程,远程访问始终使用 --tlsverify
- 启用用户命名空间重映射,将容器 root 映射到非特权主机 UID
- 禁用 ICC,阻止默认桥接网络的容器间通信
- 尽可能使用无根模式,以非 root 运行 Docker 守护进程
- 启用内容信任,仅拉取已签名镜像
- 配置日志轮转,防止日志填满磁盘
- 使用 seccomp 配置限制容器可用的系统调用
- 审计 Docker 套接字,监控对 /var/run/docker.sock 的访问
- 定期运行 Docker Bench,自动化 CIS 基准检查
- 保持 Docker 更新,及时应用安全补丁