使用 Pod 安全策略强化 K8S 安全

发布于:2020 年 5 月 25 日 16:41

使用Pod安全策略强化K8S安全

什么是 Pod 安全策略?

Kubernetes Pod 安全策略(PSP)是 Kubernetes 安全版块中极为重要的组件。Pod 安全策略是集群级别的资源,用于控制 Pod 安全相关选项,并且还是一种强化 Kubernetes 工作负载安全性的机制。Kubernetes 平台团队或集群运维人员可以利用它来控制 pod 的创建以及限制特定的用户、组或应用程序可以使用的功能。

举个简单的例子,使用 PSP 你可以:

  • 防止特权 Pod 启动并控制特权升级。
  • 限制 Pod 可以访问的主机命名空间、网络和文件系统
  • 限制可以运行 pod 的用户 / 组。
  • 限制 Pod 可以访问的 Volume
  • 限制其他参数,如运行时配置文件或只读根文件系统

在本文中,我们将向你展示在 Rancher 中如何通过启用一个简单的 Pod 安全策略来强化你的 Kubernetes 安全。

Pod 安全策略真的可以增强 K8S 的安全性吗?

是的,Pod 安全策略确实可以增强 Kubernetes 的安全性。它提供了 Kubernetes 原生控制机制,可以防止威胁而不影响性能,这与 agent 必须拦截主机上的每个动作有所区别。

如果你尚未在集群中启用 PSP(或执行访问控制之类的等效方法),则 Kubernetes 用户可能会生成特权集群。这将会被恶意利用,例如提升特权进而突破容器隔离并访问其他 Pod/ 服务。

如果没有限制 Pod spec 特权的机制,攻击者可以通过 docker 命令执行任何操作,例如,运行特权容器、使用节点资源等。

想要快速验证以上说法,你可以执行以下脚本(千万不要在生产集群上操作):

复制代码
./kubectl-root-in-host.sh
bash-4.4# whoami
root
bash-4.4# hostname
sudo--alvaro-rancher-rancheragent-0-all

你可以获得对 Kubernetes 节点的即时 root 访问权限。是不是有点后怕呢?

通过遵循最小特权的概念,你可以安全地在集群中实现 PSP,并确保在 Kubernetes Pod 或工作负载中没有不需要的权限。除了 Kubernetes 安全的核心理念外,最小特权原则也是一种通用的安全最佳实践,同时还是诸如 PCI、SOC2 或 HIPAA 等合规性标准的核心要求。

总结一下:

  • PSP 将为 Pod 授予的安全功能提供默认安全约束,该 pod 可以是集群上任何用户创建的
  • PSP 还能通过满足特定合规性基准的要求帮助你验证合规性

最小特权是一个概念,也是一个实践,可以将用户、账号和计算过程的访问权限限制为仅执行日常合法活动所需要的资源。

在你的集群中启用 Pod 安全策略

在 Kubernetes 中 Pod 安全策略可以实现为 Admission Controller。要在你的集群中启用 PSP,确保 PodSecurityPolicy 在 enable-admission-plugins 列表内,作为参数传递给你的 Kubernetes API 配置的参数:

复制代码
--enable-admission-plugins=...,PodSecurityPolicy

提供托管 Kubernetes 集群(你无法直接访问 API 配置)的云提供商通常会提供高级设置,用户可以在整个集群范围内启用 PSP。在其他情况下,你可能需要编辑 /etc/kubernetes/manifests/kube-apiserver.yaml 文件,并将其添加到相应的命令参数中。

在 Rancher 中,你可以在 UI 上编辑集群来轻松启用 PSP:

使用Pod安全策略强化K8S安全

在 Rancher 中启用 PSP

你可以选择默认应用哪个 Pod 安全策略。在本例中,我们选择了 restricted (受限)。

使用一个 Admission controller 来启用 PSP 的好处在于它提供了一个即时预防机制,甚至可以在调度之前停止部署过度特权的 Pod。缺点就是你启用一个 PSP 之后,每个 pod 都需要经过 PSP 的批准,使其部署和过渡更加困难。

Rancher 中启用基本 Pod 安全策略 demo

在这一部分中,我们将逐步演示如何通过 Rancher dashboard 在集群中启用 Pod 安全策略,并在默认情况下使用受限策略,并了解如何防止创建特权 Pod。

PSP 对象本身是将要应用于 pod specs 的要求和约束的列表。PSP YAML 如下所示:

