Podman 无根容器与 Copy Fail 漏洞:分析爆炸半径
Podman 无根容器与 Copy Fail 漏洞:分析爆炸半径
CVE-2026-31431(被称为 "Copy Fail")的披露在 Linux 社区引起了不小的波动。该漏洞允许本地非特权用户通过利用内核处理某些文件操作的方式来获取 root shell,实际上允许用户覆盖他们本应只有只读权限的文件。
对于使用容器化技术的人来说,其影响是重大的。容器通常用于隔离面向公众的服务、CI/CD 作业和开发环境。如果攻击者通过远程代码执行 (RCE) 获得立足点,Copy Fail 可能被用于在容器内提升权限。本文将专门在 Podman 无根容器的背景下检查该漏洞,并探讨不同的配置如何影响此类攻击的 "爆炸半径"。
理解无根容器
要理解 Copy Fail 的影响,首先需要了解 Podman 如何实现无根容器。与传统的 Docker daemon 模型(由 rootful daemon 启动容器)不同,Podman 使用 fork/exec 模型。容器进程是 podman run 进程的直接后代,这意味着它继承了启动它的用户的 UID。
用户命名空间与 UID 映射
Podman 利用 Linux 用户命名空间来提供隔离。这允许一个进程在容器内部拥有一个 UID,而在宿主机上拥有另一个不同的 UID。例如,在无根容器内部以 root (UID 0) 运行的进程会被映射到宿主机上的非特权用户(例如 UID 1001)。
这种映射由 /etc/subuid 管理,该文件定义了非特权用户可以分配给命名空间进程的 UID 范围。这确保了即使进程在容器内部是 root,从宿主机的角度来看它仍然是一个非特权用户,从而严重限制了其破坏宿主机系统的能力。
Linux Capabilities
Linux 中的 root 权限并不是单一的;它们被分解为 "capabilities"。Podman 使用这些来向容器进程授予细粒度的权限。例如,通过 apt 安装软件包需要 CAP_CHOWN 和 CAP_SETUID 等 capabilities。
默认情况下,一个 rootful 无根容器(在命名空间内以 root 运行)会被授予广泛的 capabilities。这增加了攻击面。更安全的方法是运行 "rootless non-root" 容器,即进程在容器内外都以非特权用户运行,并丢弃所有不必要的 capabilities。
测试 Copy Fail 漏洞利用
在实际测试中,Copy Fail 被用于尝试在各种 Podman 配置下进行权限提升。漏洞利用通常涉及下载一个 Python 脚本,该脚本允许在无需密码提示的情况下执行 su 命令,从而授予 root shell。
Rootless Rootful 容器
在进程已经在容器内以 root 运行的配置中,Copy Fail 是多余的。用户已经拥有了漏洞利用试图提供的权限。然而,该进程仍然映射到宿主机上的一个非特权用户,这意味着宿主机的 root 文件仍然无法访问。
Rootless Non-Root 容器
这是漏洞利用发挥威力的地方。在以非特权用户(例如 foo)运行的容器中,Copy Fail 可以成功地将进程提升为容器 root。
虽然攻击者现在在容器 内部 拥有了 root 权限并可以访问命名空间 root 所拥有的文件,但他们仍然受到宿主机用户权限的限制。他们无法访问由宿主机实际 root 用户拥有的文件。
缓解权限提升
可以使用两个主要的 Podman 标志来阻碍 Copy Fail 漏洞利用的即时效果:
--security-opt=no-new-privileges: 这可以防止进程获取额外的权限。当设置此标志时,Copy Fail 漏洞利用无法产生 root shell;用户仍然是foo。--cap-drop=all: 丢弃所有 capabilities 同样可以防止漏洞利用成功提升到特权 root shell。
需要注意的是,虽然这些标志可以防止 su 漏洞利用,但底层的漏洞——在 page cache 中覆盖只读文件的能力——仍然存在。必须对内核进行补丁修复才能完全解决问题。
纵深防御:限制爆炸半径
由于没有任何单一的安全边界是万无一失的的,因此必须采取纵深防御策略来限制受损容器可能造成的破坏。
只读文件系统
使用 --read-only 标志(结合 --read-only-tmpfs=false)将容器的根文件系统挂载为只读。这可以防止攻击者在漏洞利用后写入恶意二进制文件或修改系统配置,尽管它并不能阻止漏洞利用通过管道命令在内存中运行。
资源限制
利用 cgroups 来限制内存、CPU 和 PID 计数,可以确保受损的容器不会被用于对宿主机或其他容器发起拒绝服务 (DoS) 攻击。
最小化镜像
减少攻击者可用的工具集是一个关键步骤。减少攻击者可用的工具集是一个关键步骤。使用 ubuntu 作为基础镜像会提供丰富的二进制文件(如 curl 和 python3)来辅助漏洞利用。转向使用 -slim 镜像、Alpine Linux 或 "distroless" 镜像可以移除 shell 和包管理器,从而显著增加攻击者引导漏洞利用的难度。
网络防火墙
通过 iptables 或 nftables 限制传入和传出的连接,可以防止受损容器与命令控制 (C2) 服务器通信或在内部网络中进行横向移动。
批判性观点与反驳点
虽然主要的漏洞利用示例侧重于通过 su 获取 root shell,但社区讨论强调了 Copy Fail 的真正危险在于更广泛的层面。
"这个漏洞使得所有本应与容器共享只读的资源实际上变得某种程度上可写,因此在许多场景下,爆炸半径将会非常巨大,即使它不像 'su' 示例那样普遍且容易被利用。"
此外,一些研究人员指出 Copy Fail could be used for lateral attacks between containers。如果两个容器共享一个基础镜像层,恶意容器可能有可能覆盖共享层中的一个文件,从而破坏在同一个非特权用户下运行的第二个容器。
也有越来越多的观点认为,Linux 内核的隔离机制(namespaces, seccomp)对于高安全性环境可能不足,因此一些人主张使用 MicroVMs 作为更强的安全边界。
结论
Podman 的无根架构通过确保容器 root 永远不是宿主机 root,提供了比标准 rootful Docker 安装更优的安全态势。然而,正如 Copy Fail 证明的那样,容器并不是不可逾越的墙。通过结合无根执行、丢弃 capabilities、no-new-privileges 选项以及最小化镜像,管理员可以大幅度降低受损容器的爆炸半径。最终,最有效的防御仍然是及时进行内核补丁修复,并结合假设容器边界最终会被突破的纵深防御策略。