引言
容器技术已经成为现代云原生基础设施的基石,但容器的安全性往往被低估。容器并非轻量级的虚拟机——它们本质上是宿主机上的进程,依靠 Linux 内核的多种隔离机制实现"看似独立"的运行环境。理解这些底层机制,才能真正构建安全的容器部署。
一、Linux Namespace:容器的隔离基石
Namespace 是容器隔离的第一重保障,它让容器中的进程只能"看到"属于自己的资源视图:
- PID Namespace:容器内进程拥有独立的 PID 编号空间,容器内的 init 进程通常为 PID 1,无法看到宿主机上的其他进程。
- NET Namespace:每个容器拥有独立网络设备、协议栈、路由表和 iptables 规则,互不干扰。
- MNT Namespace:实现文件系统挂载点的隔离,保障 chroot 级别的存储隔离。
- IPC Namespace:隔离 System V IPC 资源(消息队列、信号量、共享内存)。
- USER Namespace:将容器内的 root 用户映射到宿主机上的非特权用户,是容器安全的核心防线。
- UTS Namespace:允许每个容器拥有独立的主机名和域名。
- Cgroup Namespace:隐藏容器自身的 cgroup 层级,防止容器进程探知宿主机 cgroup 结构。
- Time Namespace(Linux 5.6+):允许容器内进程看到不同的系统时间。
使用 unshare 命令可以手动创建新的 namespace:
# 在新的 PID、NET、MNT namespace 中运行 shell
sudo unshare --pid --net --mount --fork --mount-proc /bin/bash
# 查看当前进程的 namespace 链接
ls -la /proc/self/ns/
二、Cgroups:资源限制与防护
Control Groups (cgroups) 负责限制容器可使用的资源,防止"吵闹的邻居"问题和资源耗尽型 DoS 攻击:
- cpu:通过 CFS 调度器限制 CPU 时间片,支持硬限额(hard limit)和权重分配(shares)。
- memory:设置内存使用硬上限、软上限和 swap 限制,超出触发 OOM killer。
- blkio:限制块设备的读写 IOPS 和带宽,防止存储层 DoS。
- pids:限制容器内可创建的进程数,直接防御 fork 炸弹攻击。
- hugetlb:控制 Huge Pages 使用量,面向高性能计算场景。
- rdma:限制 RDMA/InfiniBand 资源(Linux 4.13+)。
- misc:控制其他杂项资源(如 GPU 设备数、加密设备等)。
实际战斗中的 cgroup 配置示例(Kubernetes Pod 规格):
resources:
limits:
cpu: "2"
memory: "4Gi"
ephemeral-storage: "10Gi"
requests:
cpu: "500m"
memory: "1Gi"
关键安全要点:永远为容器设置 pids-limit,建议值不低于 100,以防御恶意容器内的 fork 炸弹。
三、Capabilities:最小权限原则
Linux 将传统 root 权限拆分为 40+ 个独立的 capability,容器运行时默认会丢弃大部分高危 capability:
必须关注的高危 capability:
- CAP_SYS_ADMIN:"万能钥匙"——可执行 mount、创建设备节点、修改 namespace 等,容器逃逸最常见的利用路径。
- CAP_NET_ADMIN:修改网络配置、路由表、iptables 规则,可能导致网络隔离失效。
- CAP_SYS_PTRACE:可 ptrace 其他进程,用于进程注入或信息窃取。
- CAP_SYS_MODULE:允许加载内核模块,直接威胁宿主机内核安全。
- CAP_DAC_READ_SEARCH:绕过文件读权限检查,可读取任意文件。
- CAP_SYS_RAWIO:直接访问原始 I/O 端口和 /dev/mem,威胁硬件层安全。
- CAP_BPF(Linux 5.8+):加载 eBPF 程序,可被用于宿主机内核监控或攻击。
Docker 默认白名单策略和最佳实践:
# 丢弃所有 capability,仅保留需要的
docker run --cap-drop ALL ---cap-add NET_BIND_SERVICE nginx
# Kubernetes 配置
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
四、Seccomp:系统调用过滤
Secure Computing Mode (seccomp) 限制容器可使用的系统调用(syscall),大幅缩小内核攻击面:
- SECCOMP_MODE_STRICT:仅允许 read/write/exit/sigreturn,过于严格。
- SECCOMP_MODE_FILTER(BPF 过滤器):精确控制每个 syscall 的允许/拒绝/报错策略。
Docker 默认 seccomp 配置文件禁用了约 44 个高危 syscall,包括:
kexec_load:直接启动新内核,绕过 GRUB 安全启动。init_module/finit_module:加载内核模块。open_by_handle_at:通过文件 handle 打开文件,绕过路径权限检查。name_to_handle_at:NFS 文件系统句柄转换,可绕过文件系统权限。process_vm_readv/process_vm_writev:跨进程内存读写。userfaultfd:用户态缺页处理,常被用于内核漏洞利用(如 Dirty COW 后续利用)。ptrace:进程追踪与注入。
自定义 seccomp profile 示例:
{
"defaultAction": "SCMP_ACT_ERRNO",
"syscalls": [
{
"names": ["read", "write", "close", "exit_group", "futex",
"epoll_wait", "clock_gettime", "nanosleep"],
"action": "SCMP_ACT_ALLOW"
}
]
}
五、AppArmor 与 SELinux:强制访问控制
MAC 系统提供比传统 DAC(自主访问控制)更严格的权限控制:
- AppArmor(Ubuntu/Debian 默认):基于路径的安全策略,定义每个程序可访问的文件、网络和 capability。
- SELinux(RHEL/CentOS/Fedora 默认):基于安全上下文(type enforcement)的细粒度策略,每个进程和文件标签化。
AppArmor 策略示例(限制 Nginx 进程):
/usr/sbin/nginx flags=(complain) {
#include <abstractions/base>
#include <abstractions/nameservice>
network inet tcp,
network inet6 tcp,
/usr/sbin/nginx mr,
/var/log/nginx/** rw,
/run/nginx.pid rw,
/etc/nginx/** r,
# 明确禁止写系统目录
deny /etc/shadow r,
deny /root/** rwx,
关键原则:容器部署应始终启用 AppArmor 或 SELinux,绝不能设置为 --privileged 或关闭 MAC。
六、容器逃逸攻击与防御
历史上真实存在的容器逃逸漏洞和攻击手法:
- Dirty COW (CVE-2016-5195):内核 COW 竞态条件,容器内写入 /proc/self/mem 提升权限。
- Dirty Pipe (CVE-2022-0847):通过 pipe 缓冲区覆写只读文件,可逃逸到宿主机。
- runc 容器逃逸 (CVE-2019-5736):容器内进程覆盖宿主机 runc 二进制,下次容器启动时代码执行。
- Kubernetes API Server 配置错误:过度授权的 ServiceAccount 导致提权到集群管理员。
- SYS_PTRACE capability 滥用:通过 ptrace 注入宿主机进程获取 shell。
- cgroup release_agent 攻击:配置 cgroup 的 release_agent 在 cgroup 释放时执行恶意代码。
防御清单:
1. 始终保持内核更新,关注 Linux kernel CVE
2. 禁止容器以 --privileged 运行
3. 默认丢弃 ALL capabilities
4. 禁用容器间共享 pid namespace
5. 挂载 /proc 为 hidepid=2
6. 使用只读根文件系统 (readOnlyRootFilesystem: true)
7. 禁止特权端口绑定(securityContext.allowPrivilegeEscalation: false)
8. 使用 Pod Security Standards (PSS) 中的 Restricted 策略
9. 部署 Falco 或 Tetragon 实时检测异常行为
10. 使用 rootless 容器(无需 root 权限运行容器引擎)
七、rootless 容器:终极隔离
Rootless 容器(Docker rootless mode、Podman、Rootless Kubernetes)从根本上消除了容器逃逸的攻击面:
- 容器引擎以非 root 用户运行。
- 使用
newuidmap/newgidmap进行 UID/GID 映射。 - 通过
slirp4netslirp实现用户态网络栈(略慢但更安全)。 - 无需
--privileged标志,实际上根本不存在。 - 与 Podman 内置的 rootless 支持配合,可实现端到端无 root。
创建 rootless Podman 容器:
# 安装 Podman 后直接以普通用户运行
podman run --rm -it nginx:alpine sh
# 验证:容器内看到的 root 映射到宿主机的高 UID
podman unshare cat /proc/self/uid_map
# 输出: 0 1000 1 — 容器内 UID 0 映射到宿主机 UID 1000
八、Kubernetes 安全上下文最佳配置
生产级 Kubernetes 部署的安全加固配置:
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
appArmorProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
cpu: "1"
memory: "512Mi"
ephemeral-storage: "1Gi"
requests:
cpu: "200m"
memory: "256Mi"
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache
volumes:
- name: tmp
emptyDir:
sizeLimit: 100Mi
- name: cache
emptyDir:
sizeLimit: 200Mi
九、前沿趋势:机密容器与机密计算
随着硬件可信执行环境(TEE)的发展,容器安全正进入新的阶段:
- Intel SGX / AMD SEV-SNP / Intel TDX:硬件级内存加密,即使宿主机 root 也无法读取容器内存。
- Confidential Containers (CoCo):基于 kata-containers + TEE,实现容器负载的机密性和完整性保护。
- Measured Boot + Remote Attestation:启动时度量整个信任链,远程验证容器运行环境可信后注入密钥。
- eBPF 运行时安全:Cilium Tetragon 实时监控内核级事件,精确到进程级别的行为分析。
- WASM 容器:WebAssembly 提供更轻量、更安全的沙箱模型,无内核共享。
总结
容器安全不是单一功能,而是多层防御的深度叠加——Namespace 提供视图隔离,Cgroups 限制资源,Capabilities 细分权限,Seccomp 过滤 syscall,MAC 强制访问控制。每一层都可能被攻破,但所有层共同构成了纵深防御体系。
核心原则始终不变:最小权限、纵深防御、持续监控、快速响应。安全不是终点,而是贯穿容器全生命周期的持续过程。

发表评论 取消回复