解释 `privileged` 容器如何导致宿主机逃逸
解读
面试官想确认你对 Linux Capabilities、Namespace 隔离边界以及 Docker 安全模型的理解深度,并判断你是否具备在生产环境权衡“方便”与“安全”的能力。回答时要从内核机制层面讲清“为什么放开特权就能逃逸”,再给出国内可落地的加固方案,避免空谈。
知识点
- Linux Capabilities:细粒度划分 root 权限,Docker 默认只给 14 项危险能力,而
--privileged一次性赋予全部 37 项。 - Namespace 隔离缺陷:
--privileged会自动挂载宿主所有设备文件(--device=的通配版),导致容器进程能看到/dev/sda、/dev/mem等。 - cgroups 逃逸:特权容器可写
/sys/fs/cgroup下的release_agent,在宿主机侧执行任意命令。 - 内核漏洞利用:一旦拿到
CAP_SYS_MODULE,可insmod加载恶意 ko,直接获得宿主机 root。 - 国内合规要求:等保 2.0 三级以上明确要求“容器平台应关闭或限制特权容器”,面试时提到等保可加分。
答案
--privileged 关闭了三条核心防线,使容器进程与宿主机进程几乎等价:
- Capabilities 防线:默认白名单被清空,容器获得全部 37 项 Cap,包括
CAP_SYS_ADMIN、CAP_SYS_MODULE、CAP_DAC_READ_SEARCH等高危权限。 - 设备隔离防线:Docker 会把宿主
/dev下的所有设备挂载到容器,攻击者可直接读写宿主机磁盘/dev/sda或/dev/mem,修改宿主机文件或注入恶意代码。 - 内核接口防线:特权容器可重新挂载
/proc、/sys为读写,结合CAP_SYS_MODULE加载内核模块,触发本地提权漏洞(如国内去年爆发的 CVE-2022-0847 DirtyPipe)。
经典逃逸步骤:
- 在容器内执行
fdisk -l发现宿主磁盘/dev/sda1; mkdir /tmp/h && mount /dev/sda1 /tmp/h,把宿主机根目录挂进容器;- 写入
crontab或/root/.ssh/authorized_keys,实现宿主 root 权限反弹。
国内生产环境建议:
- 用
--cap-add=NET_ADMIN等精确授权替代--privileged; - 开启
no-new-privileges并配 AppArmor/SELinux 模板; - 在 CI 门禁里使用
docker-bench-security与阿里云「容器安全扫描」做卡点,确保镜像与运行时合规。
拓展思考
- rootless Docker 能否完全杜绝逃逸?——不能,但能把攻击面从“宿主机 root”降到“用户命名空间 uid=0”,需结合内核
seccomp过滤与shadow-utils最新补丁。 - k8s 场景下,Pod 的
securityContext.privileged=true同样等价于--privileged,国内大厂普遍通过 OPA Gatekeeper 强制拒绝此类 Pod 进入集群。 - 应急演练:在靶机里故意运行
privileged容器,让候选人 5 分钟内完成逃逸并拿到宿主/etc/shadow,可快速验证其真实动手能力。