Pod 和容器的 Linux 内核安全限制

用于加固 Pod 和容器的 Linux 内核安全模块和约束概述。

此页面描述了一些内置于 Linux 内核中的安全特性,你可以在 Kubernetes 工作负载中使用这些特性。要了解如何将这些特性应用于你的 Pod 和容器,请参阅为 Pod 或容器配置 SecurityContext。你应该已经熟悉 Linux 和 Kubernetes 工作负载的基础知识。

以非 root 权限运行工作负载

在 Kubernetes 中部署工作负载时,使用 Pod 规约来限制工作负载以节点上的 root 用户身份运行。你可以使用 Pod 的 securityContext 来为 Pod 中的进程定义特定的 Linux 用户和组,并明确限制容器不得以 root 用户身份运行。在 Pod Manifest 中设置这些值优先于容器镜像中的相似值,这在你运行不属于你的镜像时尤其有用。

配置此页面上的内核安全特性可以对集群中进程可以执行的操作进行细粒度控制,但在大规模环境中管理这些配置可能具有挑战性。以非 root 用户身份运行容器,或者在你需要 root 权限时使用用户命名空间,有助于减少你需要强制执行已配置内核安全能力的可能性。

Linux 内核中的安全特性

Kubernetes 允许你配置和使用 Linux 内核特性来改进隔离并加固你的容器化工作负载。常见的特性包括:

  • 安全计算模式 (seccomp):过滤进程可以进行的系统调用
  • AppArmor:限制单个程序的访问权限
  • Security Enhanced Linux (SELinux):为对象分配安全标签以实现更易管理的安全性策略执行

要配置其中一个特性的设置,你为节点选择的操作系统必须在内核中启用该特性。例如,Ubuntu 7.10 及更高版本默认启用 AppArmor。要了解你的操作系统是否启用了某个特定特性,请查阅操作系统文档。

你可以在 Pod 规约中使用 securityContext 字段来定义适用于这些进程的约束。securityContext 字段还支持其他安全设置,例如使用 UID 和 GID 设置特定的 Linux capability 或文件访问权限。要了解更多信息,请参阅为 Pod 或容器配置 SecurityContext

seccomp

你的某些工作负载可能需要特权才能作为节点主机上的 root 用户执行特定操作。Linux 使用 capabilities 将可用的特权划分为不同的类别,这样进程就可以获得执行特定操作所需的特权,而无需授予所有特权。每个 capability 都有一组进程可以执行的系统调用 (syscalls)。seccomp 允许你限制这些单个 syscall。它可用于对进程的权限进行沙盒化,限制其从用户空间到内核的调用。

在 Kubernetes 中,你在每个节点上使用一个容器运行时 来运行容器。示例运行时包括 CRI-O、Docker 或 containerd。每个运行时默认只允许一部分 Linux capability。你可以通过使用 seccomp profile 来进一步单独限制允许的 syscall。容器运行时通常包含一个默认的 seccomp profile。Kubernetes 允许你将加载到节点上的 seccomp profile 自动应用于你的 Pod 和容器。

要了解如何在 Kubernetes 中实现 seccomp,请参阅使用 seccomp 限制容器的系统调用Seccomp 节点参考

要了解有关 seccomp 的更多信息,请参阅 Linux 内核文档中的Seccomp BPF

seccomp 的注意事项

seccomp 是一种低级安全配置,只有当你需要对 Linux syscall 进行细粒度控制时才应自行配置。使用 seccomp,特别是在大规模环境中,存在以下风险:

  • 应用程序更新期间配置可能失效
  • 攻击者仍然可以使用允许的 syscall 来利用漏洞
  • 大规模环境中单个应用程序的 profile 管理变得具有挑战性

建议:使用容器运行时自带的默认 seccomp profile。如果你需要更隔离的环境,请考虑使用沙盒,例如 gVisor。沙盒解决了自定义 seccomp profile 的上述风险,但需要节点上更多的计算资源,并且可能与 GPU 和其他专用硬件存在兼容性问题。

AppArmor 和 SELinux:基于策略的强制访问控制

你可以使用基于策略的强制访问控制 (MAC) 机制,例如 AppArmor 和 SELinux,来加固你的 Kubernetes 工作负载。

AppArmor

AppArmor 是一个 Linux 内核安全模块,它补充了标准的基于 Linux 用户和组的权限,以将程序限制在一组有限的资源内。可以为任何应用程序配置 AppArmor,以减少其潜在的攻击面并提供更深入的防御。它通过针对特定程序或容器所需的访问进行调整的 profile 来配置,例如 Linux capability、网络访问和文件权限。每个 profile 可以以 enforcing 模式运行,该模式会阻止访问不允许的资源,或者以 complain 模式运行,该模式只报告违规行为。

AppArmor 可以通过限制容器被允许执行的操作和/或通过系统日志提供更好的审计来帮助你运行更安全的部署。你使用的容器运行时可能附带默认的 AppArmor profile,或者你可以使用自定义 profile。

要了解如何在 Kubernetes 中使用 AppArmor,请参阅使用 AppArmor 限制容器对资源的访问

