揭秘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) 准入控制器已被移除

相关推荐
Thanks_ks1 小时前
探索计算机互联网的奇妙世界:从基础到前沿的无尽之旅
物联网·云计算·区块链·tcp/ip协议·计算机互联网·万维网·未来科技
IT技术分享社区2 小时前
C#实战:使用腾讯云识别服务轻松提取火车票信息
开发语言·c#·云计算·腾讯云·共识算法
景天科技苑2 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
架构师那点事儿3 小时前
golang 用unsafe 无所畏惧,但使用不得到会panic
架构·go·掘金技术征文
wclass-zhengge3 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇3 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
九河云9 小时前
AWS账号注册费用详解:新用户是否需要付费?
服务器·云计算·aws
神一样的老师9 小时前
利用亚马逊AWS IoT核心和MQTT进行数据采集的综合指南
云计算·aws
昌sit!11 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis14 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab