随着云计算的发展,容器继续变得越来越流行。我们实现容器的方式正在引入新的解决方案和想法。其中一个新想法是无根容器。
无根容器是一个新的容器概念,它不需要root权限即可制定。已经提出了许多解决方案来克服创建具有非特权用户的容器的技术挑战,其中一些仍在开发中,一些已经准备好投入生产。虽然无根容器呈现出一些优势,主要是从安全角度来看,但它们仍处于早期阶段。
在这篇文章中,第42单元研究员Aviv Sasson回顾了无根容器的内部结构。Aviv还提供了他在其中一个名为Slirp的主要无根网络组件中发现的漏洞。运行Prisma Cloud的Palo Alto Networks客户可通过主机和容器漏洞扫描程序保护其免受此漏洞的攻击,该扫描程序会对使用此漏洞运行的软件组件发出警报。
顾名思义,无根容器与传统容器相同,但不同之处在于它们不需要root特权即可形成。
如今,无根容器仍处于早期采用阶段,但已经得到该领域主要参与者的支持。
添加新的安全层。如果容器引擎、运行时或协调器受到危害,攻击者将不会获得主机上的root权限。
Linux内核中的一项新开发使此解决方案成为可能,它允许非特权用户创建新的用户名称空间。当用户创建并输入新的用户名称空间时,他将成为该名称空间上下文中的root用户,并获得生成正常运行的容器所需的大部分权限。
我不会深入研究用户命名空间的技术细节,但是在影响整个系统的区域中,命名空间根没有真正的根拥有特权(例如,命名空间根不能加载或删除内核模块)。这导致了由每个容器引擎以不同方式解决的一些挑战。
为了在容器内实现适当的联网,通常会创建一个虚拟以太网设备(Veth)并负责联网。这给无根容器带来了问题,因为只有真正的root才有权创建这样的设备。提出了许多解决方案来解决该问题-主要的解决方案是Slirp和LXC-User-NIC。
Slirp是一个广为人知的项目,最初主要用于QEMU(又名Quick Emulator)中的联网。经过一些修改后,它被调整为在无根容器中启用网络。它的工作方式是分叉到容器的用户和网络名称空间,并创建一个成为默认路由的分路设备。然后,它将设备的文件描述符传给在默认网络名称空间中运行的父设备,该父设备现在可以与容器和Internet进行通信。
设置网络的另一种方法是运行创建veth设备的setuid二进制文件。尽管它确实启用了容器内部的网络,但它忽略了无根容器的要点,因为它要求容器二进制文件以root权限运行。
实现容器的一个复杂元素是存储管理。默认情况下,容器引擎使用称为Overlay2(或Overlay)的特殊驱动程序来创建空间和性能都很高效的分层文件系统。使用无根容器不能做到这一点,因为大多数Linux发行版不允许在用户名称空间中挂载覆盖文件系统(Ubuntu是个例外)。这个问题驱使无根容器与其他驱动程序和文件系统一起工作。
显而易见的解决方案是使用另一个驱动程序,如VFS存储驱动程序。虽然它起作用了,但它的效率要低得多。更好的解决方案是创建一个新的存储驱动程序来满足无根容器的需要。一个这样的驱动器是FUSE-OverlayFS。它是Overlay的用户空间实现,比VFS更高效,并且可以在用户名称空间内运行。
Linux控制组(Cgroup)特性是实现容器的另一个关键元素,它允许将进程和容器组织成分层的组,然后可以限制和监视各种类型的资源的使用。由于内核的cgroups接口是通过伪文件系统提供的,该伪文件系统通常驻留在“/sys”(根拥有的目录)中,因此非root用户无法访问和使用它。
cgroup的新内核实现,支持将权限委派给非特权用户。缺点是V2不支持为cgroups V1实现的所有控制器(例如,DEVICES、NET_CLS、NET_PRIO等)。
LXC针对该问题的另一个解决方案是安装pam_cgfs.so,这是一个可插拔的身份验证模块(PAM模块),允许非特权用户对cgroup进行身份验证和管理。