SELinux

SELinux 是一个 Linux 内核安全模块,它允许你限制特定主体(例如进程)对系统上文件的访问。你定义应用于具有特定 SELinux 标签的主体的安全策略。当具有 SELinux 标签的进程尝试访问文件时,SELinux 服务器会检查该进程的安全策略是否允许访问并做出授权决定。

在 Kubernetes 中,你可以在 Manifest 的 securityContext 字段中设置 SELinux 标签。指定的标签会被分配给这些进程。如果你配置了影响这些标签的安全策略,主机的 OS 内核会强制执行这些策略。

要了解如何在 Kubernetes 中使用 SELinux,请参阅为容器分配 SELinux 标签

AppArmor 与 SELinux 之间的差异

你的 Linux 节点上的操作系统通常包含 AppArmor 或 SELinux 中的一个。这两种机制提供类似类型的保护,但在以下方面存在差异:

  • 配置:AppArmor 使用 profile 定义对资源的访问。SELinux 使用适用于特定标签的策略。
  • 策略应用:在 AppArmor 中,你使用文件路径定义资源。SELinux 使用资源的索引节点 (inode) 来标识资源。

特性总结

下表描述了每种安全控制的使用场景和范围。你可以将所有这些控制结合使用来构建一个更安全的系统。

Linux 内核安全特性总结
安全特性描述如何使用示例
seccomp在用户空间中限制单个内核调用。降低利用受限系统调用漏洞破坏系统的可能性。在 Pod 或容器规约中指定已加载的 seccomp profile,以将其约束应用于 Pod 中的进程。拒绝 unshare 系统调用,该系统调用曾被用于 CVE-2022-0185
AppArmor限制程序对特定资源的访问。减少程序的攻击面。改进审计日志记录。在容器规约中指定已加载的 AppArmor profile。限制只读程序写入系统中的任何文件路径。
SELinux使用标签和安全策略限制对文件、应用程序、端口和进程等资源的访问。为特定标签指定访问限制。使用这些标签标记进程,以强制执行与标签相关的访问限制。限制容器访问其自身文件系统之外的文件。

管理自定义配置的注意事项

seccomp、AppArmor 和 SELinux 通常具有提供基本保护的默认配置。你也可以创建满足工作负载需求的自定义 profile 和策略。大规模管理和分发这些自定义配置可能具有挑战性,特别是如果你同时使用这三种特性。为了帮助你在大规模环境中管理这些配置,请使用像 Kubernetes Security Profiles Operator 这样的工具。

内核级安全特性和特权容器

Kubernetes 允许你指定某些受信任的容器可以以特权 (privileged) 模式运行。Pod 中的任何容器都可以以特权模式运行,以使用操作系统管理能力,否则这些能力将无法访问。这适用于 Windows 和 Linux。

特权容器明确覆盖你在工作负载中可能使用的一些 Linux 内核约束,如下所示:

  • seccomp:特权容器以 Unconfined seccomp profile 运行,覆盖你在 Manifest 中指定的任何 seccomp profile。
  • AppArmor:特权容器忽略任何应用的 AppArmor profile。
  • SELinux:特权容器以 unconfined_t 域运行。

特权容器

如果你在容器的 securityContext 字段中设置了 privileged: true 字段,则 Pod 中的任何容器都可以启用特权模式。特权容器会覆盖或撤销许多其他加固设置,例如应用的 seccomp profile、AppArmor profile 或 SELinux 约束。特权容器被授予所有 Linux capability,包括它们不需要的 capability。例如,特权容器中的 root 用户可能能够使用节点上的 CAP_SYS_ADMINCAP_NET_ADMIN capability,从而绕过运行时 seccomp 配置和其他限制。

在大多数情况下,应避免使用特权容器,而是使用 securityContext 字段中的 capabilities 字段授予容器所需的特定 capability。仅在你使用 securityContext 无法授予 capability 时才使用特权模式。这对于需要使用操作系统管理能力(例如操作网络堆栈或访问硬件设备)的容器非常有用。

在 Kubernetes 1.26 及更高版本中,你还可以通过在 Pod 规约的 security context 上设置 windowsOptions.hostProcess 标志,以类似特权模式运行 Windows 容器。有关详细信息和说明,请参阅创建 Windows HostProcess Pod

建议和最佳实践

  • 在配置内核级安全 capability 之前,你应该考虑实现网络级隔离。更多信息,请阅读安全清单
  • 除非必要,通过在 Pod Manifest 中设置特定的用户和组 ID 并指定 runAsNonRoot: true 来以非 root 身份运行 Linux 工作负载。

此外,你可以在 Pod Manifest 中设置 hostUsers: false 来在用户命名空间中运行工作负载。这允许你在用户命名空间中以 root 用户身份运行容器,但在节点的主机命名空间中以非 root 用户身份运行。这仍处于早期开发阶段,可能没有你所需的支援级别。有关说明,请参阅将用户命名空间与 Pod 一起使用

下一步

上次修改于 2024 年 9 月 17 日太平洋标准时间 10:57 AM:添加专门的 seccomp 节点参考 (c2b49fee37)