Rootless 模式

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
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容