云原生安全命门:隐藏的内核危机

31 阅读7分钟

云原生容器共享内核存安全隐患。内核未为多租户设计,漏洞多且难更新,易遭N日攻击。用户命名空间亦增风险。需通过独立内核等加强隔离,以弥补安全信任鸿沟。

译自:The Hidden Kernel Problem at the Heart of Cloud Native Security

作者:Jed Salazar

我们云原生生态系统中的大多数人都生活在 YAML 中。我们生活在 API、编排、控制器和容器工具中。我们生活在用户空间中。而 Linux 内核则作为一种我们很少考虑的无形力量,存在于所有这些之下。我们的日常工作涉及 Kubernetes 抽象,而不是页表或任务结构。

从安全角度来看,这是一个问题。内核是真正的边界。每个容器、每个扩展 Berkeley Packet Filter (eBPF) 程序、每个容器网络接口 (CNI) 插件以及每个隔离功能,最终都归结为单个整体式 Linux 内核内部的数据结构和代码路径。该内核已成为云原生环境中性能和安全的基础。当它失效时,其上的一切都会失效。

令人不安的部分在于此。我们围绕一个从未为云规模多租户设计,并且现在是我们基础设施中变化最快、最容易被利用的组件,建立了一个完整的生态系统。

容器继承的内核从未为此设计

如果你从内核的角度看容器,魔力很快就会消失。容器不是一个隔离的胶囊。它是一个由任务结构表示的进程。除了指向命名空间和 cgroup 的少数几个指针外,它看起来几乎与任何其他进程相同。这些命名空间营造了独立环境的假象,但内核仍然通过相同的调度程序、相同的系统调用表和相同的内存不安全 C 代码运行一切。

这是根本的脱节。从用户空间来看,容器似乎是隔离的。从内核空间来看,容器大部分是一个经过一些元数据包装的常规进程。

在过去十年中,我们在容器安全方面取得了真正的进展。镜像扫描、签名供应链、无发行版镜像和基于 eBPF 的运行时可见性都是有意义的改进。然而,这些都无法改变所有工作负载仍然共享一个内核的事实,而该内核从未被设计用于隔离数百个不受信任的租户。这种不匹配是当今风险的核心。

它成为了 CVE 权威,并显得大而不能倒

当 Linux 内核成为其自身的 CVE 编号机构时,它为行业提供了一个更清晰的窗口,可以了解内核漏洞被发现的频率。2025 年初,仅仅内核在几周内就产生了 100 多个常见漏洞和暴露 (CVE),平均每天约八个。这些不是镜像级别的问题。它们适用于在该节点上运行的每个容器。

更新镜像很简单。更新内核则不然。内核升级需要节点级别的干预,通常需要重启,并需要精心安排的流量疏导。影响范围很大,因此许多团队会推迟这项工作。随着时间的推移,节点会累积数百甚至数千个内核 CVE,同时继续运行关键工作负载。将这一点与内核是整个集群的唯一共享边界这一事实结合起来,风险就变得显而易见。如果内核出问题,一切都会出问题。

利用内核已成为一个 N 日问题

仍然有人认为,攻破内核需要国家级的才能。实际上,我们生活在一个 N 日世界。供应商修复了错误,CVE 发布了,但由于系统更新缓慢,漏洞利用在数月或数年内仍然有效。

我们研究的一个例子是 netfilter 中的一个 use-after-free 错误,该错误在 2024 年初得到修复,但在 2025 年末仍被用于勒索软件攻击。公共仓库提供了利用代码甚至预编译的二进制文件。在非特权容器内运行它可以获得主机的 root 权限。这一个动作就抹去了内核强制执行的所有边界。此时,唯一的安全举动是重建节点。

这其中没有巫术。没有深奥的内核知识。只有一个公开的漏洞利用和一个过时的内核。这就是 N 日风险的样子。

用户命名空间与用一个攻击面换取另一个攻击面

用户命名空间在 Kubernetes 中默认启用,并被广泛誉为隔离的胜利。在用户命名空间内,一个进程表现为 root,但在外部映射到一个非特权用户。这在理论上听起来很优雅。

内核并不了解也不关心这个理论。它只是看到一个具有提升权限的进程。这种扩展的权限暴露了进程以前无法触及的内核代码路径。许多最近的内核漏洞正是因此依赖于用户命名空间。它们用一个攻击面换取另一个攻击面。用户命名空间解决了实际问题,但它们也拓宽了恶意代码的入口点。它们是一种权衡,而不是安全万灵药。

我们能对共享内核做些什么

内核强化工作是真实且有价值的。像内核自保护项目这样的项目提高了内存安全性并减少了常见的利用技术。这些努力在非常不同的威胁模型下运作:一个用户、一台机器、大部分受信任的代码。Kubernetes 假设的情况恰恰相反。强化有所帮助,但它无法消除共享内核固有的底层架构风险。

仍然存在实际的步骤。Seccomp 可以移除大类系统调用。阻止 unshare 系统调用可以防止许多基于用户命名空间的漏洞利用。避免特权容器和不必要的主机挂载可以减少暴露。这些是漏洞利用前的有意义的防御。一旦内核被攻破,这些都无济于事。

更长期的答案是结构性的。共享内核就像一艘没有水密隔舱的船。一处破损就会淹没整艘船。更强的隔离模型通过为工作负载提供自己的内核或隔离域来限制爆炸半径。公共云管理程序已经证明这是有效的。Apple 的容器化框架展示了将相同原理应用于本地开发环境。这种模式很清晰。

弥补容器安全中的最后一道信任鸿沟

云原生社区取得了巨大的进步。默认设置更安全,供应链更清洁,运行时可见性也比以往任何时候都好。内核安全性也得到了改善,这要归功于致力于极其困难工作的工程师们。

重点不是 Linux 坏了。重点是我们的信任边界需要反映现实。共享内核过于强大和复杂,不能默认假定其安全性。如果我们将已经取得的进展与对内核风险更清晰的理解和更强的隔离方法相结合,我们就可以弥补云原生安全中的最后一个主要差距。是时候将内核纳入对话了。