实现容器权限最小化需先 drop all 能力,再按需 add 必要能力,并配套使用非 root 用户、只读文件系统和 no-new-privileges 三项措施,k8s 中须通过 securitycontext 正确配置并实操验证。
直接移除全部默认 capabilities 是实现容器权限最小化的关键一步,但不能只做这一步——必须配合非 root 用户、只读文件系统等措施,否则可能因缺失必要能力导致应用启动失败或功能异常。
明确目标:先 drop ALL,再按需 add
Linux Capabilities 是对传统 root 权限的精细化拆分。Docker 默认保留约 14 项(如 CAP_CHOWN、CAP_NET_BIND_SERVICE、CAP_SETUIDS 等),其中多数对普通应用无用,却可能被利用提权或逃逸。
安全加固的核心逻辑是:不信任默认配置,显式声明“只给真正需要的”。
- --cap-drop=ALL:彻底清空所有能力,是最强起点
- --cap-add=XXX:仅添加明确必需的能力,例如绑定 80/443 端口需 NET_BIND_SERVICE;需要挂载 tmpfs 可加 SETFCAP(极少见)
- 避免混用 --privileged 或 --cap-add=ALL,这两者会完全绕过能力控制
必须同步配置的三项配套措施
单独 drop capabilities 效果有限,攻击者仍可能通过 root 身份执行其他危险操作。以下三项需与之绑定使用:
- --user 1001:1001:强制以非 root 用户运行进程,防止利用 setuid 二进制或 /proc/self/exe 重写提权
- --read-only:根文件系统设为只读,阻断恶意写入、后门植入或日志覆盖行为
- --security-opt no-new-privileges:禁止进程通过 execve() 获取新权限,封堵 capability 动态提升路径
在 Kubernetes 中正确落地
K8s 不支持命令行参数,需通过 Pod SecurityContext 配置,且注意字段层级和兼容性:
- capabilities 必须写在 securityContext.capabilities 下,不是 container.securityContext
- drop 和 add 必须成对出现,不可只写其一(K8s 会拒绝校验)
- 示例片段:
runAsUser: 1001
runAsGroup: 1001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
验证是否生效的实操方法
不要依赖配置“写了就对了”,必须进入容器内验证实际效果:
- 运行容器后执行:docker exec -it
capsh --print ,确认输出中 Current: 行不含任何 capability(应显示 0x0000000000000000=) - 检查用户身份:whoami 和 id,确认 UID ≠ 0 且无 group 0
- 尝试敏感操作验证限制是否起效,例如:touch /tmp/test(若挂载了可写 volume 才能成功)、ip link add dummy0 type dummy(应报 Operation not permitted)











