0


揭秘K8s Pod安全:从SCC的实践到现在的PSA的全面解析”

1、概述

对于类似containerd这种,通过利用Linux namespace和Cgroup实现的容器技术来说,其实质就是宿主节点上的一个进程。鉴于安全因素,我们在生产中通常遵循最小权限原则,很少用Root来运行某些业务进程,也就是说,我们很少用根用户来运行相关的容器。这样做可以避免特权升级,防止容器逃逸,以及防止利用不必要的权限来进行意外操作或者恶意行为。

2、PSP 的由来

在 K8s 中,通过准入控制器来限制 Pod 的创建,当一个 apply 的 Pod 满足全部准入控制器时,才会被创建。对于 Pod 安全,K8s 也提供了自己的准入控制器。讲 K8s 的 安全策略,不得不提 openshift 的 SCC

Kubernetes 1.0 

于 2015 年 7 月 10 日发布,除了 Alpha 阶段的

SecurityContextDeny

准入插件 (当时称为 scdeny)之外,

没有任何机制来限制安全上下文和工作负载的敏感选项

。

PSP 即为 K8s 最早的安全策略,即

PodSecurityPolicy 

,PodSecurityPolicy 源自

OpenShift SecurityContextConstraints (SCC)

, SCC 出现在 Red Hat OpenShift 容器平台的第一个版本中,甚至在 Kubernetes 1.0 之前。PSP 是 SCC 的精简版。

SCC

熟悉 openshift 的小伙伴,或者参加过红帽 DO280 考试的小伙伴的,对 SCC 一定不陌生,SCC 即

SecurityContextConstraints(容器安全上下文)

,是 openshift 的一直沿用的 Pod 安全策略。

利用 SCC ,管理员能对Pod做如下的一些约束:

  • 运行特权容器 (privileged container)
  • 为容器增加能力 (capahiliticg)
  • 用主机上的目录作为卷
  • 容器的 SELinux 下文
  • 运行用户 ID
  • 主机命名空间和网络
  • 为 Pod 的卷分配 FSGroup
  • 配置允许的补充组
  • 要求使用只读文件系统
  • 控制允许使用的卷类型
  • 控制允许使用的安全计算模式配置文件(seccop prorile)

查看当前命名空间下的所以的 SSC , OpenShift 有七个 SCC 级别

[root@master student]# oc get scc
NAME               PRIV      CAPS      SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY   READONLYROOTFS   VOLUMES
anyuid             false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    10         false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
hostaccess         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath persistentVolumeClaim projected secret]
hostmount-anyuid   false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath nfs persistentVolumeClaim projected secret]
hostnetwork        false     []        MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
nonroot            false     []        MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
privileged         true      [*]       RunAsAny    RunAsAny           RunAsAny    RunAsAny    <none>     false            [*]
restricted         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
[root@master student]#

默认情况下,任何容器的执行都只授予

restricted(受限制)

的 SCC,这个 SCC 是最严格的,适用于以非 root 权限运行的 pod。它限制了 pod 对主机文件系统和网络的访问。

对应 的7中 SCC 限制说明:

  1. restricted:这个 SCC 是最严格的,适用于以 非root 权限运行的 pod。它限制了 pod 对主机文件系统和网络的访问。
  2. privileged:这个 SCC 允许 pod 以完整的 root 权限运行,并访问所有主机资源。它适用于需要访问敏感主机资源的 pod。
  3. anyuid:这个 SCC 允许 pod 以任何用户 ID 和组 ID 运行。它适用于需要访问默认用户 ID 不可访问的主机资源的 pod。
  4. hostaccess:这个 SCC 允许 pod 挂载主机文件系统并访问主机设备。它适用于需要访问默认用户 ID 不可访问的主机资源的 pod。
  5. hostmount-anyuid:这个 SCC 允许 pod 挂载主机文件系统并以任何用户 ID 和组 ID 运行。它适用于需要访问默认用户 ID 不可访问的主机资源的 pod。
  6. nonroot:这个 SCC 适用于不需要 root 权限的 pod。它限制了 pod 对主机文件系统和网络的访问。
  7. hostnetwork:这个 SCC 允许 pod 使用主机网络命名空间。这意味着 pod 可以访问主机上的网络接口和端口,而不是被限制在容器网络命名空间中。这个 SCC 可能会增加 pod 对主机网络的访问权限,因此需要谨慎使用。

PSP

PodSecurityPolicy

与其他专门的准入控制插件一样,作为内置的策略 API,对有关 Pod 安全设置的特定字段提供细粒度的权限。它承认

集群管理员和集群用户通常不是同一个人

,并且以 Pod 形式或任何将创建 Pod 的资源的形式创建工作负载的权限不应该等同于“集群上的 root 账户”。它还可以通过变更配置来应用更安全的默认值,并将底层 Linux 安全决策与部署过程分离来促进最佳实践。

使用

PodSecurityPolicy

的根源是早期关于安全策略的一个

拉取请求

, 它以 SCC(安全上下文约束)为基础,增加了新的 PSP 对象的设计方案。这是一个长达 9 个月的漫长讨论, 基于 OpenShift 的 SCC 反复讨论, 多次变动,并重命名为 PodSecurityPolicy,最终在 2016 年 2 月进入上游 Kubernetes。现在 PSP 对象已经创建,下一步是添加一个可以执行这些政策的准入控制器。第一步是添加不考虑用户或组 的准入控制。2016 年 5 月,一个特定的使 PodSecurityPolicy 达到可用状态的问题被添加进来, 以跟踪进展,并在名为 PSP 准入的拉取请求中合并了准入控制器的第一个版本。然后大约两个月后,发布了

