In the previous post I looked at how security is handled in Kubernetes. Let’s now see how it works in practice.
One of the most powerful controllers is the Pod Security Policy admission controller (PSP). PSP is a cluster-level security mechanism that enables control over sensitive aspects of pod specification. It allows you to define a set of conditions a pod must meet in order to be accepted into the system.The following use case illustrates how it works.
Let’s assume that we have a shared file system (eg. NFS) that should be accessible by containers. We want to define the following set of conditions:
- Restrict access to the particular type of volumes.
- Block access to host drives.
- Permit the use of persistent volume claims (PVC) existing in a particular Kubernetes namespace (to be exact, this namespace is different from kernel namespace; K8s namespace is a space admins grant users). PVs are global, but the user is restricted to using PVC in a given namespace. It is impossible for a user to go beyond this very namespace so even if they try to create PVC, and it is indeed created, there will be no attached PV as it lies below the user access layer.
- Prohibit path-mounting from the host filesystem. This blocks for containers access to the paths with user home directories, eg, directories containing all user names in the OS along with their passwords.
- Forbid the escalation of rights (su, sudo).
- Forbid the launching of containers as privileged containers (that is, those with direct access to host resources (eg. hardware).
- Limit users with the right to launch processes in a container. This allows us to establish that only users with specified UIDs and who belong to a specified group can run certain processes.
- Define groups that can have access to the filesystem.
In order to launch Pod Security Policy, the following requirements must be met:
- Enable RBAC (Role-based Access Control) - enabled by default from Kubernetes 1.6.
- Enable PSP (admission plugin) using the option --enable-admission-plugins=PodSecurityPolicy, which is added to start the parameters of the Kubernetes api-server.
Pod Security Policy offers several parameters to be configured:
- privileged - defines if a container can be run as privileged, which effectively allows a container to access all devices on a host.
- hostPID, hostIPC - defines if a container can share the host process ID and interprocess communication namespaces.
- hostNetwork, hostPorts - determines if a pod can access a host network namespace and the ports allowed in that namespace.
- volumes - defines which type of volumes a pod can use.
- allowedHostPaths - allows which paths are allowed in hostPath volumes.
- allowedFlexVolumes - defines allowable types of flexVolumes.
- fsGroup - used to set the group that owns the pod volumes.
- readOnlyRootFilesystem - defines whether or not the root filesystem for a pod can be modified
- runAsUser, runAsGroup - limits the user IDs that are allowed and the primary group ID that can be used to launch a pod (the processes in a container)
- supplementalGroups - controls which supplemental group ID can be assigned to processes in a pod.
- allowPrivilegeEscalation - sets the possibility of privilege escalation for child processes in a pod (restrictions on setuid, eg.: su, sudo).
- defaultAddCapabilities, requiredDropCapabilities, allowedCapabilities - defines the allowable Linux capabilities (gaining additional privileges).
- seLinux - the container’s SELinux context.
- allowedProcMountTypes - defines which mount type can be used; it is read-only and masked by default.
PSP - a real-life example of a policy
Let’s take a look at the example of a restricted policy below. This policy limits the granting of potentially dangerous privileges and effectively prevents users from gaining access to resources that should not be visible. Benefits of such limitations are: avoiding sensitive data leakages, and destroying data or getting control of the hardware and operating system below the containers. The user and group IDs 32767 are designated as a restricted system user (you may want to replace it with any other IDs existing in your system). A list of volumes is the recommended minimum. Restricting any of the listed volume types can potentially lead to the functionality of pods/containers being broken. The policy below is a reasonable minimum that should be extended only under justified circumstances.
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
spec:
allowPrivilegeEscalation: false
fsGroup:
ranges:
- max: 32767
min: 32767
rule: MustRunAs
requiredDropCapabilities:
- ALL
runAsUser:
ranges:
- max: 32768
min: 32767
rule: MustRunAs
seLinux:
rule: RunAsAny
supplementalGroups:
ranges:
- max: 32767
min: 32767
rule: MustRunAs
volumes:
- configMap
- emptyDir
- projected
- secret
- downwardAPI
To make your work faster and smoother, you may use PSP Advisor. This tool enables you to show what privileges are needed to run certain processes.
Conclusion
If used properly, Pod Security Policies provide granular control over what actions users can perform on a Kubernetes cluster. PSP will help you secure a K8s cluster and limit permissions for users.