linux容器安全依赖用户权限模型与namespace、cgroup协同:user namespace映射uid实现“假root”受限,capabilities按需授权,cgroup通过/sys/fs/cgroup权限控制资源限额,缺一不可。

Linux 系统权限与容器技术不是并列关系,而是底层支撑关系:容器的隔离性与安全性,高度依赖 Linux 原生权限机制(尤其是 UID/GID)与 Namespace、Cgroup 的协同设计。没有用户权限模型,Namespace 和 Cgroup 就无法实现真正的安全隔离。
User Namespace 是权限隔离的核心载体
User Namespace 让容器内 root(UID 0)在宿主机上表现为普通用户,这是容器权限模型的基石。它通过 UID/GID 映射表(/proc/[pid]/uid_map)将容器内 ID 映射到宿主机上非特权范围(如 100000–165535),从而避免容器逃逸后直接获得宿主机 root 权限。
- 未启用 User Namespace 时,容器进程在宿主机上以真实 root 运行,一旦突破其他隔离层(如 PID 或 Mount),极易提权
- Docker 默认不启用 User Namespace,需显式配置 --userns-remap 或 daemon.json 中设置 userns-remap = default
- 启用后,/etc/passwd、/etc/group 在容器内可自由修改,但不会影响宿主机——映射关系由内核强制维护
权限控制贯穿 Namespace 创建全过程
创建多数 Namespace 需要相应 capability(能力)权限,而 capability 本身是基于传统 Unix 权限的精细化拆分。例如:
- CLONE_NEWNET(网络隔离)需要 CAP_NET_ADMIN,通常只授予 root 或明确授权的用户
- CLONE_NEWUSER(用户隔离)可在无特权条件下创建,但首次映射必须由 root 或具有 CAP_SETUIDS 的进程完成
- CLONE_NEWNS(挂载隔离)需 CAP_SYS_ADMIN,且后续 mount/unmount 操作受 mount namespace 权限约束
这意味着:即使一个普通用户能运行容器,其可用的 Namespace 类型也受限于被授予的 capabilities,而非单纯“有无 root”。
Cgroup 资源限制受文件系统权限约束
Cgroup v1/v2 的控制接口位于 /sys/fs/cgroup/ 下,该路径本质是一个伪文件系统,其目录与文件权限决定谁可以设置资源限额:
- cgroup.procs、cpu.max、memory.max 等文件默认仅允许 owner(通常是 root)写入
- 若将 cgroup 子树 chown 给某用户或组,并赋予写权限,该用户即可管理对应容器的 CPU/内存配额
- Kubernetes 的 Pod QoS 分级(Guaranteed/Burstable/BestEffort)正是通过向不同 cgroup 路径写入不同 resource limits 实现的,背后依赖的是 kubelet 进程的权限配置
权限组合决定容器实际安全边界
单靠某一层权限控制无法保障安全。典型组合场景如下:
- 仅用 PID+NET Namespace,但未启用 User Namespace → 容器内 root 可调用 setuid(0) 并尝试突破
- 启用 User Namespace,但未限制 capabilities → 容器仍可能执行 mount、reboot、net_admin 等高危操作
- 限制了 capabilities,但 cgroup memory.max 设为 -1(无限制)→ 内存耗尽可触发 OOM killer,波及宿主机关键进程
真正安全的容器运行时,必须同时满足:最小化 capabilities + 启用 User Namespace + 设置硬性 cgroup 限额 + 文件系统只读挂载 + seccomp/bpf 过滤系统调用。











