Example demo: How to simplify the OD security strategy in production?

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.

Keywords: Kubernetes network less SELinux

Added by JeDi58 on Thu, 02 Apr 2020 12:38:22 +0300