复制代码
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
allowedCapabilities:
- NET_ADMIN
- IPC_LOCK
allowedHostPaths:
- pathPrefix: /dev
- pathPrefix: /run
- pathPrefix: /
fsGroup:
rule: RunAsAny
hostNetwork: true
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
privileged: true
runAsUser:
rule: RunAsAny
volumes:
- hostPath
- secret

以上 PSP 有很多允许权限,例如:

  • 它允许 pod 可以与其他 Linux 功能(如 NET_ADMIN 和 IPC_LOCK)一起运行
  • 它允许从主机安装敏感路径
  • Pod 可以作为特权运行

浏览 Kubernetes 官方文档可以获取可用的 PSP 控件及其默认值的完整列表:

https://kubernetes.io/docs/concepts/policy/pod-security-policy/

让我们来看一个示例,说明如何防止特权 Pod 在集群中运行。

在集群中启用 PSP 之后,请尝试部署类似的 pod:

deploy-not-privileged.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: not-privileged-deploy
name: not-privileged-deploy
spec:
replicas: 1
selector:
matchLabels:
app: not-privileged-deploy
template:
metadata:
labels:
app: not-privileged-deploy
spec:
containers:
- image: alpine
name: alpine
stdin: true
tty: true
securityContext:
runAsUser: 1000
runAsGroup: 1000

它可以立即使用,因为我们告诉 Rancher 启用具有受限安全策略的 PSP,该策略允许没有特权的 pod 正常运行,像上面那样。

检查默认 PSP 中的内容,如下所示:

$ kubectl get psp restricted-psp -o yaml

复制代码
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
annotations:
serviceaccount.cluster.cattle.io/pod-security: restricted
serviceaccount.cluster.cattle.io/pod-security-version: "1960"
creationTimestamp: "2020-03-04T19:56:10Z"
labels:
cattle.io/creator: norman
name: restricted-psp
resourceVersion: "2686"
selfLink: /apis/policy/v1beta1/podsecuritypolicies/restricted-psp
uid: 40957380-1d44-4e43-9333-91610e3fc079
spec:
allowPrivilegeEscalation: false
fsGroup:
ranges:
- max: 65535
min: 1
rule: MustRunAs
requiredDropCapabilities:
- ALL
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
ranges:
- max: 65535
min: 1
rule: MustRunAs
volumes:
- configMap
- emptyDir
- projected
- secret
- downwardAPI
- persistentVolumeClaim

或者在 Rancher 的全局视角检查。选择【安全 >Pod 安全策略】并点击 受限 的选项。

使用Pod安全策略强化K8S安全

在 Rancher 中检查 Pod 安全策略

该 PSP 应该允许任何 pod,只要它以标准用户(不是 root)身份运行,并且不需要任何特权和特殊功能。

有关 PSP 和 RBAC 的其他内容,我们将在以后进行探讨。为了简单起见,加上 Rancher 已经为你设置了必需的绑定,因此我们现在略过这一部分。让我们尝试部署一个特权 pod,例如来自 kubectl-root-in-host.sh 脚本的那个 pod:

deploy-privileged.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: privileged-deploy
name: privileged-deploy
spec:
replicas: 1
selector:
matchLabels:
app: privileged-deploy
template:
metadata:
labels:
app: privileged-deploy
spec:
containers:
- image: alpine
name: alpine
stdin: true
tty: true
securityContext:
privileged: true
hostPID: true
hostNetwork: true

该 pod 将不会进入集群

复制代码
Warning FailedCreate 2s (x12 over 13s) replicaset-controller Error creating: pods "privileged-deploy-7569b9969d-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used spec.securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]

PodSecurityPolicy admission controller 将不允许创建这个 pod,因为现有的 PSP 不允许使用“hostPID”、“hostNetwork” 或 “privileged”。

总结

在本文中我们通过在 Rancher 环境中启用一个简单的 Pod 安全策略来增强你的 Kubernetes 安全。通过使用默认的受限 PSP,我们确保 pod 只能在不需要扩展安全权限的情况下运行。最后,我们尝试部署一个拥有众多权限的 pod,并且失败了,因为现有的 PSP 阻止了它被调度到集群上。

Rancher Kubernetes 平台拥有着超过一亿次下载量,我们深知安全问题对于用户而言的重要性。后期我们也将会推出更多与安全相关的内容,帮助 Rancher 用户安全、稳妥地落地 Kubernetes。

阅读数:6 发布于:2020 年 5 月 25 日 16:41

评论

发布
暂无评论