K8s:通过 PSA(Pod Security Admission) 定义K8s 集群安全基线

2023-09-11 15:32:20 浏览数 (2)

1写在前面


  • 博文内容涉及 PSA Pod 安全准入控制认知
  • 理解不足小伙伴帮忙指正

对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》


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

Kubernetes 1.21版本开始,PodSecurityPolicy(PSP)已被标记为已弃用,,从 Kubernetes v1.25 开始PodSecurityPolicy (PSP) 准入控制器已被移除

2PSA

PSA 使用 Pod 安全标准 (PSS) 来定义安全策略。Kubernetes Pod 安全性标准(Security Standard) 为 Pod 定义不同的隔离级别安全。这些标准能够让你以一种清晰、一致的方式定义如何限制 Pod 行为。

Kubernetes 提供了一个内置的 Pod Security 准入控制器(PSA)来执行 Pod 安全标准 (Pod Security Standard)。创建 Pod 时在名字空间级别应用这些 Pod 安全限制。

Pod 安全性标准 PSS

Pod 安全性标准定义了三种不同的策略(Policy),以广泛覆盖安全应用场景。这些策略是叠加式的(Cumulative),安全级别从高度宽松至高度受限。概述每个策略的要求。

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

三个分类对应的权限控制,细粒度对应 securityContext 安全上下文对象中的不同的值,可以理解为把 securityContext 中属性按照安全级别分为了三个大类:这里的分类类似 Open Shift 中的 7类 SCC。

Privileged

Privileged 策略是有目的地开放且完全无限制的策略。此类策略通常针对由特权较高、受信任的用户所管理的系统级或基础设施级负载

Privileged 策略定义中限制较少。默认允许的(Allow-by-default)实施机制(例如 gatekeeper) 可以缺省设置为 Privileged。与此不同,对于默认拒绝(Deny-by-default)的实施机制(如 Pod 安全策略)而言, Privileged 策略应该禁止所有限制。

Baseline

Baseline 策略的目标是便于常见的容器化应用采用,同时禁止已知的特权提升。此策略针对的是应用运维人员和非关键性应用的开发人员。

Restricted

Restricted 策略旨在实施当前保护 Pod 的最佳实践,尽管这样作可能会牺牲一些兼容性。该类策略主要针对运维人员和安全性很重要的应用的开发人员,以及不太被信任的用户。

3安全性准入控制配置

回到安全准入控制 PSA,在集群中,配置安全准入控制,有两种方式:

  • 为命名空间设置 Pod 安全性准入控制标签
  • 集群范围的安全准入控制器配置

命名空间设置Pod 安全性准入控制标签

为命名空间设置 Pod 安全性准入控制标签,需要在命名空间API 对象上添加对应的标签,通过标签来控制Pod安全准入控制。

安全准入控制标签,通过 MODE LEVEL 进行准入限制, LEVEL 用于设置安全级别 PSS,MODE 用于设置命中策略后的处理逻辑

MODE 也同样分为三类:

  • enforce:策略违例会导致 Pod 被拒绝
  • audit: 策略违例会触发审计日志中记录新事件时添加审计注解;但是 Pod 仍是被接受的。
  • warn: 策略违例会触发用户可见的警告信息,但是 Pod 仍是被接受的。

命名空间可以配置任何一种或者所有模式,或者甚至为不同的模式设置不同的级别。为了尽早地捕获违例状况,auditwarn 模式都应用到负载资源enforce 模式并不应用到工作负载资源,仅应用到所生成的 Pod 对象上。

对于每种模式,决定所使用策略的标签有两个:

代码语言:javascript复制
# 模式的级别标签用来标示对应模式所应用的策略级别
#
# MODE 必须是 `enforce`、`audit` 或 `warn` 之一
# LEVEL 必须是 `privileged`、baseline` 或 `restricted` 之一
pod-security.kubernetes.io/<MODE>: <LEVEL>

# 可选:针对每个模式版本的版本标签可以将策略锁定到
# 给定 Kubernetes 小版本号所附带的版本(例如 v1.28)
#
# MODE 必须是 `enforce`、`audit` 或 `warn` 之一
# VERSION 必须是一个合法的 Kubernetes 小版本号或者 `latest`
pod-security.kubernetes.io/<MODE>-version: <VERSION>

配置 baseline Pod 容器标准准入

