Kubernetes Pod Security Policy is a mechanism to enforce best security practices in Kubernetes. In this tutorial, we will explain how to enable Kubernetes Pod Security Policy across your cluster using kube-psp-advisor to address the practical challenges of building an adaptive and fine-grained security policy on Kubernetes in production.
What is a Kubernetes Pod Security Policy? An example
A Kubernetes Pod Security Policy is a cluster-level resource that controls security sensitive aspects of the pod specification limiting access privileges of a Kubernetes pod. For example you can use Kubernetes PSP for restricting:
- Running privileged containers
- The user that the container is running as
- Access the host process or network namespace
- Access the host filesystem
- Linux capabilities, Seccomp or SELinux profiles
A Pod Security Policy definition will look like the following:
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
privileged: true
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- hostPath
- secret
Code language: PHP (php)
This PSP is quite relaxed: allows the NET_ADMIN
and IPC_LOCK
capabilities, mount /
, /dev
and /run
from the host and Kubernetes secret volumes. Doesn’t enforce any file system group ID nor supplemental groups. Allows to run the container as any user, access the host network namespace and run as a privileged container. No SELinux policy is enforced.
How to enable #Kubernetes Pod #Security Policy with kube-psp-advisor
Click to tweet
How to enable Kubernetes Pod Security Policy
Implementing a Kubernetes Pod Security Policy is just like creating any other Kubernetes resource in your cluster:
$ kubectl apply -f example-psp.yaml
Then, to verify the Pod Security Policy has been created successfully:
$ kubectl get psp
Code language: JavaScript (javascript)
The output will be look like following:
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
example true NET_ADMIN, IPC_LOCK RunAsAny RunAsAny RunAsAny RunAsAny false hostPath,secret
Code language: JavaScript (javascript)
But how do you know what your Pod Security Policy should be like? Does it restrict everything that we do not need? We can end up with a policy that is either too restricted or too loose.
Kubernetes Pod Security Policy best practices and challenges of implementing in production
We all know the theory of Kubernetes security best practices:
- Do not run privileged containers
- Do not run containers as root
- Do not allow access to the host namespace
- Restrict Linux capabilities
- …
However, building a Pod Security Policy based on Kubernetes security best practices might not be realistic for a bunch of reasons.
Let me give you a few real live examples that you can find out in the wild:
For performance reasons, the IPC_LOCK
capability might be required. We can see this in multi-process applications like Cassandra, MySQL, etc.
Monitoring and security components usually require extended access privileges in order to see everything they need. For example, PacketBeat requires NET_ADMIN
capability to capture network traffic. Sysdig, our container security product, requires to be run as a privileged container to hook into the kernel to capture system calls and access to the host namespace to see all the running containers that we want to monitor and secure. If you want to debug a Golang application using Delve, then you will need add the SYS_PTRACE
capability to the pod.
A production security policy depends on the requirements of the software run and how it was built. Implementing a Kubernetes Pod Security policy is a joint effort between DevSecOps and software development teams. They both need to come up with a way that adapts the theory of Kubernetes security best practices with the many different access privilege requirements from diverse applications.
Kubernetes Security Policy made easy with kube-psp-advisor
Kubernetes Pod Security Policy Advisor (a.k.a kube-psp-advisor) is an opensource tool from Sysdig, like Sysdig Inspect or Falco. kube-psp-advisor scans the existing security context from Kubernetes resources like deployments, daementsets, replicasets, etc taken as the reference model we want to enforce and then automatically generates the Pod Security Policy for all the resources in the entire cluster.
kube-psp-advisor will look at different attributes to create the recommended Pod Security Policy:
- allowPrivilegeEscalation
- allowedCapabilities
- allowedHostPaths
- hostIPC
- hostNetwork
- hostPID
- privileged
- readOnlyRootFilesystem
- runAsUser
- Volume
Using kube-psp-advisor is really simple. First clone and build the project:
$ git clone https://github.com/sysdiglabs/kube-psp-advisor
$ cd kube-psp-advisor && make build
Code language: PHP (php)
Now we are ready to use it. kube-psp-advisor can accept a few parameters:
--namespace
. By default, the Pod Security Policy is generated for the resources in the entire cluster. With this flag just analyzes and generates the policy for the dedicated namespace.
--report
. Prints the resources that are making use of each Kubernetes security feature, e.g.: which pods, deployments, etc are using hostIPC
, hostNetwork
, etc.
--kubeconfig
. Absolute path to the kubeconfig
file, defaults to $HOME/.kube/config
.
kube-psp-advisor loaded the kubeconfig file, connect to the kubernetes cluster API server and then conduct the scan which print through stdout
the generated PSP, like this:
$ ./kube-psp-advisor --namespace=psp-test
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
creationTimestamp: null
name: pod-security-policy-20181130114734
spec:
allowedCapabilities:
- SYS_ADMIN
- NET_ADMIN
allowedHostPaths:
- pathPrefix: /bin
- pathPrefix: /tmp
- pathPrefix: /usr/sbin
- pathPrefix: /usr/bin
fsGroup:
rule: RunAsAny
hostIPC: false
hostNetwork: false
hostPID: false
privileged: true
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- hostPath
- configMap
- secret
Code language: PHP (php)
To finish, we will review and apply the generated Kubernetes Pod Security Policy:
$ ./kube-psp-advisor --namespace psp-test > psp-test.yaml && cat psp-test.yaml
$ kubectl apply -f psp-test.yaml
If we want to know more on how it was built, we will use the --report
flag:
$ ./kube-psp-advisor --namespace=psp-test --report | jq .podSecuritySpecs
{
"hostIPC": [
{
"metadata": {
"name": "busy-rs",
"kind": "ReplicaSet"
},
"namespace": "psp-test",
"hostPID": true,
"hostMetwork": true,
"hostIPC": true,
"volumeTypes": [
"configMap"
]
},
{
"metadata": {
"name": "busy-job",
"kind": "Job"
},
"namespace": "psp-test",
"hostIPC": true,
"volumeTypes": [
"hostPath"
],
"mountedHostPath": [
"/usr/bin"
]
}
],
"hostNetwork": [
{
"metadata": {
"name": "busy-rs",
"kind": "ReplicaSet"
},
"namespace": "psp-test",
"hostPID": true,
"hostMetwork": true,
"hostIPC": true,
"volumeTypes": [
"configMap"
]
},
{
"metadata": {
"name": "busy-pod",
"kind": "Pod"
},
"namespace": "psp-test",
"hostMetwork": true,
"volumeTypes": [
"hostPath",
"secret"
],
"mountedHostPath": [
"/usr/bin"
]
}
],
"hostPID": [
{
"metadata": {
"name": "busy-deploy",
"kind": "Deployment"
},
"namespace": "psp-test",
"hostPID": true,
"volumeTypes": [
"hostPath"
],
"mountedHostPath": [
"/tmp"
]
},
{
"metadata": {
"name": "busy-rs",
"kind": "ReplicaSet"
},
"namespace": "psp-test",
"hostPID": true,
"hostMetwork": true,
"hostIPC": true,
"volumeTypes": [
"configMap"
]
}
]
}
Code language: JavaScript (javascript)
Conclusion
Building a Kubernetes Pod Security Policy can be hard. Not all application might work following all the Kubernetes security best practices by the book. That doesn’t mean that you should ignore and skip implementing PSP at all. If an specific Pod requires some additional access, still being able to implement a Pod Security Policy that restricts further access privileges is definitely a good security approach. This is actually something that you will find in most production environments.
kube-psp-advisor makes implementing Kubernetes Pod Security Policy a simple and straightforward process, so you can get running in almost no time, adapting to your application requirements and specifically fine-grained for each one to allow only the least access privilege.