目标
加固不是阻止漏洞利用,而是决定攻击者得手之后能拿到什么。以 UID 10001 运行、根文件系统只读、能力清零,意味着被攻陷的进程只能读自己的代码、写两个 tmpfs 挂载。从这个起点上删掉的每一层,都是根本不可能发生的损害。
步骤要点
- Dockerfile 里建专用组与用户并 USER 10001:10001,被攻陷的进程在容器内也从零特权起步。
- 运行时 –read-only,仅为 /tmp 与 /app/cache 挂 noexec,nosuid 且限容的 tmpfs。
- Kubernetes 用 securityContext 声明同样约束:runAsNonRoot、readOnlyRootFilesystem、allowPrivilegeEscalation false、capabilities drop ALL。
- 验证即攻击:exec 进容器跑 id 与 touch /etc/passwd,应分别显示 uid 10001 与 Read-only file system。
- 再确认合法写入路径可用:touch /tmp/probe 成功说明白名单覆盖了真实需求。
排错提示
应用因写配置或日志崩溃说明写入路径是隐式的,逐个枚举并显式挂载,更好的方向是改环境变量配置加 stdout 日志;镜像里没有 useradd 工具就直接写数字形式的 USER,或换自带非 root 用户的基镜像;要绑低位端口就加回恰好 CAP_NET_BIND_SERVICE,而不是回退 root 运行。
适用边界
这些是容器层加固不是隔离保证,内核级逃逸仍需及时打补丁的宿主;只读根文件系统把状态推到挂载里,到处写文件的应用需要先重构。
代码示例
securityContext:
runAsNonRoot: true
runAsUser: 10001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]