Rootless 模式
什么是 Rootless 模式
Rootless 模式允许 Docker 守护进程(dockerd)和容器以非 root 用户身份运行,极大地降低了容器逃逸的风险。在这个模式下,即使攻击者获得了容器内 root 权限,也无法对宿主机造成实质伤害。
传统模式的缺陷
# 传统模式下,dockerd 以 root 运行
ps aux | grep dockerd
root 12345 ... /usr/bin/dockerd -H fd://
# 容器逃逸意味着获得宿主机 root 权限
Rootless 模式的工作原理
Rootless 模式通过 Userspace Networking 和 Namespace 技术实现:
# 进程关系(Rootless)
普通用户 → rootless-dockerd → containerd → runc → 容器
# 容器的网络通过 slirp4netns 实现
# 存储使用 fuse-overlayfs 或 vfs
核心组件
- rootlesskit:创建用户命名空间
- slirp4netns:用户态网络栈
- fuse-overlayfs:用户态 overlayfs 驱动
- dockerd-rootless-setuptool.sh:自动配置脚本
安装 Rootless Docker
前提条件
# 检查内核支持
uname -r # 需要 >= 4.18
cat /proc/sys/kernel/unprivileged_userns_clone # 需要 1
# 检查是否需要配置
sudo sysctl -w kernel.unprivileged_userns_clone=1
echo 'kernel.unprivileged_userns_clone=1' | sudo tee /etc/sysctl.d/99-userns.conf
安装步骤
# 方法 1:使用官方脚本
curl -fsSL https://get.docker.com/rootless | sh
# 方法 2:手动设置
export PATH=/home/user/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock
dockerd-rootless-setuptool.sh install
# 设置环境变量
echo 'export PATH=/home/user/bin:$PATH' >> ~/.bashrc
echo 'export DOCKER_HOST=unix:///run/user/1000/docker.sock' >> ~/.bashrc
启动 Rootless Docker
# 启动
systemctl --user start docker
# 开机自启
systemctl --user enable docker
# 验证
docker info | grep Rootless
# Rootless: true
Rootless 模式的使用
# 正常使用 Docker 命令
docker run -d -p 8080:80 nginx
# 查看运行用户
docker run --rm alpine whoami
# root # 容器内还是 root,但映射为普通用户
# 查看进程所有者
ps aux | grep nginx
# user 12345 ... nginx # 进程属于普通用户
Rootless vs Rootful 对比
| 特性 | Rootful | Rootless |
|---|---|---|
| dockerd 运行用户 | root | 普通用户 |
| 容器逃逸风险 | 高(可获得 root) | 低(限制在用户空间) |
| 性能 | 原生网络/存储 | 有轻微性能损失 |
| 端口 <1024 | 直接绑定 | 需额外配置 |
| 存储驱动 | overlay2 | fuse-overlayfs 或 vfs |
| 网络驱动 | bridge, overlay | bridge(通过 slirp4netns) |
| 兼容性 | 全部功能 | 部分功能受限 |
Rootless 模式的限制
1. 特权端口
# ❌ 不能直接绑定 <1024 端口
docker run -p 80:80 nginx # 失败
# ✅ 使用高位端口
docker run -p 8080:80 nginx
# ✅ 使用工具转发
sudo setcap cap_net_bind_service=+ep /usr/bin/rootlesskit
2. 网络限制
# ❌ 不支持 host 网络模式
docker run --net=host nginx # 失败
# ❌ 不支持 overlay 网络
docker network create -d overlay mynet # 失败
# ✅ 支持 bridge 网络(通过 slirp4netns)
docker run --net=bridge nginx # 可用
3. 存储限制
# ❌ 不支持某些存储驱动
docker info | grep Storage
# Storage Driver: fuse-overlayfs
# 或 vfs(效率较低)
# 性能影响
# 相比 overlay2 有 5-15% 的性能损失
4. 资源限制
# 部分 cgroup 功能受限
# 内存和 CPU 限制可能无法完全生效
# 解决方法
docker run --cgroupns=host --cpus=1 --memory=256m nginx
配置特权端口
# 方法 1:设置 CAP_NET_BIND_SERVICE
sudo setcap cap_net_bind_service=+ep /usr/bin/rootlesskit
# 方法 2:使用端口转发
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
检查是否运行在 Rootless 模式
# 方法 1
docker info | grep -i rootless
# 方法 2
ps aux | grep dockerd | grep -v root
# 方法 3
echo $DOCKER_HOST
# unix:///run/user/1000/docker.sock
从 Rootful 迁移到 Rootless
# 1. 备份数据
docker save -o all-images.tar $(docker images -q)
# 2. 安装 Rootless Docker
dockerd-rootless-setuptool.sh install
# 3. 迁移数据
docker load -i all-images.tar
docker volume create mydata
docker run -v mydata:/data alpine sh -c "cp /old-data/* /data/"
# 4. 切换默认 Docker
alias docker='docker --host unix:///run/user/1000/docker.sock'
安全收益
Rootless 模式提供了显著的安全改进:
安全层次:
1. 容器内 root → 仅限用户命名空间内的 root
2. 容器逃逸 → 获得普通用户权限
3. 容器漏洞 → 不能执行管理员操作
4. 内核漏洞 → 无 root 权限,利用难度增加
生产环境评估
# 性能测试
docker run --rm alpine time dd if=/dev/zero of=/tmp/test bs=1M count=100
# 兼容性测试
docker run --rm -p 8080:80 nginx
curl localhost:8080
Rootless 模式是 Docker 安全的重要演进方向。虽然不是所有场景都适用,但它显著降低了容器逃逸的风险,是生产环境安全加固的重要选项。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容