Pod 安全性标准
Pod 的安全性配置一般通过使用 安全性上下文(Security Context) 来保证。安全性上下文允许用户逐个 Pod 地定义特权级及访问控制。
以前,对集群的安全性上下文的需求的实施及其基于策略的定义都通过使用 Pod 安全性策略来实现。 Pod 安全性策略(Pod Security Policy) 是一种集群层面的资源,控制 Pod 规约中 安全性敏感的部分。
不过,新的策略实施方式不断涌现,或增强或替换 PodSecurityPolicy 的使用。 本页的目的是详细介绍建议实施的 Pod 安全框架;这些内容与具体的实现无关。
策略类型
在进一步讨论整个策略谱系之前,有必要对基本的策略下个定义。 策略可以是很严格的也可以是很宽松的:
- Privileged - 不受限制的策略,提供最大可能范围的权限许可。这些策略 允许已知的特权提升。
- Baseline - 限制性最弱的策略,禁止已知的策略提升。 允许使用默认的(规定最少)Pod 配置。
- Restricted - 限制性非常强的策略,遵循当前的保护 Pod 的最佳实践。
策略
Privileged
Privileged 策略是有目的地开放且完全无限制的策略。此类策略通常针对由 特权较高、受信任的用户所管理的系统级或基础设施级负载。
Privileged 策略定义中限制较少。对于默认允许(Allow-by-default)实施机制(例如 gatekeeper), Privileged 框架可能意味着不应用任何约束而不是实施某策略实例。 与此不同,对于默认拒绝(Deny-by-default)实施机制(如 Pod 安全策略)而言, Privileged 策略应该默认允许所有控制(即,禁止所有限制)。
Baseline
Baseline 策略的目标是便于常见的容器化应用采用,同时禁止已知的特权提升。 此策略针对的是应用运维人员和非关键性应用的开发人员。 下面列举的控制应该被实施(禁止):
控制(Control) | 策略(Policy) |
宿主名字空间 |
必须禁止共享宿主名字空间。 限制的字段: spec.hostNetwork spec.hostPID spec.hostIPC 允许的值: false |
特权容器 |
特权 Pod 禁用大多数安全性机制,必须被禁止。 限制的字段: spec.containers[*].securityContext.privileged spec.initContainers[*].securityContext.privileged 允许的值: false、未定义/nil |
权能 |
必须禁止添加默认集合之外的权能。 限制的字段: spec.containers[*].securityContext.capabilities.add spec.initContainers[*].securityContext.capabilities.add 允许的值: 空(或限定为一个已知列表) |
HostPath 卷 |
必须禁止 HostPath 卷。 限制的字段: spec.volumes[*].hostPath 允许的值: 未定义/nil |
宿主端口 |
应禁止使用宿主端口,或者至少限定为已知列表。 限制的字段: spec.containers[*].ports[*].hostPort spec.initContainers[*].ports[*].hostPort 允许的值: 0、未定义(或限定为已知列表) |
AppArmor |
在被支持的主机上,默认使用 'runtime/default' AppArmor Profile。
基线策略应避免覆盖或者禁用默认策略,以及限制覆盖一些 profile 集合的权限。 限制的字段: metadata.annotations['container.apparmor.security.beta.kubernetes.io/*'] 允许的值: 'runtime/default'、未定义 |
SELinux |
设置 SELinux 类型的操作是被限制的,设置自定义的 SELinux 用户或角色选项是被禁止的。 限制的字段: spec.securityContext.seLinuxOptions.type spec.containers[*].securityContext.seLinuxOptions.type spec.initContainers[*].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.securityContext.seLinuxOptions.role spec.containers[*].securityContext.seLinuxOptions.role spec.initContainers[*].securityContext.seLinuxOptions.role 允许的值: 未定义或空 |
/proc 挂载类型 |
要求使用默认的 /proc 掩码以减小攻击面。限制的字段: spec.containers[*].securityContext.procMount spec.initContainers[*].securityContext.procMount 允许的值: 未定义/nil、'Default' |
Sysctls |
Sysctls 可以禁用安全机制或影响宿主上所有容器,因此除了若干『安全』的子集之外,应该被禁止。
如果某 sysctl 是受容器或 Pod 的名字空间限制,且与节点上其他 Pod 或进程相隔离,可认为是安全的。 限制的字段: spec.securityContext.sysctls 允许的值: kernel.shm_rmid_forced net.ipv4.ip_local_port_range net.ipv4.tcp_syncookies net.ipv4.ping_group_range 未定义/空值 |
Restricted
Restricted 策略旨在实施当前保护 Pod 的最佳实践,尽管这样作可能会牺牲一些兼容性。 该类策略主要针对运维人员和安全性很重要的应用的开发人员,以及不太被信任的用户。 下面列举的控制需要被实施(禁止):
控制(Control) | 策略(Policy) |
基线策略的所有要求。 | |
卷类型 |
除了限制 HostPath 卷之外,此类策略还限制可以通过 PersistentVolumes 定义的非核心卷类型。 限制的字段: spec.volumes[*].hostPath spec.volumes[*].gcePersistentDisk spec.volumes[*].awsElasticBlockStore spec.volumes[*].gitRepo spec.volumes[*].nfs spec.volumes[*].iscsi spec.volumes[*].glusterfs spec.volumes[*].rbd spec.volumes[*].flexVolume spec.volumes[*].cinder spec.volumes[*].cephFS spec.volumes[*].flocker spec.volumes[*].fc spec.volumes[*].azureFile spec.volumes[*].vsphereVolume spec.volumes[*].quobyte spec.volumes[*].azureDisk spec.volumes[*].portworxVolume spec.volumes[*].scaleIO spec.volumes[*].storageos spec.volumes[*].csi 允许的值: 未定义/nil |
特权提升 |
禁止(通过 SetUID 或 SetGID 文件模式)获得特权提升。 限制的字段: spec.containers[*].securityContext.allowPrivilegeEscalation spec.initContainers[*].securityContext.allowPrivilegeEscalation 允许的值: false |
以非 root 账号运行 |
必须要求容器以非 root 用户运行。 限制的字段: spec.securityContext.runAsNonRoot spec.containers[*].securityContext.runAsNonRoot spec.initContainers[*].securityContext.runAsNonRoot 允许的值: true |
非 root 组 (可选) |
禁止容器使用 root 作为主要或辅助 GID 来运行。 限制的字段: spec.securityContext.runAsGroup spec.securityContext.supplementalGroups[*] spec.securityContext.fsGroup spec.containers[*].securityContext.runAsGroup spec.initContainers[*].securityContext.runAsGroup 允许的值: 非零值 未定义/nil ( *.runAsGroup 除外) |
Seccomp |
必须要求使用 RuntimeDefault seccomp profile 或者允许使用特定的 profiles。 限制的字段: spec.securityContext.seccompProfile.type spec.containers[*].securityContext.seccompProfile spec.initContainers[*].securityContext.seccompProfile 允许的值: 'runtime/default' 未定义/nil |
策略实例化
将策略定义从策略实例中解耦出来有助于形成跨集群的策略理解和语言陈述, 以免绑定到特定的下层实施机制。
随着相关机制的成熟,这些机制会按策略分别定义在下面。特定策略的实施方法不在这里定义。
常见问题
为什么不存在介于 Privileged 和 Baseline 之间的策略类型
这里定义的三种策略框架有一个明晰的线性递进关系,从最安全(Restricted)到最不安全, 并且覆盖了很大范围的工作负载。特权要求超出 Baseline 策略者通常是特定于应用的需求, 所以我们没有在这个范围内提供标准框架。 这并不意味着在这样的情形下仍然只能使用 Privileged 框架,只是说处于这个范围的 策略需要因地制宜地定义。
SIG Auth 可能会在将来考虑这个范围的框架,前提是有对其他框架的需求。
安全策略与安全上下文的区别是什么?
安全上下文在运行时配置 Pod 和容器。安全上下文是在 Pod 清单中作为 Pod 和容器规约的一部分来定义的,所代表的是 传递给容器运行时的参数。
安全策略则是控制面用来对安全上下文以及安全性上下文之外的参数实施某种设置的机制。 在 2020 年 2 月,目前实施这些安全性策略的原生解决方案是 Pod 安全性策略 - 一种对集群中 Pod 的安全性策略进行集中控制的机制。 Kubernetes 生态系统中还在开发一些其他的替代方案,例如 OPA Gatekeeper。
我应该为我的 Windows Pod 实施哪种框架?
Kubernetes 中的 Windows 负载与标准的基于 Linux 的负载相比有一些局限性和区别。 尤其是 Pod SecurityContext 字段 对 Windows 不起作用。 因此,目前没有对应的标准 Pod 安全性框架。
沙箱(Sandboxed) Pod 怎么处理?
现在还没有 API 标准来控制 Pod 是否被视作沙箱化 Pod。 沙箱 Pod 可以通过其是否使用沙箱化运行时(如 gVisor 或 Kata Container)来辨别,不过 目前还没有关于什么是沙箱化运行时的标准定义。
沙箱化负载所需要的保护可能彼此各不相同。例如,当负载与下层内核直接隔离开来时, 限制特权化操作的许可就不那么重要。这使得那些需要更多许可权限的负载仍能被有效隔离。
此外,沙箱化负载的保护高度依赖于沙箱化的实现方法。 因此,现在还没有针对所有沙箱化负载的建议策略。