Pod 安全性标准
详细了解 Pod 安全性标准(Pod Security Standards)中所定义的不同策略级别。
Pod 安全性标准定义了三种不同的策略(Policy),以广泛覆盖安全应用场景。 这些策略是叠加式的(Cumulative),安全级别从高度宽松至高度受限。 本指南概述了每个策略的要求。
Profile | 描述 |
---|
Privileged | 不受限制的策略,提供最大可能范围的权限许可。此策略允许已知的特权提升。 |
Baseline | 限制性最弱的策略,禁止已知的特权提升。允许使用默认的(规定最少)Pod 配置。 |
Restricted | 限制性非常强的策略,遵循当前的保护 Pod 的最佳实践。 |
Profile 细节
Privileged
Privileged 策略是有目的地开放且完全无限制的策略。 此类策略通常针对由特权较高、受信任的用户所管理的系统级或基础设施级负载。
Privileged 策略定义中限制较少。默认允许的(Allow-by-default)实施机制(例如 gatekeeper) 可以缺省设置为 Privileged。 与此不同,对于默认拒绝(Deny-by-default)的实施机制(如 Pod 安全策略)而言, Privileged 策略应该禁止所有限制。
Baseline
Baseline 策略的目标是便于常见的容器化应用采用,同时禁止已知的特权提升。 此策略针对的是应用运维人员和非关键性应用的开发人员。 下面列举的控制应该被实施(禁止):
说明:
在下述表格中,通配符(*
)意味着一个列表中的所有元素。 例如 spec.containers[*].securityContext
表示所定义的所有容器的安全性上下文对象。 如果所列出的任一容器不能满足要求,整个 Pod 将无法通过校验。
Baseline 策略规范控制(Control) | 策略(Policy) |
HostProcess | Windows Pod 提供了运行 HostProcess 容器 的能力,这使得对 Windows 节点的特权访问成为可能。Baseline 策略中禁止对宿主的特权访问。 特性状态: Kubernetes v1.26 [stable] 限制的字段 spec.securityContext.windowsOptions.hostProcess spec.containers[].securityContext.windowsOptions.hostProcess spec.initContainers[ ].securityContext.windowsOptions.hostProcess spec.ephemeralContainers[].securityContext.windowsOptions.hostProcess
准许的取值 |
宿主名字空间 | 必须禁止共享宿主上的名字空间。 限制的字段 spec.hostNetwork spec.hostPID spec.hostIPC
准许的取值 |
特权容器 | 特权 Pod 会使大多数安全性机制失效,必须被禁止。 限制的字段 spec.containers[].securityContext.privileged spec.initContainers[].securityContext.privileged spec.ephemeralContainers[ ].securityContext.privileged
准许的取值 |
权能 | 必须禁止添加除下列字段之外的权能。 限制的字段 spec.containers[].securityContext.capabilities.add spec.initContainers[ ].securityContext.capabilities.add spec.ephemeralContainers[].securityContext.capabilities.add
准许的取值 - 未定义、nil
AUDIT_WRITE CHOWN DAC_OVERRIDE FOWNER FSETID KILL MKNOD NET_BIND_SERVICE SETFCAP SETGID SETPCAP SETUID SYS_CHROOT
|
HostPath 卷 | 必须禁止 HostPath 卷。 限制的字段 准许的取值 |
宿主端口 | 应该完全禁止使用宿主端口(推荐)或者至少限制只能使用某确定列表中的端口。 限制的字段 spec.containers[].ports[].hostPort spec.initContainers[].ports[].hostPort spec.ephemeralContainers[].ports[].hostPort
准许的取值 |
AppArmor | 在受支持的主机上,默认使用 runtime/default AppArmor 配置。Baseline 策略应避免覆盖或者禁用默认策略,以及限制覆盖一些配置集合的权限。 限制的字段 metadata.annotations[“container.apparmor.security.beta.kubernetes.io/“]
准许的取值 - 未定义、nil
runtime/default localhost/
|
SELinux | 设置 SELinux 类型的操作是被限制的,设置自定义的 SELinux 用户或角色选项是被禁止的。 限制的字段 spec.securityContext.seLinuxOptions.type spec.containers[].securityContext.seLinuxOptions.type spec.initContainers[ ].securityContext.seLinuxOptions.type spec.ephemeralContainers[].securityContext.seLinuxOptions.type
准许的取值 - 未定义、””
container_t container_init_t container_kvm_t
限制的字段 spec.securityContext.seLinuxOptions.user spec.containers[ ].securityContext.seLinuxOptions.user spec.initContainers[].securityContext.seLinuxOptions.user spec.ephemeralContainers[ ].securityContext.seLinuxOptions.user spec.securityContext.seLinuxOptions.role spec.containers[].securityContext.seLinuxOptions.role spec.initContainers[ ].securityContext.seLinuxOptions.role spec.ephemeralContainers[].securityContext.seLinuxOptions.role
准许的取值 |
/proc 挂载类型 | 要求使用默认的 /proc 掩码以减小攻击面。 限制的字段 spec.containers[].securityContext.procMount spec.initContainers[].securityContext.procMount spec.ephemeralContainers[ ].securityContext.procMount
准许的取值 |
Seccomp | Seccomp 配置必须不能显式设置为 Unconfined 。 限制的字段 spec.securityContext.seccompProfile.type spec.containers[].securityContext.seccompProfile.type spec.initContainers[ ].securityContext.seccompProfile.type spec.ephemeralContainers[].securityContext.seccompProfile.type
准许的取值 - 未定义、nil
RuntimeDefault Localhost
|
Sysctls | Sysctls 可以禁用安全机制或影响宿主上所有容器,因此除了若干“安全”的子集之外,应该被禁止。如果某 sysctl 是受容器或 Pod 的名字空间限制,且与节点上其他 Pod 或进程相隔离,可认为是安全的。 限制的字段 spec.securityContext.sysctls[].name
准许的取值 - 未定义、nil
kernel.shm_rmid_forced net.ipv4.ip_local_port_range net.ipv4.ip_unprivileged_port_start net.ipv4.tcp_syncookies net.ipv4.ping_group_range net.ipv4.ip_local_reserved_ports (从 Kubernetes 1.27 开始)net.ipv4.tcp_keepalive_time (从 Kubernetes 1.29 开始)net.ipv4.tcp_fin_timeout (从 Kubernetes 1.29 开始)net.ipv4.tcp_keepalive_intvl (从 Kubernetes 1.29 开始)net.ipv4.tcp_keepalive_probes (从 Kubernetes 1.29 开始)
|
Restricted
Restricted 策略旨在实施当前保护 Pod 的最佳实践,尽管这样作可能会牺牲一些兼容性。 该类策略主要针对运维人员和安全性很重要的应用的开发人员,以及不太被信任的用户。 下面列举的控制需要被实施(禁止):
说明:
在下述表格中,通配符(*
)意味着一个列表中的所有元素。 例如 spec.containers[*].securityContext
表示 所定义的所有容器 的安全性上下文对象。 如果所列出的任一容器不能满足要求,整个 Pod 将无法通过校验。
Restricted 策略规范控制 | 策略 |
Baseline 策略的所有要求。 |
卷类型 | 除了限制 HostPath 卷之外,此类策略还限制可以通过 PersistentVolumes 定义的非核心卷类型。 限制的字段 准许的取值 spec.volumes[ ] 列表中的每个条目必须将下面字段之一设置为非空值:spec.volumes[].configMap spec.volumes[ ].csi spec.volumes[].downwardAPI spec.volumes[ ].emptyDir spec.volumes[].ephemeral spec.volumes[ ].persistentVolumeClaim spec.volumes[].projected spec.volumes[ ].secret
|
特权提升(v1.8+) | 禁止(通过 SetUID 或 SetGID 文件模式)获得特权提升。这是 v1.25+ 中仅针对 Linux 的策略 (spec.os.name != windows) 限制的字段 spec.containers[].securityContext.allowPrivilegeEscalation spec.initContainers[ ].securityContext.allowPrivilegeEscalation spec.ephemeralContainers[].securityContext.allowPrivilegeEscalation
允许的取值 |
以非 root 账号运行 | 容器必须以非 root 账号运行。 限制的字段 spec.securityContext.runAsNonRoot spec.containers[].securityContext.runAsNonRoot spec.initContainers[].securityContext.runAsNonRoot spec.ephemeralContainers[ ].securityContext.runAsNonRoot
准许的取值 如果 Pod 级别 spec.securityContext.runAsNonRoot 设置为 true ,则允许容器组的安全上下文字段设置为 未定义/nil 。 |
非 root 用户(v1.23+) | 容器不可以将 runAsUser 设置为 0 限制的字段 spec.securityContext.runAsUser spec.containers[].securityContext.runAsUser spec.initContainers[ ].securityContext.runAsUser spec.ephemeralContainers[].securityContext.runAsUser
准许的取值 |
Seccomp (v1.19+) | Seccomp Profile 必须被显式设置成一个允许的值。禁止使用 Unconfined Profile 或者指定 不存在的 Profile。这是 v1.25+ 中仅针对 Linux 的策略 (spec.os.name != windows) 限制的字段 spec.securityContext.seccompProfile.type spec.containers[].securityContext.seccompProfile.type spec.initContainers[].securityContext.seccompProfile.type spec.ephemeralContainers[ ].securityContext.seccompProfile.type
准许的取值 如果 Pod 级别的 spec.securityContext.seccompProfile.type 已设置得当,容器级别的安全上下文字段可以为未定义/nil 。 反之如果 所有的 容器级别的安全上下文字段已设置, 则 Pod 级别的字段可为 未定义/nil 。 |
权能(v1.22+) | 容器必须弃用 ALL 权能,并且只允许添加 NET_BIND_SERVICE 权能。这是 v1.25+ 中仅针对 Linux 的策略 (.spec.os.name != “windows”) 限制的字段 spec.containers[].securityContext.capabilities.drop spec.initContainers[ ].securityContext.capabilities.drop spec.ephemeralContainers[].securityContext.capabilities.drop
准许的取值
限制的字段 spec.containers[ ].securityContext.capabilities.add spec.initContainers[].securityContext.capabilities.add spec.ephemeralContainers[ ].securityContext.capabilities.add
准许的取值 |
策略实例化
将策略定义从策略实例中解耦出来有助于形成跨集群的策略理解和语言陈述, 以免绑定到特定的下层实施机制。
随着相关机制的成熟,这些机制会按策略分别定义在下面。特定策略的实施方法不在这里定义。
Pod 安全性准入控制器
替代方案
说明: 本部分链接到提供 Kubernetes 所需功能的第三方项目。Kubernetes 项目作者不负责这些项目。此页面遵循CNCF 网站指南,按字母顺序列出项目。要将项目添加到此列表中,请在提交更改之前阅读内容指南。
在 Kubernetes 生态系统中还在开发一些其他的替代方案,例如:
Pod OS 字段
Kubernetes 允许你使用运行 Linux 或 Windows 的节点。你可以在一个集群中混用两种类型的节点。 Kubernetes 中的 Windows 与基于 Linux 的工作负载相比有一些限制和差异。 具体而言,许多 Pod securityContext
字段在 Windows 上不起作用。
说明:
v1.24 之前的 Kubelet 不强制处理 Pod OS 字段,如果集群中有些节点运行早于 v1.24 的版本, 则应将限制性的策略锁定到 v1.25 之前的版本。
限制性的 Pod Security Standard 变更
Kubernetes v1.25 中的另一个重要变化是限制性的(Restricted) Pod 安全性已更新, 能够处理 pod.spec.os.name
字段。根据 OS 名称,专用于特定 OS 的某些策略对其他 OS 可以放宽限制。
OS 特定的策略控制
仅当 .spec.os.name
不是 windows
时,才需要对以下控制进行限制:
用户命名空间
用户命名空间是 Linux 特有的功能,可在运行工作负载时提高隔离度。 关于用户命名空间如何与 PodSecurityStandard 协同工作, 请参阅 文档 了解 Pod 如何使用用户命名空间。
常见问题
为什么不存在介于 Privileged 和 Baseline 之间的策略类型
这里定义的三种策略框架有一个明晰的线性递进关系,从最安全(Restricted)到最不安全, 并且覆盖了很大范围的工作负载。特权要求超出 Baseline 策略者通常是特定于应用的需求, 所以我们没有在这个范围内提供标准框架。 这并不意味着在这样的情形下仍然只能使用 Privileged 框架, 只是说处于这个范围的策略需要因地制宜地定义。
SIG Auth 可能会在将来考虑这个范围的框架,前提是有对其他框架的需求。
安全配置与安全上下文的区别是什么?
安全上下文在运行时配置 Pod 和容器。安全上下文是在 Pod 清单中作为 Pod 和容器规约的一部分来定义的, 所代表的是传递给容器运行时的参数。
安全策略则是控制面用来对安全上下文以及安全性上下文之外的参数实施某种设置的机制。 在 2020 年 7 月, Pod 安全性策略已被废弃, 取而代之的是内置的 Pod 安全性准入控制器。
沙箱(Sandboxed)Pod 怎么处理?
现在还没有 API 标准来控制 Pod 是否被视作沙箱化 Pod。 沙箱 Pod 可以通过其是否使用沙箱化运行时(如 gVisor 或 Kata Container)来辨别, 不过目前还没有关于什么是沙箱化运行时的标准定义。
沙箱化负载所需要的保护可能彼此各不相同。例如,当负载与下层内核直接隔离开来时, 限制特权化操作的许可就不那么重要。这使得那些需要更多许可权限的负载仍能被有效隔离。
此外,沙箱化负载的保护高度依赖于沙箱化的实现方法。 因此,现在还没有针对所有沙箱化负载的建议配置。