容器逃逸防范
什么是容器逃逸
容器逃逸(Container Escape)是指攻击者从容器内部突破隔离,获得宿主机操作系统访问权限的攻击行为。这是容器安全中最严重的事件之一。
常见的逃逸路径
1. Docker Socket 挂载
# ❌ 不要将 Docker Socket 挂载到容器内
services:
app:
image: myapp
volumes:
- /var/run/docker.sock:/var/run/docker.sock
访问到 socket 后可以执行:
# 逃逸脚本
docker -H unix:///var/run/docker.sock run -v /:/host ubuntu chroot /host
2. 特权模式滥用
# 特权容器 + 挂载宿主机文件系统
docker run --privileged ubuntu bash -c "
mount /dev/sda1 /mnt
chroot /mnt
"
3. 内核漏洞利用
历史上著名的逃逸漏洞:
# CVE-2019-5736 (runC)
# 覆盖宿主机 runC 二进制文件
# CVE-2020-15257 (containerd)
# 通过 containerd shim API 逃逸
# CVE-2022-0492 (cgroup)
# 利用 cgroup v1 提权
4. 挂载宿主机敏感目录
# ❌ 危险挂载
docker run -v /proc:/host_proc ubuntu
docker run -v /sys:/host_sys ubuntu
# 利用 /proc/sysrq-trigger
echo b > /proc/sysrq-trigger # 重启宿主机
5. Capabilities 滥用
# SYS_ADMIN + mount 可实现逃逸
docker run --cap-add=SYS_ADMIN ubuntu bash -c "
mount -t cgroup -o memory cgroup /mnt
mkdir /mnt/release_agent
echo '/sbin/poweroff' > /mnt/release_agent
echo 0 > /mnt/notify_on_release
"
逃逸检测和预防
1. 运行时监控
使用 Falco 等工具检测容器异常行为:
services:
falco:
image: falcosecurity/falco
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /proc:/host/proc:ro
- /boot:/host/boot:ro
command: falco
Falco 规则示例:
- rule: Container Escape via Mount
desc: Detected mount of host filesystem
condition: >
evt.type = mount and
container.id != host
output: "Container escape attempt (user=%user.name)"
priority: CRITICAL
2. Docker 安全检查脚本
#!/bin/bash
# container-escape-check.sh
echo "=== 检查容器安全配置 ==="
# 检查 Docker Socket
if [ -S /var/run/docker.sock ]; then
echo "❌ WARNING: Docker socket is mounted!"
fi
# 检查特权模式
if [ -f /proc/self/status ]; then
CapEff=$(grep CapEff /proc/self/status | awk '{print $2}')
if [ "$CapEff" = "0000003fffffffff" ]; then
echo "❌ WARNING: Container is running in privileged mode!"
fi
fi
# 检查宿主机文件系统访问
for dir in /host /mnt /root; do
if [ -d "$dir" ] && mountpoint -q "$dir" 2>/dev/null; then
echo "❌ WARNING: Host filesystem mounted at $dir"
fi
done
Docker 配置加固
daemon.json 安全配置
{
"userns-remap": "default",
"live-restore": true,
"userland-proxy": false,
"no-new-privileges": true,
"seccomp-profile": "/etc/docker/seccomp.json",
"authorization-plugins": ["docker-opa"],
"log-driver": "journald"
}
不要挂载敏感路径
# ❌ 不安全
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /proc:/proc
- /sys:/sys
- /:/host
# ✅ 安全
volumes:
- ./app-data:/data
- named-volume:/persistent-data
防止逃逸的最佳实践
1. 容器配置原则
# ✅ 安全的容器启动
docker run -d \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--security-opt=no-new-privileges:true \
--read-only \
--user 1000:1000 \
nginx
2. 只读文件系统
# 使用只读根文件系统
docker run --read-only nginx
# 允许特定目录写入
docker run --read-only -v /tmp:/tmp nginx
3. 禁止提权
# 防止通过 setuid bit 提权
docker run --security-opt=no-new-privileges:true nginx
# Docker Compose
services:
app:
security_opt:
- no-new-privileges:true
4. 使用用户命名空间
{
"userns-remap": "default"
}
容器内的 root 映射为宿主机上的普通用户,即使逃逸也无法获得宿主机的 root 权限。
5. 限制系统调用
docker run --security-opt seccomp=/custom-seccomp.json nginx
逃逸攻击的防御层次
攻击者 → 应用漏洞 → 容器突破 → Cgroups → Namespace → Seccomp → AppArmor → 内核
防御:
第一层:应用安全(最小化攻击面)
第二层:容器配置(非 root、只读、删 cap)
第三层:系统调用限制(Seccomp)
第四层:MAC(AppArmor/SELinux)
第五层:内核安全(用户命名空间、更新)
紧急响应
检测到容器逃逸时的应对步骤:
# 1. 立即隔离
docker stop container_name
docker network disconnect bridge container_name
# 2. 获取证据
docker logs container_name > evidence.log
docker inspect container_name > container-info.json
# 3. 分析影响范围
# 检查宿主机是否有异常进程
ps aux | grep -E "crypto|miner|unknown"
# 4. 修补漏洞
# 更新 Docker 版本
# 更新内核
# 修复配置
容器逃逸是可以预防的。通过正确的安全配置和防御层次,绝大多数逃逸攻击都可以被有效阻止。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容