解释 `privileged` 容器如何导致宿主机逃逸

解读

面试官想确认你对 Linux Capabilities、Namespace 隔离边界以及 Docker 安全模型的理解深度,并判断你是否具备在生产环境权衡“方便”与“安全”的能力。回答时要从内核机制层面讲清“为什么放开特权就能逃逸”,再给出国内可落地的加固方案,避免空谈。

知识点

  1. Linux Capabilities:细粒度划分 root 权限,Docker 默认只给 14 项危险能力,而 --privileged 一次性赋予全部 37 项。
  2. Namespace 隔离缺陷--privileged 会自动挂载宿主所有设备文件--device= 的通配版),导致容器进程能看到 /dev/sda/dev/mem 等。
  3. cgroups 逃逸:特权容器可写 /sys/fs/cgroup 下的 release_agent,在宿主机侧执行任意命令。
  4. 内核漏洞利用:一旦拿到 CAP_SYS_MODULE,可 insmod 加载恶意 ko,直接获得宿主机 root。
  5. 国内合规要求:等保 2.0 三级以上明确要求“容器平台应关闭或限制特权容器”,面试时提到等保可加分。

答案

--privileged 关闭了三条核心防线,使容器进程与宿主机进程几乎等价:

  1. Capabilities 防线:默认白名单被清空,容器获得全部 37 项 Cap,包括 CAP_SYS_ADMINCAP_SYS_MODULECAP_DAC_READ_SEARCH 等高危权限。
  2. 设备隔离防线:Docker 会把宿主 /dev 下的所有设备挂载到容器,攻击者可直接读写宿主机磁盘 /dev/sda/dev/mem,修改宿主机文件或注入恶意代码。
  3. 内核接口防线:特权容器可重新挂载 /proc/sys 为读写,结合 CAP_SYS_MODULE 加载内核模块,触发本地提权漏洞(如国内去年爆发的 CVE-2022-0847 DirtyPipe)。

经典逃逸步骤

  1. 在容器内执行 fdisk -l 发现宿主磁盘 /dev/sda1
  2. mkdir /tmp/h && mount /dev/sda1 /tmp/h,把宿主机根目录挂进容器;
  3. 写入 crontab/root/.ssh/authorized_keys,实现宿主 root 权限反弹。

国内生产环境建议

  • --cap-add=NET_ADMIN 等精确授权替代 --privileged
  • 开启 no-new-privileges 并配 AppArmor/SELinux 模板;
  • 在 CI 门禁里使用 docker-bench-security 与阿里云「容器安全扫描」做卡点,确保镜像与运行时合规。

拓展思考

  1. rootless Docker 能否完全杜绝逃逸?——不能,但能把攻击面从“宿主机 root”降到“用户命名空间 uid=0”,需结合内核 seccomp 过滤与 shadow-utils 最新补丁。
  2. k8s 场景下,Pod 的 securityContext.privileged=true 同样等价于 --privileged,国内大厂普遍通过 OPA Gatekeeper 强制拒绝此类 Pod 进入集群。
  3. 应急演练:在靶机里故意运行 privileged 容器,让候选人 5 分钟内完成逃逸并拿到宿主 /etc/shadow,可快速验证其真实动手能力。