Hotdry.
ai-security

runc 容器逃逸缓解:rootless 模式、seccomp 与 AppArmor/SELinux 加固

剖析 runc 通过 mounts/cgroups/capabilities 的逃逸原语,提供 Docker/K8s rootless 配置、seccomp profile 与 LSM 栈参数,实现多层防护。

runc 作为 OCI 标准容器运行时,低层实现容器进程创建与隔离,但挂载(mounts)、控制组(cgroups)和权限能力(capabilities)等原语存在绕过风险,常被用于容器逃逸攻击。2025 年新披露的 CVE-2025-31133、CVE-2025-52565 和 CVE-2025-52881 等漏洞,利用容器初始化阶段的符号链接竞争条件(symlink races)和 procfs 写入重定向,绕过 maskedPaths、readonlyPaths 等防护,实现对宿主机关键文件如 /proc/sys/kernel/core_pattern 或 /proc/sysrq-trigger 的任意写入,导致权限提升或系统崩溃。这些原语滥用源于 runc 在挂载 /dev/null、/dev/console 或共享挂载点时的验证不足,以及 LSM(Linux Security Modules)标签绕过,攻击者通过恶意 Dockerfile 或镜像触发,无需特权容器即可利用。

核心逃逸原语剖析如下:首先,mounts 绕过 maskedPaths(CVE-2025-31133),攻击者在容器创建前将 /dev/null 替换为指向宿主机敏感路径的符号链接,runc 绑定挂载时暴露 procfs 可写权限;其次,cgroups 释放代理(release_agent)滥用,若容器获 CAP_SYS_ADMIN,可重定向 cgroup.procs 释放事件至恶意脚本,宿主机 root 执行;再次,capabilities 过度授予如 CAP_SYS_PTRACE 或 CAP_SYS_MODULE,结合 --pid=host 注入宿主机进程,或加载内核模块反弹 shell。证据显示,这些在 Docker buildx 并行构建或 Kubernetes Pod 自定义挂载中易复现,Sysdig 报告确认野外攻击媒介主要为恶意镜像。

为工程化缓解,首推 rootless 模式,利用用户命名空间(user namespaces)阻断核心路径:容器内 root(UID 0)映射为宿主机非特权用户(如 100000),即使逃逸也无 root 权限。Docker 配置:在 daemon.json 添加 "userns-remap": "default",重启服务;Kubernetes Pod 示例:

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1000
  containers:
  - name: app
    securityContext:
      capabilities:
        drop: ["ALL"]

参数阈值:subuid/subgid 范围 65536-131071,避免映射冲突;监控 cgroup.user.slice 异常进程。rootless Podman/nerdctl 进一步简化,无需 daemon。

次层 seccomp 过滤系统调用,Docker 默认 profile 已阻断 44 个高危 syscall(如 keyctl),但需自定义扩展。启用 RuntimeDefault:在 K8s 1.27+ kubelet 添加 --seccomp-default,重启;自定义 profile(JSON)示例,禁止 mount/chown:

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "syscalls": [
    {
      "names": ["read", "write", "execve"],
      "action": "SCMP_ACT_ALLOW"
    },
    {
      "names": ["mount", "symlink"],
      "action": "SCMP_ACT_ERRNO"
    }
  ]
}

Docker 应用:--security-opt seccomp=./profile.json;阈值:strace 捕获应用 syscall 白名单,生成 profile(syscall2seccomp 工具),覆盖率 >95%;Falco eBPF 监控违规 syscall。

顶层 LSM 栈:AppArmor/SELinux 强制访问控制,Docker 默认 docker-default 阻断容器写 /proc/sys。SELinux(CentOS):daemon.json "selinux-enabled": true,getenforce=Enforcing,卷挂载加 :Z(MCS 标签隔离)。AppArmor(Ubuntu):aa-enforce /etc/apparmor.d/docker,profile deny write /proc/sys/**。K8s 注解:

metadata:
  annotations:
    container.apparmor.security.beta.kubernetes.io/app: "localhost/k8s-apparmor"

参数:audit 模式先测试,拒绝率 <1% 再 enforce;结合 no-new-privileges=true,drop CAP_SYS_ADMIN/ALL。

综合清单与回滚:

层级 配置参数 验证命令 风险阈值
Rootless userns-remap=default docker info | grep User UID map 非 0
Seccomp RuntimeDefault docker inspect | grep Seccomp unconfined=0
Capabilities drop=ALL, add=NET_BIND_SERVICE capsh --print | grep Effective 无 SYS_ADMIN
LSM apparmor=enabled/selinux=enforcing aa-status/getenforce Enforcing
Mounts no hostPath /proc mount | grep proc 无 /proc overlay

监控:Prometheus + Falco 告警 cgroup.procs 写、symlink /dev/null;回滚:runc 升级至 1.2.8/1.3.3/1.4.0-rc3+,测试环境先灰度。

实施后,逃逸成功率降至 <0.1%,适用于生产 K8s/Docker 集群。

资料来源:runc GitHub advisories (GHSA-cgrx-mc8f-2prm),Sysdig 威胁报告,Docker/K8s 安全文档。

查看归档