引言

容器技术已经成为现代云原生基础设施的基石,但容器的安全性往往被低估。容器并非轻量级的虚拟机——它们本质上是宿主机上的进程,依靠 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 强制访问控制。每一层都可能被攻破,但所有层共同构成了纵深防御体系。

核心原则始终不变:最小权限、纵深防御、持续监控、快速响应。安全不是终点,而是贯穿容器全生命周期的持续过程。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部