Pod 和容器的 Linux 内核安全约束
此页面描述了一些内置于 Linux 内核中的安全功能,您可以将其用于 Kubernetes 工作负载。要了解如何将这些功能应用于您的 Pod 和容器,请参阅为 Pod 或容器配置 SecurityContext。您应该已经熟悉 Linux 和 Kubernetes 工作负载的基本知识。
以非 root 权限运行工作负载
在 Kubernetes 中部署工作负载时,请使用 Pod 规范来限制该工作负载在节点上以 root 用户身份运行。您可以使用 Pod securityContext
来定义 Pod 中进程的特定 Linux 用户和组,并明确限制容器以 root 用户身份运行。在 Pod 清单中设置这些值优先于容器镜像中的类似值,这对于运行您不拥有的镜像特别有用。
注意
确保您为工作负载分配的用户或组拥有应用程序正常运行所需的权限。将用户或组更改为没有正确权限的用户或组可能会导致文件访问问题或操作失败。配置此页面上的内核安全功能可以对集群中的进程可以执行的操作进行细粒度控制,但大规模管理这些配置可能很困难。以非 root 身份运行容器,或者如果您需要 root 权限则在用户命名空间中运行容器,有助于降低您需要强制执行已配置的内核安全功能的可能性。
Linux 内核中的安全功能
Kubernetes 允许您配置和使用 Linux 内核功能来提高隔离并加强您的容器化工作负载。常见功能包括以下内容
- 安全计算模式 (seccomp):过滤进程可以执行的系统调用
- AppArmor:限制单个程序的访问权限
- 安全增强 Linux (SELinux):为对象分配安全标签,以更易于管理安全策略强制执行
要为这些功能之一配置设置,您为节点选择的操作系统必须在内核中启用该功能。例如,Ubuntu 7.10 及更高版本默认启用 AppArmor。要了解您的操作系统是否启用特定功能,请查阅操作系统文档。
您使用 Pod 规范中的 securityContext
字段来定义应用于这些进程的约束。securityContext
字段还支持其他安全设置,例如使用 UID 和 GID 的特定 Linux 功能或文件访问权限。要了解更多信息,请参阅为 Pod 或容器配置 SecurityContext.
seccomp
您的一些工作负载可能需要权限才能以 root 用户身份在节点的主机上执行特定操作。Linux 使用功能将可用权限划分为类别,以便进程可以获得执行特定操作所需的权限,而无需授予所有权限。每个功能都有一组进程可以执行的系统调用(syscall)。seccomp 允许您限制这些单独的 syscall。它可以用来隔离进程的权限,限制它可以从用户空间到内核的调用。
在 Kubernetes 中,您在每个节点上使用容器运行时来运行您的容器。运行时示例包括 CRI-O、Docker 或 containerd。每个运行时默认只允许使用一部分 Linux 功能。您可以使用 seccomp 配置文件进一步限制允许的 syscall。容器运行时通常包含一个默认的 seccomp 配置文件。Kubernetes 允许您将自动应用到节点上的 seccomp 配置文件应用到您的 Pod 和容器。
注意
Kubernetes 还为 Pod 和容器设置了allowPrivilegeEscalation
。当设置为 false
时,这将阻止进程获得新的功能并限制无特权用户将应用的 seccomp 配置文件更改为更宽松的配置文件。要了解如何在 Kubernetes 中实现 seccomp,请参阅使用 seccomp 限制容器的 syscall.
要了解更多有关 seccomp 的信息,请参阅 Linux 内核文档中的Seccomp BPF。
seccomp 的注意事项
seccomp 是一种低级安全配置,您只有在需要对 Linux syscall 进行细粒度控制时才应自行配置。使用 seccomp,尤其是在大规模情况下,存在以下风险
- 配置可能会在应用程序更新期间中断
- 攻击者仍然可以使用允许的 syscall 利用漏洞
- 针对单个应用程序的配置文件管理在大规模情况下变得具有挑战性
建议:使用容器运行时捆绑的默认 seccomp 配置文件。如果您需要更隔离的环境,请考虑使用沙盒,例如 gVisor。沙盒使用自定义 seccomp 配置文件解决了前面的风险,但需要在您的节点上使用更多计算资源,并且可能与 GPU 和其他专用硬件存在兼容性问题。
AppArmor 和 SELinux:基于策略的强制访问控制
您可以使用 Linux 基于策略的强制访问控制 (MAC) 机制(如 AppArmor 和 SELinux)来加强您的 Kubernetes 工作负载。
AppArmor
AppArmor 是一个 Linux 内核安全模块,它补充了标准的 Linux 用户和组基于权限的机制来限制程序对一组有限的资源的访问。AppArmor 可以为任何应用程序配置,以减少其潜在的攻击面并提供更深入的防御。它通过配置文件进行配置,这些配置文件经过调整以允许特定程序或容器(如 Linux 功能、网络访问和文件权限)所需的访问权限。每个配置文件可以以强制模式运行,该模式阻止对不允许的资源的访问,或者以抱怨模式运行,该模式只报告违规。
AppArmor 可以通过限制容器允许执行的操作来帮助您运行更安全的部署,或者通过系统日志提供更好的审核。您使用的容器运行时可能会附带一个默认的 AppArmor 配置文件,或者您可以使用自定义配置文件。
要了解如何在 Kubernetes 中使用 AppArmor,请参阅使用 AppArmor 限制容器对资源的访问.
SELinux
SELinux 是一个 Linux 内核安全模块,它允许您限制特定主体(例如进程)对系统上文件的访问权限。您定义应用于具有特定 SELinux 标签的主体的安全策略。当具有 SELinux 标签的进程尝试访问文件时,SELinux 服务器会检查该进程的安全策略是否允许访问并做出授权决定。
在 Kubernetes 中,您可以在清单的 securityContext
字段中设置 SELinux 标签。指定的标签将分配给这些进程。如果您已配置影响这些标签的安全策略,则主机操作系统内核将强制执行这些策略。
要了解如何在 Kubernetes 中使用 SELinux,请参阅为容器分配 SELinux 标签.
AppArmor 和 SELinux 之间的区别
Linux 节点上的操作系统通常包含 AppArmor 或 SELinux 之一。这两种机制都提供了类似类型的保护,但存在一些差异,例如以下差异
- 配置:AppArmor 使用配置文件来定义对资源的访问权限。SELinux 使用应用于特定标签的策略。
- 策略应用:在 AppArmor 中,您使用文件路径定义资源。SELinux 使用资源的索引节点 (inode) 来标识资源。
功能摘要
下表描述了每个安全控制的使用案例和范围。您可以将所有这些控制一起使用来构建更强大的系统。
安全功能 | 描述 | 使用方法 | 示例 |
---|---|---|---|
seccomp | 限制用户空间中的单个内核调用。降低利用受限 syscall 的漏洞危害系统的可能性。 | 在 Pod 或容器规范中指定一个加载的 seccomp 配置文件,以将其约束应用于 Pod 中的进程。 | 拒绝 unshare syscall,该 syscall 在CVE-2022-0185 中使用。 |
AppArmor | 限制程序对特定资源的访问。减少程序的攻击面。改进审计日志记录。 | 在容器规范中指定一个加载的 AppArmor 配置文件。 | 限制只读程序写入系统中的任何文件路径。 |
SELinux | 使用标签和安全策略限制对资源(如文件、应用程序、端口和进程)的访问。 | 指定特定标签的访问限制。用这些标签标记进程以强制执行与标签相关的访问限制。 | 限制容器访问其自身文件系统之外的文件。 |
注意
AppArmor 和 SELinux 等机制可以提供超出容器范围的保护。例如,您可以使用 SELinux 来帮助缓解CVE-2019-5736。管理自定义配置的注意事项
seccomp、AppArmor 和 SELinux 通常具有提供基本保护的默认配置。您还可以创建满足工作负载要求的自定义配置文件和策略。在大规模情况下管理和分发这些自定义配置可能具有挑战性,尤其是在您将所有三个功能一起使用时。为了帮助您在大规模情况下管理这些配置,请使用Kubernetes 安全配置文件操作员 等工具。
内核级安全功能和特权容器
Kubernetes 允许您指定某些受信任的容器可以在特权模式下运行。Pod 中的任何容器都可以以特权模式运行,以使用否则无法访问的操作系统管理功能。此功能适用于 Windows 和 Linux。
特权容器明确地覆盖了您可能在工作负载中使用的一些 Linux 内核约束,如下所示
- seccomp:特权容器以
Unconfined
seccomp 配置文件运行,覆盖您在清单中指定的任何 seccomp 配置文件。 - AppArmor:特权容器会忽略任何应用的 AppArmor 配置文件。
- SELinux:特权容器以
unconfined_t
域运行。
特权容器
如果您在容器的 securityContext
字段中设置了 privileged: true
字段,则 Pod 中的任何容器都可以启用特权模式。特权容器会覆盖或撤消许多其他加固设置,例如应用的 seccomp 配置文件、AppArmor 配置文件或 SELinux 约束。特权容器被授予所有 Linux 功能,包括它们不需要的功能。例如,特权容器中的 root 用户可能能够在节点上使用 CAP_SYS_ADMIN
和 CAP_NET_ADMIN
功能,从而绕过运行时 seccomp 配置和其他限制。
在大多数情况下,您应该避免使用特权容器,而应使用 securityContext
字段中的 capabilities
字段授予容器所需的特定功能。只有在您无法通过 securityContext 授予功能的情况下,才使用特权模式。这对于想要使用操作系统管理功能(如操作网络堆栈或访问硬件设备)的容器很有用。
在 Kubernetes 1.26 及更高版本中,您还可以通过在 Pod 规范的安全上下文中设置 windowsOptions.hostProcess
标志,以类似的特权模式运行 Windows 容器。有关详细信息和说明,请参阅 创建 Windows HostProcess Pod。
建议和最佳实践
- 在配置内核级安全功能之前,您应该考虑实施网络级隔离。有关更多信息,请阅读 安全检查清单。
- 除非必要,请通过在 Pod 清单中设置特定的用户和组 ID 以及指定
runAsNonRoot: true
来以非 root 用户身份运行 Linux 工作负载。
此外,您可以在用户命名空间中运行工作负载,方法是在 Pod 清单中设置 hostUsers: false
。这使您可以在用户命名空间中以 root 用户身份运行容器,但在节点上的主机命名空间中以非 root 用户身份运行。这仍处于开发的早期阶段,可能没有您需要的支持级别。有关说明,请参阅 使用 Pod 的用户命名空间。