Kubernetes 1.3

。

之后,PSP 准入控制器通过添加最初被搁置的内容进行了增强。在 2016 年 11 月上旬

合并鉴权机制

, 允许管理员在集群中使用多个策略,为不同类型的用户授予不同级别的访问权限。后来,2017 年 10 月合并的一个拉取请求 修复了 PodSecurityPolicies 在变更和字母顺序之间冲突的设计问题, 并继续构建我们所知道的 PSP 准入。之后,进行了许多改进和修复,以构建最近 Kubernetes 版本的 PodSecurityPolicy 功能。

对于 PSP 的使用,需要做 api-server 组件中启用配置 ,在 kube-apiserver 组件的启动配置中添加

--enable-admission-plugins=PodSecurityPolicy

参数

创建 PodSecurityPolicy

,创建了一个名为 "restricted-psp" 的 PodSecurityPolicy,其中容器不能以特权模式运行,必须以非 root 用户身份运行,并且在文件系统权限和存储卷方面宽松一些。

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted-psp
spec:
  privileged: false
  seLinux:
    rule: RunAsAny
  runAsUser:
    rule: MustRunAsNonRoot
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

上述示例创建了一个名为 "restricted-psp" 的 PodSecurityPolicy,其中容器不能以特权模式运行,必须以非 root 用户身份运行,并且在文件系统权限和存储卷方面宽松一些。

配置 PodSecurityPolicy

:PSP 直接和角色绑定,然后通过角色绑定用户或者 SA 来实现 pod 对 PSP 的应用。

  • 创建一个 ClusterRole,并将 PodSecurityPolicy 绑定到该 ClusterRole。
  • 创建一个 ClusterRoleBinding,将该 ClusterRole 绑定到您希望使用该 PodSecurityPolicy 的用户、服务账号或命名空间。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: psp-demo-role
rules:
- apiGroups:
  - policy
  resources:
  - podsecuritypolicies
  verbs:
  - use
  resourceNames:
  - restricted-psp

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: psp-demo-rolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: psp-demo-role
subjects:
- kind: User
  name: <your-username>

通过 服务账号 sa 的方式绑定,在之后的 pod 创建中,使用对应的服务账号创建 Pod 即可应用 PSP 对应的策略

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: my-rolebinding
  namespace: my-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: psp:restricted-psp
subjects:
- kind: ServiceAccount
  name: my-serviceaccount
  namespace: my-namespace

3、PSA 的发展

尽管

PodSecurityPolicy

试图解决的是一个关键问题,但它却包含一些重大缺陷:

  • 有缺陷的鉴权模式 - 如果用户针对 PSP 具有执行 use 动作的权限,而此 PSP 准许该 Pod 或者该 Pod 的服务帐户对 PSP 执行 use 操作,则用户可以创建一个 Pod。
  • 难以推广 - PSP 失败关闭。也就是说,在没有策略的情况下,所有 Pod 都会被拒绝。这主要意味着默认情况下无法启用它,并且用户必须在启用该功能之前为所有工作负载添加 PSP
  • 不一致的无边界 API - API 的发展有很多不一致的地方,特别是由于许多小众场景的请求:如标签、调度、细粒度的卷控制等。它的可组合性很差,优先级模型较弱,会导致意外的变更优先级。这使得 PSP 与其他第三方准入控制器的结合真的很困难。
  • 需要安全知识 - 有效使用 PSP 仍然需要了解 Linux 的安全原语。例如:MustRunAsNonRoot + AllowPrivilegeEscalation。
PodSecurityPolicy

的经验得出的结论是,大多数用户关心两个或三个策略,这导致了 Pod 安全标准(PSS)的创建,它定义了

三个策略

:

  • Privileged(特权的): 不受限制的策略,提供最大可能范围的权限许可。此策略允许已知的特权提升。
  • Baseline(基线的): 限制性最弱的策略,禁止已知的策略提升。允许使用默认的(规定最少)Pod 配置。
  • Restricted(受限的): 限制性非常强的策略,遵循当前的保护 Pod 的最佳实践

作为

PSP

的替代品,新的 Pod 安全准入(Pod Security Admission ,PSA) 是

Kubernetes v1.25

的稳定的准入插件,用于在命名空间级别强制执行这些标准。无需深入的安全知识,就可以更轻松地实施基本的 Pod 安全性。

从

Kubernetes 1.21

版本开始,

PodSecurityPolicy(PSP)

已被

标记为已弃用

,,从

Kubernetes v1.25

开始,

PodSecurityPolicy (PSP)

准入控制器已被

移除

。

作为

PSP

的替代品,新的 Pod 安全性准入(Pod Security Admission)在 Kubernetes v1.22 作为 Alpha 特性发布, 在 Kubernetes v1.23 中作为 Beta 特性默认可用。从 1.25 版本起, 此特性进阶至正式发布(Generally Available)。用于在命名空间级别强制执行这些标准。无需深入的安全知识,就可以更轻松地实施基本的 Pod 安全性。

从

Kubernetes 1.21

版本开始,

PodSecurityPolicy(PSP)

已被

标记为已弃用

,,从

Kubernetes v1.25

开始

PodSecurityPolicy (PSP)

准入控制器已被

移除

。

标签: k8s kubernetes go

本文转载自: https://blog.csdn.net/m0_37723088/article/details/138281375
版权归原作者 力哥讲技术 所有, 如有侵权,请联系我们删除。

“揭秘K8s Pod安全:从SCC的实践到现在的PSA的全面解析””的评论:

还没有评论