Pod security policy is critical to enhance K8S cluster security.This article will continue with the previous article on Pod security.
First, it briefly describes how to associate a Pod with a Pod security policy and uses RBAC to show the steps.It then describes how to enable the default PSP in Rancher and create a custom PSP.Finally, a tool will be used to simplify the use of Pod security strategy in production, greatly increase productivity, and quickly stamp ~
This article is from RancherLabs
stay Previous Articles In, we demonstrated how to enable PSP in Rancher using a restricted PSP policy as the default value.We also show how to prevent privileged Pod s from being accepted into a cluster.
We purposely omitted specific details about role-based access control (RBAC) and how to connect Pod to a specific PSP.So, this article will allow us to continue our in-depth study of PSP.
Match Pod to Pod Security Policy
You may have noticed that PSP mode is not associated with any Kubernetes namespace, Service Account, or Pod.In fact, PSP is a cluster-wide resource.So how do we specify which Pods should be managed by which PSPs?The following diagram shows how all participating components, resources, and access processes work.
Perhaps it sounds complicated at first.Now let's go into more detail.
When a Pod is deployed, access control applies policies based on the object requested for deployment.
Pod itself has no associated policy - it is the service account that executes the Deployment.In the figure above, Jorge deployed the pod using webapp-sa service account.
RoleBinding associates service account with Roles (or ClusterRoles), which is a resource that specifies that PSP can be used.In this diagram, webapp-sa is associated with webapp-role, which provides licenses for specific PSP resources.When you deploy a Pod, the Pod is checked against the webapp-sa PSP.In fact, a service account can use multiple PSPs, and one of them can verify a Pod is sufficient.You can see the details in the official documents:
https://kubernetes.io/docs/concepts/policy/pod-security-policy/#policy-order
Access control then determines whether Pod meets any of these PSP s.If the Pod meets the requirements, access control dispatches the Pod; if the Pod does not meet the requirements, deployment is blocked.
The above can be summarized as follows:
-
Pod identity is determined by its service account
-
If no service account is declared in the specification, the default account will be used
- You need to allow the use of declared Role s or ClusterRole
Finally, you need to have a RoleBinding that associates the Role (thereby allowing access using PSP) with the Servcie Account declared in the Pod specification.
Let's illustrate with some examples.
Real examples of RBAC
Assuming you already have a PSP-enabled cluster, this is a common way to create a restrictive PSP using PSP that can be used by any Pod.You will then add a more specific PSP that has additional privileges to bind to a specific service account.Having a default, secure, and rigorous policy helps cluster management because most Pods do not require special privileges or functionality and run by default.Then, if some of your workloads require additional privileges, we can create a custom PSP and bind a specific service account for that workload to a less restricted PSP.
However, how do I bind a Pod to a specific PSP instead of the default restricted PSP?And how do you do this using a normal Kubernetes cluster that automatically adds RoleBindings?
Let's look at a complete example where we define some security defaults (restricted PSP s that any service account in the cluster can use) and then provide additional privileges to a single service account for a specific deployment that requires that service.
First, we manually create a new namespace.It is not managed by Rancher, so RoleBindings are not automatically created.Then we try to deploy a restricted Pod in that namespace:
$ kubectl create ns psp-test $ cat 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 $ kubectl -n psp-test apply -f deploy-not-privileged.yaml $ kubectl -n psp-test describe rs ... Warning FailedCreate 4s (x12 over 15s) replicaset-controller Error creating: pods "not-privileged-deploy-684696d5b5-" is forbidden: unable to validate against any pod security policy: []
A pod cannot be created because there is no RoleBinding in the namespace psp-test and the namespace is bound to a role that allows any PSP to be used.We will solve this problem by creating a cluster-wide ClusterRole and ClusteterRoleBinding to allow any Service Account to use a restricted PSP by default.When PSP was enabled in previous articles, Rancher created a restricted PSP.
resourceNames: - restricted-psp --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: restricted-role-bind roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: use-restricted-psp subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:serviceaccounts $ kubectl apply -f clusterrole-use-restricted.yaml
Unprivileged deployment should work after we apply these changes.
However, if we need to deploy a privileged Pod, it will not be allowed by the existing policy:
$ cat deploy-privileged.yaml apiVersion: v1 kind: ServiceAccount metadata: name: privileged-sa namespace: psp-test --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: privileged-deploy name: privileged-deploy namespace: psp-test 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 serviceAccountName: privileged-sa $ kubectl -n psp-test apply -f deploy-privileged.yaml $ kubectl -n psp-test describe rs privileged-deploy-7569b9969d Name: privileged-deploy-7569b9969d Namespace: default Selector: app=privileged-deploy,pod-template-hash=7569b9969d Labels: app=privileged-deploy ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedCreate 4s (x14 over 45s) 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]
In this case, since we created ClusterRoleBinding, Pod can use PSP, but restricted-psp will not validate Pod because it requires privileged, hostNetwork, and other parameters.
We have seen the restricted-psp policy in the previous article.Let's examine the details of default-psp, which Rancher created when enabling PSP to allow these privileges:
$ kubectl get psp default-psp -o yaml apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' creationTimestamp: "2020-03-10T08:45:08Z" name: default-psp resourceVersion: "144774" selfLink: /apis/policy/v1beta1/podsecuritypolicies/default-psp uid: 1f83b803-bbee-483c-8f66-bfa65feaef56 spec: allowPrivilegeEscalation: true allowedCapabilities: - '*' fsGroup: rule: RunAsAny hostIPC: true hostNetwork: true hostPID: true hostPorts: - max: 65535 min: 0 privileged: true runAsUser: rule: RunAsAny seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny volumes: - '*'
You can see that this is a very relaxed strategy, especially if we allow privileged, hostNetwork, hostPID, hostIPC, hostPorts, and other features to run as root.
We just need to explicitly allow the Pod to use PSP.We bind privileged-sa ServiceAccount to the ClusterRole by creating a ClusterRole similar to the existing restricted-cluster role but allowing default-psp resources and then creating a RoleBinding for our psp-test namespace:
$ cat clusterrole-use-privileged.yaml --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: use-privileged-psp rules: - apiGroups: ['policy'] resources: ['podsecuritypolicies'] verbs: ['use'] resourceNames: - default-psp --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: privileged-role-bind namespace: psp-test roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: use-privileged-psp subjects: - kind: ServiceAccount name: privileged-sa $ kubectl -n psp-test apply -f clusterrole-use-privileged.yaml
After a while, the privileged Pod will be created.Then you will notice that restricted-psp and default-psp are now ready for direct use.Next, let's take a closer look at them.
Default PSP on Rancher
Enable PSP access control by editing cluster settings in Rancher and select one of the defined PSPs as the default option:
Rancher will create a pair of PSP resources in the cluster:
-
restricted-psp: If you choose "restricted" as the default PSP
- default-psp: The default PSP, which allows the creation of privileged Pod s.
In addition to restricted-psp and default-psp, Rancher also creates a ClusterRole named restricted-clusterrole:
annotations: serviceaccount.cluster.cattle.io/pod-security: restricted creationTimestamp: "2020-03-10T08:44:39Z" labels: cattle.io/creator: norman name: restricted-clusterrole rules: - apiGroups: - extensions resourceNames: - restricted-psp resources: - podsecuritypolicies verbs: - use
This ClusterRole allows restricted-psp policy.Where can Binding allow authorization to use pod ServiceAccount?
For namespaces that belong to items in Rancher, it also sets the RoleBinding configuration for you:
$ kubectl -n default get rolebinding default-default-default-restricted-clusterrole-binding -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: annotations: podsecuritypolicy.rbac.user.cattle.io/psptpb-role-binding: "true" serviceaccount.cluster.cattle.io/pod-security: restricted labels: cattle.io/creator: norman name: default-default-default-restricted-clusterrole-binding namespace: default ... roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: restricted-clusterrole subjects: - kind: ServiceAccount name: default namespace: default
The resource name (default-default-default-restricted-cluster role-binding) can be confusing, and in fact it consists of:
default-serviceaccountname-namespace-restricted-clusterrole-binding
And if you create a new service account similar to myservice account, a new role binding is automatically created:
$ kubectl create sa myserviceaccount serviceaccount/myserviceaccount created $ kubectl get rolebinding NAME AGE --- default-default-default-restricted-clusterrole-binding 13m default-myserviceaccount-default-restricted-clusterrole-binding 4s
With this amazing feature, you do not need to configure RBAC for secure pod s that do not require any elevated privileges.
Create your PSP in Rancher
PSP is a standard Kubernetes resource and the entire Pod security policy, so you can use it through the Kubernetes API or the kubectl CLI.
You can create your own custom PSP s by defining them in a YAML file and then use kubectl to create resources in the cluster.View the official documentation to see all available controls ( https://kubernetes.io/docs/concepts/policy/pod-security-policy/ ).Once the control set is defined in YAML, you can run:
$ kubectl create psp my-custom-psp
To create a PSP resource.
With Rancher, you can view or add new policies directly from the UI:
PSP is powerful but complex
Configuring Pod security policies is a tedious process.After you enable PSP in the Kubernetes cluster, any Pod you want to deploy must be allowed through one of the PSPs.Implementing strong security policies can be time consuming, and generating a policy for each deployment of each application can be a burden.If your policy is very relaxed, the least privileged access method is not enforced; however, if it has many restrictions, you may damage your application because Pod cannot run successfully in Kubernetes.
The ability to automatically generate Pod security policies with a minimum set of access requirements will help you install the PSP more easily.And you can't just deploy them in a production environment without verifying that your application works and that manual testing is cumbersome and inefficient.What if you could validate the PSP against the runtime behavior of the Kubernetes workload?
How to simplify the use of PSP in production environments?
Kubernetes Pod Security Policy Advisor (also known as kube-psp-advisor) is an open source tool for Sysdig.Kube-psp-advisor scans existing security contexts from Kubernetes resources such as deployment, daemonset, replicaset, etc., uses them as the reference model we want to execute, and automatically generates Pod security policies for all resources throughout the cluster.Kube-psp-advisor creates a recommended od security policy by viewing different attributes:
-
allowPrivilegeEscalation
-
allowedCapabilities
-
allowedHostPaths
-
hostIPC
-
hostNetwork
-
hostPID
-
Privileged
-
readOnlyRootFilesystem
-
runAsUser
- Volume
Check the kube-psp-advisor tutorial for more details on how it works:
https://sysdig.com/blog/enable-kubernetes-pod-security-policy/
Automatically generate PSP using Sysdig Secure
Sysdig Secure Kubernetes Policy Advisor helps users create and validate Pod security policies.
The first step is to set up a new PSP simulation environment.You can simulate many different strategies in different scopes, such as the Kubernetes namespace.
Sysdig analyzes the requirements of the Pod specification in your Deployment definition and creates a PSP with the least privileges for your application.This controls whether privileged Pods are allowed to run as containers, volume s, and so on.Ni can fine-tune the PSP and define a namespace for the simulation environment you will run:
The policy on the left destroys the application because nginx Deployment is a privileged Pod and has host network access.You must decide whether to expand the PSP to allow this behavior or choose to reduce Deployment privileges to accommodate this strategy.In any case, you will detect this condition before applying the PSP, which will prevent Pod from running and cause damage on Application deployment.
Conclusion
As these examples show, by granting or denying access to specific resources, PSP allows you to fine-grained control over Pod s and containers running in Kubernetes.These policies are relatively easy to create and deploy and should be useful components of any Kubernetes security policy.