Kubernetes PSP seems not to affect something

2/3/2020

I'm trying to deploy a restricted psp which should disable the use of the root user in a pod:

kind: PodSecurityPolicy
metadata:
  name: unprivilegedpolicy
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
  fsGroup:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
  readOnlyRootFilesystem: false

I've added this psp to a ClusterRole and binded it to the namespace hello-world:

Name:         UnPrivilegedClusterRole
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources                   Non-Resource URLs  Resource Names        Verbs
  ---------                   -----------------  --------------        -----
  podsecuritypolicies.policy  []                 [unprivilegedpolicy]  [use]

[root@master01 ~]# kubectl describe clusterrolebindings.rbac.authorization.k8s.io HelloWorldRoleBinding
Name:         HelloWorldRoleBinding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  UnPrivilegedClusterRole
Subjects:
  Kind   Name                    Namespace
  ----   ----                    ---------
  Group  system:serviceaccounts  hello-world

BUT if I try to run a ngnix container ```kubectl run --name=nginx hello-world" the containers succesfully runs as root user. The deployment is deployed via a ServiceAccount. I also enabled the PodSecurityPolicy at the admission-controller.

Does anybody has a solution for this?

-- Simon
kubernetes

1 Answer

2/12/2020

First of all:

$ kubectl run --name=nginx hello-world

You did not specify image name of the pod. Correct syntax should be:

$ kubectl run --image=nginx NAME_OF_DEPLOYMENT

As said above commands will try to create a deployment.


The issue you are encountering is most probably connected with:

  • Not working/turned on admission controller

On newly created Kubernetes cluster with pod security policy turned on you should not be able to spawn any pod regardless of your privileges.

Pod security policy control is implemented as an optional (but recommended) admission controller. PodSecurityPolicies are enforced by enabling the admission controller, but doing so without authorizing any policies will prevent any pods from being created in the cluster.

-- Kubernetes.io: enabling pod security policies

Admission controller as well as pod security policy and RBAC are strongly connected with solutions you are working with. You should refer to documentation specific to your case.

For example:

  • Newly created GKE cluster with pod security enabled and none PSP configured will not create pods. It will display a message: Unable to validate against any pod security policy: []

Warning: If you enable the PodSecurityPolicy controller without first defining and authorizing any actual policies, no users, controllers, or service accounts can create or update Pods. If you are working with an existing cluster, you should define and authorize policies before enabling the controller.

-- GKE: Pod security policies and how to enable/disable it

  • Newly created Kubernetes cluster with kubespray (with pod security policy variable set to true when provisioning and running on Ubuntu) will have a restrictive PSP created and it will have a MustRunAsNonRoot parameter inside the PSP.

There is another issue with NGINX pod. NGINX image will try to run as root user inside of the pod. Admission controller with PSP configured with:

runAsUser:
  rule: MustRunAsNonRoot

will deny that with message: Error: container has runAsNonRoot and image will run as root with accordance to PSP.

To run NGINX pod with this policy you would need to either:

  • Create a PSP (which will allow to run as root user inside a pod) with:
  runAsUser:
    rule: RunAsAny
  • Create own NGINX image configured in a way that allows running NGINX as non root user.

Example of such pod below:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: non-root-nginx
  name: non-root-nginx
spec:
  securityContext:
    runAsUser: 101
    fsGroup: 101
  containers:
  - image: nginx
    name: non-root-nginx
    volumeMounts:
    - mountPath: /var/cache/nginx
      name: edir
    - mountPath: /var/run
      name: varun
    - mountPath: /etc/nginx/conf.d/default.conf
      name: default-conf
      subPath: default.conf
  dnsPolicy: ClusterFirst
  restartPolicy: Never
  volumes:
  - name: edir
    emptyDir: {}
  - name: varun
    emptyDir: {}
  - name: default-conf
    configMap:
      name: nginx8080
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx8080
  namespace: default
data:
  default.conf: |+
    server {
        listen       8080;
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
-- Dawid Kruk
Source: StackOverflow