Docker cgroup与namespace隔离下容器root用户为何能读取宿主机受限文件
问题解答
1. 容器能读取敏感文件的核心原因
默认配置下,容器内的root用户对应的UID就是宿主机的UID 0,Linux内核的文件权限校验只认UID/GID,不会区分进程是否运行在容器中:
- 你通过
-v /root/secrets.txt:/tmp/secrets.txt主动将宿主机的敏感文件挂载进了容器的文件系统视图 - 容器内执行
cat命令的进程默认以root身份运行,UID为0,刚好匹配宿主机上secrets.txt的所有者UID 0,符合文件rw-------的权限要求,因此内核直接放行读取操作
2. 该现象与Docker隔离机制并不冲突
Docker的隔离本质是视图隔离 + 权限限制,而非完全禁止对宿主机资源的访问:
- Namespace的作用是隔离进程的可见资源范围(比如只能看到容器内的进程、网络、挂载点等),但不会修改内核底层的权限校验逻辑
- 默认配置下容器root只是被Capability、Seccomp、AppArmor等安全模块限制了修改宿主机内核配置、管理硬件等高风险操作,对于你主动挂载进容器的文件,依然遵循常规的Linux DAC权限规则
3. 你遗漏的核心知识点
- User Namespace的默认状态:绝大多数Linux发行版的Docker默认关闭用户命名空间,没有做UID偏移映射,容器内UID 0和宿主机UID 0完全等价。如果开启用户命名空间,容器内的root会被映射为宿主机上的非特权UID,此时就无法读取该文件。
- Bind Mount的权限逻辑:绑定挂载是直接把宿主机文件暴露给容器,权限校验完全遵循内核规则,Docker不会额外增加权限拦截。
- docker组的权限本质:能执行
docker命令的用户,相当于间接获得了宿主机的root权限——因为可以通过挂载宿主机根目录、修改宿主机配置等操作实现提权,这也是生产环境不允许随意将普通用户加入docker组的核心原因。
4. 与docker run使用方式的关系
默认情况下容器运行进程的用户,和执行docker run命令的用户完全无关:
- Docker Daemon默认以root身份运行,你作为docker组的普通用户只是向Daemon发送了创建容器的请求,Daemon启动容器进程时默认使用Dockerfile中指定的用户,未指定的话就是root
- 你可以通过
docker run --user <非rootUID>参数强制容器以非特权用户运行,此时如果容器内进程UID和宿主机文件所有者UID不匹配,就无法读取该文件
内容的提问来源于stack exchange,提问作者samshers
相关产品推荐
相关产品推荐

