容器逃逸防范

容器逃逸防范

什么是容器逃逸

容器逃逸(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
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容