docker默认安全配置的核心风险在于daemon.json中未审查的特权设置,如"privileged": true或"cap-add": ["all"]会默认赋予容器过高内核权限,必须通过"default-cap-drop": ["all"]、"no-new-privileges": true等显式约束实现最小权限。

直接看 Docker 的默认安全配置文件,核心是定位那些让容器获得过高内核权限的设置。关键不在“有没有配置”,而在于“哪些配置被默认启用却未被审查”——尤其是那些允许容器绕过内核隔离机制的选项。
查 daemon.json 中的特权与能力放行项
Docker 守护进程的主配置文件 /etc/docker/daemon.json 是起点。它控制所有容器的默认行为,包括是否默认开启危险能力。
- 运行
grep -E "(privileged|cap-add|security-opt)" /etc/docker/daemon.json,重点检查是否存在"default-ulimits"、"default-runtime"或显式"cap-add"条目 - 若发现
"privileged": true或"cap-add": ["ALL"],说明所有新容器默认拥有特权或全能力集,这是高危信号 - 即使没写
privileged,也要确认是否缺失"no-new-privileges": true——该选项能阻止容器内进程动态提权,但默认不启用
验证内核模块加载与命名空间共享配置
容器能否逃逸,常取决于它是否能操作内核模块或共享宿主机关键命名空间。这些控制点藏在 daemon 配置和运行时参数中。
- 检查是否禁用危险模块:执行
lsmod | grep -E "(kvm|hyperv|vboxguest)",若这些模块已加载且容器未被明确限制,攻击者可能利用其接口突破隔离 - 确认是否禁止共享敏感命名空间:在 daemon.json 中应包含
"default-runtime": "runc"(非 unconfined),并确保没有全局启用--pid=host、--network=host或--ipc=host - 查看实际运行的容器是否违规:运行
docker ps --format "{{.ID}}\t{{.Command}}" | head -5,再对每个 ID 执行docker inspect --format '{{.HostConfig.PidMode}} {{.HostConfig.NetworkMode}}' [ID],确认返回不是host
扫描镜像层与启动脚本中的隐性特权残留
很多特权不是来自 daemon 配置,而是固化在镜像里——比如构建时未清理的 SUID 文件、硬编码的 root 用户、或启动脚本中调用 mount 等系统调用。
- 对目标镜像执行
docker run --rm -it [镜像名] find / -perm -4000 -type f 2>/dev/null,列出所有 SUID 文件;重点关注/bin/mount、/usr/bin/newgrp等高风险二进制 - 检查 Dockerfile 是否含
USER root或完全缺失 USER 指令;若有,需重构镜像,添加RUN adduser -u 1001 -D appuser && chown -R appuser:appuser /app和USER appuser - 进入运行中容器执行
cat /proc/1/status | grep CapEff,将十六进制 Capability 掩码转为可读形式(如用 Pythoncapset.decode(0x0000003fffffffff)),确认是否保留了CAP_SYS_ADMIN、CAP_NET_ADMIN等高危能力
加固策略:从默认放行转向显式约束
修补的本质不是“关掉某个开关”,而是把所有权限设为显式拒绝,再按需白名单放行。
- 修改 daemon.json,强制最小能力集:
{ "default-cap-drop": ["ALL"], "default-cap-add": ["NET_BIND_SERVICE"], "no-new-privileges": true } - 重启守护进程:
systemctl restart docker,然后验证新启动的容器是否仍以非 root 用户运行、无 CAP_SYS_ADMIN、且无法挂载新文件系统 - 对存量容器,不建议热修复,应重建镜像:在 Dockerfile 开头加入
FROM <minimal-base></minimal-base>(如debian:slim或distroless),删除所有apt install中的sudo、passwd、util-linux等含 SUID 的包