代码语言:javascript复制
apiVersion: v1
kind: Namespace
metadata:
  name: my-baseline-namespace
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/enforce-version: v1.28

    # 我们将这些标签设置为我们所 _期望_ 的 `enforce` 级别
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: v1.28
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: v1.28

使用 kubectl label 为现有名字空间添加标签

在刚开始为名字空间评估安全性策略变更时,使用 --dry-run 标志是很有用的。Pod 安全性标准会在 dry run(试运行) 模式下运行,在这种模式下会生成新策略如何处理现有 Pod 的信息, 但不会真正更新策略。

代码语言:javascript复制
kubectl label --dry-run=server --overwrite ns --all 
    pod-security.kubernetes.io/enforce=baseline

应用到所有名字空间

如果你是刚刚开始使用 Pod 安全性标准,一种比较合适的初始步骤是针对所有名字空间为类似 baseline 这种比较严格的安全级别配置审计注解。

代码语言:javascript复制
kubectl label --overwrite ns --all 
  pod-security.kubernetes.io/audit=baseline 
  pod-security.kubernetes.io/warn=baseline

查看没有显式设置 enforce 级别的名字空间

代码语言:javascript复制
kubectl get namespaces --selector='!pod-security.kubernetes.io/enforce'

应用到单个名字空间

代码语言:javascript复制
kubectl label --overwrite ns my-existing-namespace 
  pod-security.kubernetes.io/enforce=restricted 
  pod-security.kubernetes.io/enforce-version=v1.28

集群范围的安全准入控制器配置

可以为 Pod 安全性的实施设置豁免(Exemptions) 规则, 从而允许创建一些本来会被与给定名字空间相关的策略所禁止的 Pod。豁免规则可以在内置准入控制器配置静态配置

Kubernetes 提供的内置的准入控制器 用来强制实施 Pod 安全性标准。除了豁免选项,也可以配置此准入控制器来设置集群范围的默认值

豁免规则必须显式枚举。满足豁免标准的请求会被准入控制器忽略 (所有 enforce、audit 和 warn 行为都会被略过)。豁免的维度包括:

  • Username:来自用户名已被豁免的、已认证的(或伪装的)的用户的请求会被忽略。
  • RuntimeClassName:指定了已豁免的运行时类名称的 Pod 和负载资源会被忽略。
  • Namespace:位于被豁免的名字空间中的 Pod 和负载资源会被忽略。

大多数 Pod 是作为对工作负载资源的响应, 由控制器所创建的,这意味着

  • 为某最终用户提供豁免时,只会当该用户直接创建 Pod 时对其实施安全策略的豁免。用户创建工作负载资源时不会被豁免。
  • 控制器服务账号(例如system:serviceaccount:kube-system:replicaset-controller) 通常不应该被豁免,因为豁免这类服务账号隐含着对所有能够创建对应工作负载资源的用户豁免。

pod-security.admission.config.k8s.io/v1 配置需要 v1.25 。对于 v1.23 和 v1.24,使用 v1beta1。对于 v1.22,使用 v1alpha1。

需要说明的是,下面的 yaml 文件需要通过 ——admission-control-config-file 指定到 kube-apiserver,不能直接应用

代码语言:javascript复制
apiVersion: apiserver.config.k8s.io/v1 # 查阅兼容性说明
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
  configuration:
    apiVersion: pod-security.admission.config.k8s.io/v1
    kind: PodSecurityConfiguration
    # 当未设置 mode 标签时会应用的默认设置
    #
    # level 标签必须是以下取值之一:
    # - "privileged" (默认)
    # - "baseline"
    # - "restricted"
    #
    # version 标签必须是如下取值之一:
    # - "latest" (默认) 
    # - 诸如 "v1.28" 这类版本号
    defaults:
      enforce: "privileged"
      enforce-version: "latest"
      audit: "privileged"
      audit-version: "latest"
      warn: "privileged"
      warn-version: "latest"
    exemptions:
      # 要豁免的已认证用户名列表
      usernames: []
      # 要豁免的运行时类名称列表
      runtimeClasses: []
      # 要豁免的名字空间列表
      namespaces: []

4博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知,这是一个开源项目,如果你认可它,不要吝啬星星哦 :)

https://medium.com/@muthanagavamsi/kubernetes-pod-security-admission-psa-20664cb3074d

https://kubernetes.io/zh-cn/docs/concepts/security/pod-security-standards/

https://kubernetes.io/zh-cn/docs/concepts/security/pod-security-admission/

https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/

0 人点赞