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
字段还支持其他安全设置,例如特定的 Linux 功能或使用 UID 和 GID 的文件访问权限。要了解更多信息,请参阅为 Pod 或容器配置 SecurityContext。
seccomp
你的一些工作负载可能需要权限才能以节点主机上的 root 用户身份执行特定操作。Linux 使用*功能*将可用权限划分为多个类别,以便进程可以获得执行特定操作所需的权限,而无需授予所有权限。每个功能都有一组进程可以进行的系统调用(系统调用)。seccomp 允许你限制这些单独的系统调用。它可用于对进程的权限进行沙箱处理,限制它能够从用户空间到内核进行的调用。
在 Kubernetes 中,你在每个节点上使用*容器运行时*来运行你的容器。示例运行时包括 CRI-O、Docker 或 containerd。默认情况下,每个运行时只允许一部分 Linux 功能。你可以使用 seccomp 配置文件进一步限制允许的系统调用。容器运行时通常包含默认的 seccomp 配置文件。Kubernetes 允许你将加载到节点上的 seccomp 配置文件自动应用于你的 Pod 和容器。
注意
Kubernetes 还为 Pod 和容器提供了allowPrivilegeEscalation
设置。设置为 false
时,这可以防止进程获得新功能,并限制非特权用户将应用的 seccomp 配置文件更改为更宽松的配置文件。要了解如何在 Kubernetes 中实现 seccomp,请参阅使用 seccomp 限制容器的系统调用。
要详细了解 seccomp,请参阅 Linux 内核文档中的Seccomp BPF。
seccomp 的注意事项
seccomp 是一种低级安全配置,只有在你需要对 Linux 系统调用进行细粒度控制时,才应该自行配置。使用 seccomp(尤其是在大规模使用时)存在以下风险
- 配置可能会在应用程序更新期间中断
- 攻击者仍然可以使用允许的系统调用来利用漏洞
- 单个应用程序的配置文件管理在大规模情况下变得具有挑战性
**建议**:使用容器运行时捆绑的默认 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 | 限制用户空间中的单个内核调用。降低使用受限系统调用的漏洞危害系统的可能性。 | 在 Pod 或容器规范中指定已加载的 seccomp 配置文件,以将其约束应用于 Pod 中的进程。 | 拒绝在 CVE-2022-0185 中使用的 unshare 系统调用。 |
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 一起使用。