系统调用拦截

Incus 支持拦截来自非特权容器的一些特定系统调用。如果它们被认为是安全的,它将在主机上以提升的权限执行它们。

这样做会对相关系统调用产生性能影响,并且会导致 Incus 评估请求并(如果允许)以提升的权限处理请求。

特定系统调用拦截选项的启用是通过容器配置选项在每个容器的基础上完成的。

可用的系统调用

mknod / mknodat

mknodmknodat 系统调用可用于创建各种特殊文件。

在容器内部最常见的是,它们可能被调用来创建块或字符设备。在非特权容器中不允许创建此类设备,因为这是一种非常容易通过允许对磁盘或内存等资源的直接写访问来提升权限的方法。

但是,有些文件是安全的。对于这些文件,拦截此系统调用可能会解除某些特定工作负载的阻塞,并允许它们在非特权容器中运行。

当前允许的设备为

  • overlayfs 隐藏文件 (char 0:0)

  • /dev/console (char 5:1)

  • /dev/full (char 1:7)

  • /dev/null (char 1:3)

  • /dev/random (char 1:8)

  • /dev/tty (char 5:0)

  • /dev/urandom (char 1:9)

  • /dev/zero (char 1:5)

除了字符设备之外的所有文件类型目前都像往常一样发送到内核,因此启用此功能不会改变它们的行为。

这可以通过将 security.syscalls.intercept.mknod 设置为 true 来启用。

bpf

bpf 系统调用用于管理内核中的 eBPF 程序。这些程序可以附加到各种内核子系统。

通常,加载不受信任的 eBPF 程序可能存在问题,因为它可以促进基于时间的攻击。

Incus 的 eBPF 支持目前仅限于管理设备 cgroup 条目的程序。要启用它,您需要将 security.syscalls.intercept.bpfsecurity.syscalls.intercept.bpf.devices 都设置为 true。

mount

mount 系统调用允许挂载物理和虚拟文件系统。默认情况下,内核会限制非特权容器仅使用少数虚拟和网络文件系统。

要允许挂载物理文件系统,可以使用系统调用拦截。Incus 提供了各种选项来处理此问题。

security.syscalls.intercept.mount 用于控制整个功能,并且需要为任何其他选项工作而打开。

security.syscalls.intercept.mount.allowed 允许指定可以在容器中直接挂载的文件系统列表。这是最危险的选项,因为它允许用户向内核提供不受信任的数据。这很容易用来崩溃主机系统或攻击它。它仅应在受信任的环境中使用。

security.syscalls.intercept.mount.shift 可以在此基础上设置,以便将结果挂载转移到容器使用的 UID/GID 映射。这需要避免在非特权容器内所有内容都显示为 nobody/nogroup

与之相比,一个更安全的替代方案是security.syscalls.intercept.mount.fuse,它可以设置为文件系统名称和 FUSE 处理程序的配对。当设置此选项时,尝试挂载其中一个已配置的文件系统将被透明地重定向,转而调用该文件系统的 FUSE 等效项。

由于所有这些都在调用者权限下运行,因此避免了围绕内核攻击面的整个问题,因此通常被认为是安全的,但您应该记住,任何类型的系统调用拦截都为使主机系统过载提供了一种简单的方法。

sched_setscheduler

sched_setscheduler系统调用用于管理进程优先级。

授予此权限可能会允许用户大幅提高其进程的优先级,从而可能占用大量系统资源。

它还允许访问诸如SCHED_FIFO之类的调度程序,这些调度程序通常被认为存在缺陷,并且会严重影响整体系统稳定性。这就是为什么在正常情况下,只有真正的 root 用户(或全局CAP_SYS_NICE)才会允许使用它的原因。

setxattr

setxattr系统调用用于设置文件的扩展属性。

当前由其处理的属性为

  • trusted.overlay.opaque(overlayfs 目录白洞)

请注意,由于仲裁必须发生在一系列字符字符串上,因此目前没有简单的方法只拦截我们关心的几个属性。由于我们只允许上述属性,因此这可能会导致以前由内核允许的其他属性出现故障。

可以通过将security.syscalls.intercept.setxattr设置为true来启用此功能。

sysinfo

sysinfo系统调用被一些发行版用来代替/proc/条目报告资源使用情况。

为了提供特定于容器而不是整个系统的资源使用信息,此系统调用拦截模式使用基于 cgroup 的资源使用信息来填充系统调用响应。