K8s Pod Security Policy实践

网友投稿 1639 2022-11-30

k8s Pod Security Policy实践

K8s Pod Security Policy实践

什么是 Pod 安全策略?

Pod 安全策略(Pod Security Policy) 是集群级别的资源,它能够控制 Pod 规约 中与安全性相关的各个方面。 ​​PodSecurityPolicy​​ 对象定义了一组 Pod 运行时必须遵循的条件及相关字段的默认值,只有 Pod 满足这些条件 才会被系统接受。 Pod 安全策略允许管理员控制如下方面:

控制的角度

字段名称

运行特权容器

​privileged​

使用宿主名字空间

​hostPID、hostIPC​

使用宿主的网络和端口

​hostNetwork, hostPorts​

控制卷类型的使用

​volumes​

使用宿主文件系统

​allowedHostPaths​

允许使用特定的 FlexVolume 驱动

​allowedFlexVolumes​

分配拥有 Pod 卷的 FSGroup 账号

​fsGroup​

以只读方式访问根文件系统

​readOnlyRootFilesystem​

设置容器的用户和组 ID

​runAsUser, runAsGroup, supplementalGroups​

限制 root 账号特权级提升

​allowPrivilegeEscalation, defaultAllowPrivilegeEscalation​

Linux 权能字(Capabilities)

​defaultAddCapabilities, requiredDropCapabilities, allowedCapabilities​

设置容器的 SELinux 上下文

​seLinux​

指定容器可以挂载的 proc 类型

​allowedProcMountTypes​

指定容器使用的 AppArmor 模版

​annotations​

指定容器使用的 seccomp 模版

​annotations​

指定容器使用的 sysctl 模版

​forbiddenSysctls,allowedUnsafeSysctls​

什么是 PodSecurityPolicy?

PodSecurityPolicy 是一个内置的准入控制器,可以让集群管理员控制 Pod 规范的安全敏感问题:首先,在集群中创建一个或多个 PodSecurityPolicy 资源,以定义 Pod 必须满足的要求。

然后,创建 RBAC 规则来控制,将哪个 PodSecurityPolicy 应用于给定的 Pod。如果 Pod 满足 PSP 的要求,就会被允许进入集群。在某些情况下,PSP 还可以修改 Pod 字段,并为这些字段创建新的默认值。如果 Pod 不满足 PSP 要求,它将被拒绝,并且无法运行。

关于 PodSecurityPolicy,需要了解一件事情:它与 PodSecurityContext 不同。

作为 Pod 规范的一部分,PodSecurityContext(及其每个容器对应的 SecurityContext)是为 Pod 指定安全相关设置的字段集合。Security Context 向 kubelet 和容器运行时指示 Pod 该如何运行。相比之下,PodSecurityPolicy 只约束(或默认)可能在 Security Context 中设置的值。

PSP 的弃用不会以任何方式影响到 PodSecurityContext。

K8s Pod Security Policy实践

这是关于如何加固kubernetes集群安全的文章[1]。在测试环境下使用默认的users和service accounts的默认授权创建pods并没有问题,但是在生产环境下,这可能会导致不可预料的灾难。Kubernetes提供pod security policy用来限制users和service account的权限。

概览

在minikube创建的集群中实践pod security policy前,在这里我将做一些理论基础的介绍。

实验条件

读者在实践pod security policy之前必须先要对下面这些名词的概念有充分的理解:

MinikubeNamespacePodReplica SetService AccountCluster RoleCluster Role Binding

Pod Securities Policy

Pod Security Policies(Adminssion Controller)授予users和service accounts创建或更新pods使用资源的权限。这是一种集群级别的资源类型,用来限制pod对敏感资源的使用。

Adminssion Controller

Addmission controller会拦截发往Kubernetes API Server调用资源的请求,验证请求调用的users和service accout是否已经授权和认证使用被调用的资源对象。例如:Admission controller会验证请求者是否拥有使用hostNetwork等kubernetes资源的权限。

Policy

对授权资源使用权限的规则定义在YAML文件中。

Policy Definition Guidelines

规则有两种:一种是限制(restrictive)使用资源的规则,另一种是允许(permission)使用资源的规则。

Pod Security Policy应该遵循以下的规范:

如果要​​限制​​user和service account使用集群中的资源,需要对相应的用户​​绑定限制策略​​如果要​​允许​​user和service account使用集群中的资源,需要对相应的用户​​绑定允许策略​​

例子

在这部分中我们将开始在集群中实践​​pod security policy​​。

Enabling Pod Security Policy

Pod 安全策略实现为一种可选(但是建议启用)的 ​​准入控制器​​​。 ​​启用了准入控制器​​ 即可强制实施 Pod 安全策略,不过如果没有授权认可策略之前即启用 准入控制器 将导致集群中无法创建任何 Pod。

PSP(Pod Security Policy) 在默认情况下并不会开启。通过将PodSecurityPolicy关键词添加到 ​​--enbale-admission-plugins​​ 配置数组后,可以开启PSP权限认证功能。

# Example--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy

注意:开启PodSecurityPolicy功能后,即使没有使用任何安全策略,都会使得创建pods(包括调度任务重新创建pods)失败

Testing

通过下面的deployment yaml文件测试在没有PSP策略的情况下是否可以创建pod:

apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment namespace: default labels: app: nginxspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.4

使用下面的命令创建deployment资源:

sudo kubectl apply -f nginx-deployment.yaml

使用下面的命令检查pod是否创建:

kubectl get pods,replicasets,deployments

资源查看

