【k8s】scc权限 restricted、anyuid、privileged
文章目录
- 概述
- 1. 内置的scc
- 2. OpenShift如何确定pod的scc
- 2.1 Pod未带SCC标签的情况
- 2.2. Pod带有SCC标签的情况
- 参考
概述
在OpenShift(后文简称OCP)中,很早就一个概念:Security Context Constraints ,简称SCC,即安全上下文约束。K8S的Pod安全策略和OCP中的SCC有一定继承(现有OCP的SCC后有K8S的pod安全策略)。为了更好地理解K8S的容器安全策略,并且控制篇幅,我们在本篇中先介绍OCP的SCC。
1. 内置的scc
安全上下文约束是OpenShift提供的工具,用于控制平台上允许每个Pod请求的特权。OpenShift带有8个预定义的安全上下文约束,您可以使用oc get scc命令列出这些约束。
SCC | Description | 说明 |
---|---|---|
restricted | 受限拒绝访问所有主机功能,并要求Pod必须与UID和分配给名称空间的SELinux上下文一起运行。这是限制性最强 的SCC,默认情况下,它用于经过身份验证的用户 | 换句话说,这是最安全的一种SCC。 |
nonroot | nonroot提供受限SCC的所有功能,但允许用户使用任何非root UID运行。用户必须指定UID,或者必须在容器运行时清单上指定UID。 | 需要具有相同的其他受限制的SCC安全功能的可预测的非根UID的应用程序可以使用此SCC,只要它们在清单中通知了UID。 |
anyuid | anyuid提供了受限SCC的所有功能,但允许用户使用任何UID和任何GID运行。 | 在kubernetes和OpenShift之类的平台上,这等效于允许在容器内部和外部都允许UID 0或root用户。SELinux在这里起到了重要的作用,它增加了一层保护,并且使用seccomp过滤不需要的系统调用。 |
hostmount-anyuid | hostmount-anyuid提供了受限SCC的所有功能,但允许通过Pod进行主机安装和任何UID。这主要由持久性卷回收器使用。警告:此SCC允许主机文件系统作为任何UID(包括UID 0)进行访问。请谨慎授权。 | 与anyuid相同的警告,但在这里它会更进一步,并允许安装主机卷。请注意,描述中提到的卷回收器是受信任的工作负载,也是必不可少的基础架构. |
hostnetwork | hostnetwork允许使用主机网络和主机端口,但仍要求Pod必须与分配给namepac的UID和SELinux上下文一起运行e | 在这里,pod/容器将能够直接“查看和使用”主机网络堆栈。非零UID和预分配的SELinux上下文将有助于提供另一层安全性。 |
node-exporter | node-exporter scc is used for the Prometheus node exporter | Node-exporter 是为Prometheus设计的,用于从集群中检索指标。它允许访问主机网络,主机PIDS和主机卷,但不能访问主机IPC。也允许anyuid。不能被其他应用程序使用。 |
hostaccess | hostaccess允许访问所有主机名称空间,但仍要求Pod必须与分配给名称空间的UID和SELinux上下文一起运行。警告:此SCC允许主机访问名称空间,文件系统和PIDS。它只能由受信任的Pod使用。谨慎行事。 | 在描述中,主机名称空间是指在pod或容器名称空间之外,或者,我们可以将其称为节点或根Linux名称空间。确实,限制UID并使用SELinux将为保护节点设置一层安全性。但是,它是一个非常宽松的SCC,仅应由绝对必要的受信任工作负载使用。 |
Privileged | privileged允许访问所有特权和主机功能,并具有以任何用户,任何组,任何fsGroup和任何SELinux上下文运行的能力。警告:这是最宽松 的SCC,仅应用于集群管理。谨慎行事。 | 此scc允许pod /容器控制主机/ worker节点甚至其他容器中的所有内容。这是最特权和最宽松的SCC策略。仅受信任的工作负载应使用此选项,并讨论是否应将其用于生产中是有效的。特权pod可以完全控制主机。 |
本质是scc权限列表不同
:
restricted | anyuid | privileged |
---|---|---|
allowHostDirVolumePlugin: false | allowHostDirVolumePlugin: false | allowHostDirVolumePlugin: true |
allowHostIPC: false | allowHostIPC: false | allowHostIPC: true |
allowHostNetwork: false | allowHostNetwork: false | allowHostNetwork: true |
allowHostPID: false | allowHostPID: false | allowHostPID: true |
allowHostPorts: false | allowHostPorts: false | allowHostPorts: true |
allowPrivilegeEscalation: true | allowPrivilegeEscalation: true | allowPrivilegeEscalation: true |
allowPrivilegedContainer: false | allowPrivilegedContainer: false | allowPrivilegedContainer: true |
allowedCapabilities: null | allowedCapabilities: [ | allowedCapabilities: [*] |
NET_RAW | ||
FSETID | ||
SETGID | ||
SETUID | ||
CHOWN | ||
SYS_CHROOT] | ||
allowedUnsafeSysctls: | allowedUnsafeSysctls: [*] | |
apiVersion: security.openshift.io/v1 | apiVersion: security.openshift.io/v1 | apiVersion: security.openshift.io/v1 |
defaultAddCapabilities: null | defaultAddCapabilities: null | defaultAddCapabilities: null |
fsGroup: | fsGroup: RunAsAny | fsGroup: RunAsAny |
groups: [] | groups: [system:cluster-admins] | groups: [system:cluster-admins, system:nodes, system:masters] |
kind: SecurityContextConstraints | kind: SecurityContextConstraints | kind: SecurityContextConstraints |
name: restricted | name: anyuid | name: privileged |
resourceVersion: “3512475209” | resourceVersion: “3512475203” | resourceVersion: “340” |
uid: bdb21b4f-dfda-456a-8aa3-7fdcd8ee2f2d | uid: d35f70ed-47ce-4b22-83d0-b0b2a4bc07f8 | uid: 1df9ef3c-1fab-4031-a2cd-3d7479069050 |
priority: null | priority: 10 | priority: null |
readOnlyRootFilesystem: false | readOnlyRootFilesystem: false | readOnlyRootFilesystem: false |
requiredDropCapabilities: [KILL, MKNOD, SETUID, SETGID] | requiredDropCapabilities: [MKNOD] | requiredDropCapabilities: null |
runAsUser: | runAsUser: RunAsAny | runAsUser: RunAsAny |
seLinuxContext: | seLinuxContext: MustRunAs | seLinuxContext: RunAsAny |
supplementalGroups: RunAsAny | supplementalGroups: RunAsAny | supplementalGroups: RunAsAny |
users: [] | users: [] | users: [system:admin, system:serviceaccount:openshift-infra:build-controller] |
volumes: [configMap, csi, downwardAPI, emptyDir, ephemeral, persistentVolumeClaim, projected, secret] | volumes: [configMap, csi, downwardAPI, emptyDir, ephemeral, persistentVolumeClaim, projected, secret] | volumes: [*] |
2. OpenShift如何确定pod的scc
- 如果Pod指定了SCC注解,且ServiceAccount有权限使用该SCC,则优先使用注解指定的SCC。
- 如果未指定注解,则基于ServiceAccount的绑定权限,从严格到宽松挑选合适的SCC。
- 无论是否指定注解,最终都需要验证ServiceAccount的绑定权限,这意味着标签并不能完全绕过权限控制。
2.1 Pod未带SCC标签的情况
如果Pod没有明确指定SCC,OpenShift会按照以下流程选择一个适用的SCC:
- 检查Pod的ServiceAccount,以及该ServiceAccount的角色绑定所允许的SCC列表。
- 对SCC列表按照权限的严格程度排序:
- 从最严格的SCC(例如restricted)到最宽松的SCC(例如privileged)。
- 从排序中选择第一个Pod能满足的SCC作为其适用的SCC。
2.2. Pod带有SCC标签的情况
- OpenShift允许通过Pod的openshift.io/scc注解直接指定使用的SCC。
- 如果Pod通过注解明确指定了一个SCC(如openshift.io/scc=restricted),OpenShift会优先尝试使用该SCC。
- 然而,Pod仍需满足以下条件:
- Pod的ServiceAccount具有绑定到该SCC的权限:OpenShift会检查绑定(RoleBinding 或 ClusterRoleBinding)中,是否允许ServiceAccount使用这个指定的SCC。
- 如果绑定验证成功,则使用指定的SCC。
- 如果绑定验证失败,则该Pod无法创建。
参考
K8S中的Pod安全策略(上):K8S学习篇3
OpenShift如何确定pod的scc?