启用UserNS需宿主机配置daemon.json的"userns-remap":"default"并重启Docker服务,使容器root映射至宿主机非特权UID(如100000+);Compose中须显式设user:"10001:10001",配合镜像内建用户及只读挂载,方实现有效隔离。

直接在 docker-compose.yml 中启用 userns_mode: "host" 并不能提升安全——它反而会禁用用户命名空间隔离,属于高危配置。真正起作用的是宿主机层面的用户命名空间映射机制,Compose 本身不管理 userns,而是依赖 Docker 守护进程的全局配置和镜像/服务级的 user 指定协同生效。
宿主机必须先启用用户命名空间支持
这是前提,否则所有容器内 user 设置都只是“伪降权”:攻击者仍可利用内核漏洞提权到宿主机 root。
- 检查
/etc/subuid和/etc/subgid是否已为运行 Docker 的用户(如docker或当前用户)分配了足够范围的子 UID/GID,例如:dockremap:100000:65536 - 确认 Docker daemon.json 中启用了 user namespace 映射:
{"userns-remap": "default"}或指定用户名 - 重启 Docker 服务使配置生效:
sudo systemctl restart docker
Compose 中必须显式指定非 root UID:GID
仅靠宿主机 userns 配置不够,容器内进程仍默认以 UID 0 运行。需强制切换为映射范围内的非特权 ID。
- 在服务中使用数字格式的
user,避免用户名(因镜像内可能无对应条目):user: "10001:10001" - UID/GID 建议 ≥ 10000,避开系统保留范围(
README.md明确指出 “UIDs below 10,000 are a security risk”) - 搭配
read_only: true和tmpfs挂载,进一步限制写权限
镜像构建阶段同步创建专用用户
防止运行时因文件属主不匹配导致启动失败或权限绕过。
- Dockerfile 中提前建组建用户,并用
--chown赋权应用文件:RUN groupadd -r app && useradd -r -u 10001 -g app appCOPY --chown=app:app ./app /appUSER app - 确保
CMD或ENTRYPOINT不再以 root 权限执行初始化脚本 - 验证方式:
docker-compose exec web whoami应返回 UID 数字,而非root
配合 Docker 27 的 bridge 默认拒绝策略使用
userns 解决的是进程级权限问题,网络层需同步加固,形成纵深防御。
- 将服务接入显式声明的隔离网络:
networks: [backend],而非默认bridge - 在
docker network create中启用--opt com.docker.network.bridge.default-deny=true - 服务间通信必须通过
links或自定义别名显式授权,杜绝隐式互通


















