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 允许你限制这些单独的系统调用。它可以用来沙箱化进程的特权,限制其从用户空间到内核的调用。
在 Kubernetes 中,你在每个节点上使用一个容器运行时来运行你的容器。示例运行时包括 CRI-O、Docker 或 containerd。默认情况下,每个运行时仅允许 Linux 功能的一个子集。你可以通过使用 seccomp 配置文件进一步限制允许的单独系统调用。容器运行时通常包含一个默认的 seccomp 配置文件。Kubernetes 允许你自动将加载到节点上的 seccomp 配置文件应用于你的 Pod 和容器。
注意
Kubernetes 还具有 Pod 和容器的allowPrivilegeEscalation
设置。当设置为 false
时,这将阻止进程获得新的功能,并限制非特权用户将应用的 seccomp 配置文件更改为更宽松的配置文件。要了解如何在 Kubernetes 中实现 seccomp,请参阅使用 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 规范的 security context 上设置 windowsOptions.hostProcess
标志,以类似的特权模式运行 Windows 容器。有关详细信息和说明,请参阅创建 Windows HostProcess Pod。
建议和最佳实践
- 在配置内核级安全功能之前,应考虑实施网络级隔离。有关更多信息,请阅读安全检查清单。
- 除非必要,否则通过在 Pod 清单中设置特定的用户和组 ID 并指定
runAsNonRoot: true
,以非 root 用户身份运行 Linux 工作负载。
此外,你可以通过在 Pod 清单中设置 hostUsers: false
在用户命名空间中运行工作负载。这使你可以在用户命名空间中以 root 用户身份运行容器,但在节点上的主机命名空间中以非 root 用户身份运行。这仍处于开发的早期阶段,可能没有你需要的支持级别。有关说明,请参阅在 Pod 中使用用户命名空间。