通过上图可见deployments和relicaset正在运行,由于缺少PSP policy,集群并没有创建相应的pods。

Defining Policies

下面将创建两个policies,

1.Restrictive Policy

下面是典型的限制资源使用的restrictive policy:

apiVersion: policy/v1beta1kind: PodSecurityPolicymetadata: name: restrictivespec: privileged: false hostNetwork: false allowPrivilegeEscalation: false defaultAllowPrivilegeEscalation: false hostPID: false hostIPC: false runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny volumes: - 'configMap' - 'downwardAPI' - 'emptyDir' - 'persistentVolumeClaim' - 'secret' - 'projected' allowedCapabilities: - '*'

2. Permissive Policy

下面是允许使用资源的permissive policy,多条permissive policy规则被用来设置相应user或者sevice account使用相关类型的资源。

apiVersion: policy/v1beta1kind: PodSecurityPolicymetadata: name: permissivespec: privileged: true hostNetwork: true hostIPC: true hostPID: true seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny hostPorts: - min: 0 max: 65535 volumes: - '*'

上面两种poicies可以使用下面的命令创建对应的PSP资源:

kubectl apply -f default-restrict-psp.yamlkubectl apply -f permissive-psp.yaml

核对psp是否创建成功与否:

[root@master psp]# kubectl get psp NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMESpermissive true RunAsAny RunAsAny RunAsAny RunAsAny false *restrictive false * RunAsAny RunAsAny RunAsAny RunAsAny false configMap,downwardAPI,emptyDir,persistentVolumeClaim,secret,projected

下面将通过cluster role和cluster role binding在集群中使用刚才定义的安全策略(Pod Security Policy)。

Cluster Role

关于restrictive policy的restrictive cluster role

kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: psp-restrictiverules:- apiGroups: - extensions resources: - podsecuritypolicies resourceNames: - restrictive verbs: - use

关于permissive policy的permissive cluster role

通过下面命令创建相应的cluster role资源:

kubectl apply -f psp-restrictive-cluster-roleyamlkubectl apply -f psp-permissive-cluster-roleyaml

Cluster Role Bindings

kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: psp-defaultsubjects:- kind: Group name: system:serviceaccounts namespace: deaultroleRef: kind: ClusterRole name: psp-restrictive apiGroup: rbac.authorization.k8s.io

上面的role binding会将restrictive cluster role绑定到所有的system service account。

使用下面的命令生成role binding资源:

kubectl apply -f psp-restrictive-cluster-role-binding.yaml

Testing

已经定义了restrictive policy并且将对应的psp绑定到对应的service account,我将通过重新生成开篇的deployment资源来验证pods是否可以创建。

首先,删除已经存在的deployment资源。

kubectl delete deploy nginx-deploymentkubectl get po,rs,deploy

资源查看

重新创建deployment:

kubectl apply -f nginx-deployment.yamlkubectl get po,rs,deploy

资源查看

注意:通过图可见在policies创建后,可以创建pod资源。

Breaking Policy Rules

在这部分,我将在deployment中使用已经在restrictive policy中禁止的“hostNetwork”。

首先,清楚前面创建的deployment资源。

kubectl delete deploy ninx-deploymentkubectl get po.rs,deploy

使用下面的命令和yaml文件重新创建相应资源:

apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-hostnetwork-deployment namespace: kube-system labels: app: nginxspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.4 hostNetwork: true

kubectl apply -f nginx-host-network-deployment.yamlkubectl get po,rs,deploy

可见replica set controller并没有创建相对应的pod,原因如下:

Warning FailedCreate 2m38s (x17 over 8m5s) replicaset-controller Error creating: pods "nginx-hostnetwork-deployment-fd75d78b-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used]

注意:上面的错误显示在创建deployment时试图获取已经被限制的资源,k8s集群不允许这样的行为。

Creating deployment with privileged access

在这部分,我将通过对一些controllers(deamon-set-controller,replicaset-controller,job-controller)的调用user和service account授予一些特殊权限。

首先,我先创建role binding。

apiVersion: rbac.authorization.k8s.io/v1beta1kind: RoleBindingmetadata: name: psp-permissive namespace: kube-systemroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: psp-permissivesubjects:- kind: ServiceAccount name: daemon-set-controller namespace: kube-system- kind: ServiceAccount name: replicaset-controller namespace: kube-system- kind: ServiceAccount name: job-controller namespace: kube-system

使用以下命令创建role binding:

kubectl apply -f psp-permissive-cluster-role-binding.yaml

接下来我将重新创建deployment并在pod中使用被restrictive policy限制使用的资源。当前deployment与前面deployment的区别在于现在在kube-system命名空间中创建deployment,以前则是在default命名空间中,这主要是由于刚刚对kube-system授予permissive policy权限。

apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-hostnetwork-deployment namespace: kube-system labels: app: nginxspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.4 hostNetwork: true

使用下面命令,重新创建deployment资源:

kubectl apply -f nginx-host-network-deployment-kube-system.yaml

使用下面命令,验证pod是否正常运行:

kubectl get po,rs,deploy -n kube-system | grep hostnetwork

注意:由于已经对kube-system命名空间的user和service account授权使用hostNetwork,可见nginx-hostnetwork-deployment pod已经部署在kube-system命名空间。

总结

上面的内容演示了如何通过使用PSP授权使用特殊资源,在k8s集群中实现Pod Security Policy安全策略。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:浅谈MyBatis原生批量插入的坑与解决方案
下一篇:最小化微服务漏洞 Secret存储敏感数据
相关文章

 发表评论

暂时没有评论,来抢沙发吧~