核心是多层权限限制:以非root用户运行容器、drop所有capabilities后按需添加、禁止危险挂载与命名空间共享、启用seccomp等运行时安全策略。
核心思路是:不让容器进程拥有超出业务所需的权限,尤其要切断它接触宿主机关键资源的路径。权限限制不是单一配置,而是多层设防。
用非 root 用户运行容器
Dockerfile 中必须显式声明 USER 指令,指定一个低权限系统用户(如 www-data、appuser),而不是依赖默认的 root。这能确保即使应用被攻破,攻击者拿到的 shell 也受限于该用户的权限范围,无法直接修改 /etc、加载内核模块或写入关键目录。
- 避免在构建阶段和运行阶段混用 root:多阶段构建中,构建器可用 root,但最终镜像应 COPY 文件后立即切换 USER
- 用户需提前在镜像中创建,且 UID 不应为 0;建议使用数值 UID(如 USER 1001)避免与宿主机用户冲突
- 挂载卷时注意权限:若挂载宿主机目录,确保该目录对容器内非 root 用户可读/写(如用 chmod 755 或 chown 1001:1001)
禁用高危能力并最小化 Capabilities
Linux Capabilities 是比 root 更细粒度的权限控制。Docker 默认赋予容器大量 capabilities(如 CAP_SYS_ADMIN、CAP_NET_ADMIN),这些极易被用于逃逸。应主动 drop 所有,再按需 add 必需项。
- 启动容器时加 --cap-drop=ALL,然后仅添加必要能力,例如 --cap-add=NET_BIND_SERVICE(绑定 1024 以下端口)
- 绝对禁止 --privileged 模式;它等同于授予容器全部 capabilities + 宿主机设备访问权,是逃逸高发入口
- 敏感能力如 CAP_SYS_MODULE(加载内核模块)、CAP_SYS_PTRACE(调试其他进程)、CAP_SYS_RAWIO(直接 I/O)一律不添加
严格控制挂载与命名空间暴露
容器通过挂载宿主机路径或共享命名空间,可能绕过隔离边界。必须明确禁止所有非必要挂载,并关闭危险命名空间共享。
- 禁止挂载 /proc/sys、/sys/fs/cgroup、/var/run/docker.sock —— 尤其 docker.sock 是最常见逃逸跳板
- 避免使用 --network=host,它让容器共享宿主机网络命名空间,失去网络隔离
- 慎用 --pid=host、--ipc=host:它们分别共享进程和 IPC 命名空间,可能导致信息泄露或信号劫持
- 挂载宿主机路径时,始终加 :ro(只读)后缀,除非业务明确需要写入
启用运行时安全策略
seccomp、AppArmor 或 SELinux 可拦截危险系统调用,是逃逸的最后一道防线。推荐优先使用 seccomp,默认 profile 已过滤大量高风险调用。
- 启动容器时指定 --security-opt seccomp=/path/to/seccomp.json,使用 Docker 官方默认 profile 或定制精简版
- 如宿主机已启用 AppArmor,可通过 --security-opt apparmor=your-profile 加载限制策略
- 避免禁用:--security-opt seccomp=unconfined 或 --security-opt apparmor=unconfined 会完全关闭保护


















