← 中文资源

简体中文版本

用非 root 用户与只读根文件系统加固基础镜像

以专用 UID 运行容器、根文件系统只读、必要时挂 tmpfs、默认丢弃能力,并用越权尝试验证。

阅读英文原文

目标

加固不是阻止漏洞利用,而是决定攻击者得手之后能拿到什么。以 UID 10001 运行、根文件系统只读、能力清零,意味着被攻陷的进程只能读自己的代码、写两个 tmpfs 挂载。从这个起点上删掉的每一层,都是根本不可能发生的损害。

步骤要点

  1. Dockerfile 里建专用组与用户并 USER 10001:10001,被攻陷的进程在容器内也从零特权起步。
  2. 运行时 –read-only,仅为 /tmp 与 /app/cache 挂 noexec,nosuid 且限容的 tmpfs。
  3. Kubernetes 用 securityContext 声明同样约束:runAsNonRoot、readOnlyRootFilesystem、allowPrivilegeEscalation false、capabilities drop ALL。
  4. 验证即攻击:exec 进容器跑 id 与 touch /etc/passwd,应分别显示 uid 10001 与 Read-only file system。
  5. 再确认合法写入路径可用:touch /tmp/probe 成功说明白名单覆盖了真实需求。

排错提示

应用因写配置或日志崩溃说明写入路径是隐式的,逐个枚举并显式挂载,更好的方向是改环境变量配置加 stdout 日志;镜像里没有 useradd 工具就直接写数字形式的 USER,或换自带非 root 用户的基镜像;要绑低位端口就加回恰好 CAP_NET_BIND_SERVICE,而不是回退 root 运行。

适用边界

这些是容器层加固不是隔离保证,内核级逃逸仍需及时打补丁的宿主;只读根文件系统把状态推到挂载里,到处写文件的应用需要先重构。

代码示例

securityContext:
  runAsNonRoot: true
  runAsUser: 10001
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]