** NOTE**: The steps below must be run with a cluster-admin user.
-
Create a new namespace for running our tests:
NAMESPACE=test-drop-capabilities oc create ns ${NAMESPACE}
-
Create an SA for running our application
oc -n ${NAMESPACE} create sa testuser
-
We are going to create our own SCC based on the restricted one, on top of that we will give it a priority of 1 so it gets prioritized and we will allow to run oud pods as any user.
NOTE: We removed
system:authenticated
group so we will need to assign the SCC manually to our SAs/Users/Groups.cat <<EOF | oc create -f - kind: SecurityContextConstraints metadata: name: restricted-dropcaps-test priority: 1 readOnlyRootFilesystem: false requiredDropCapabilities: - KILL - MKNOD - SETUID - SETGID runAsUser: type: RunAsAny seLinuxContext: type: MustRunAs supplementalGroups: type: RunAsAny users: [] volumes: - configMap - downwardAPI - emptyDir - persistentVolumeClaim - projected - secret allowHostDirVolumePlugin: false allowHostIPC: false allowHostNetwork: false allowHostPID: false allowHostPorts: false allowPrivilegeEscalation: true allowPrivilegedContainer: false allowedCapabilities: null apiVersion: security.openshift.io/v1 defaultAddCapabilities: null fsGroup: type: MustRunAs groups: [] EOF
-
We're grating use privileges of this new SCC to the SA test-user we created at step 2
oc -n ${NAMESPACE} adm policy add-scc-to-user restricted-dropcaps-test system:serviceaccount:${NAMESPACE}:testuser
-
Now we run a pod that requests to drop all capabilities:
cat <<EOF | oc -n ${NAMESPACE} create -f - apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: reversewords-app-captest-uid0 name: reversewords-app-captest-uid0 spec: replicas: 1 selector: matchLabels: app: reversewords-app-captest-uid0 strategy: {} template: metadata: creationTimestamp: null labels: app: reversewords-app-captest-uid0 spec: serviceAccountName: testuser containers: - image: quay.io/mavazque/reversewords:ubi8 name: reversewords command: ["sleep", "9999"] resources: {} env: - name: APP_PORT value: "80" securityContext: runAsUser: 0 capabilities: drop: - all status: {} EOF
-
If we check the capabilities present on the pod we see they've not been dropped:
oc -n ${NAMESPACE} exec -ti deployment/reversewords-app-captest-uid0 -- cat /proc/1/status | grep Cap
NOTE: Effective capabilities are not empty.
CapInh: 000000000000051b CapPrm: 000000000000051b CapEff: 000000000000051b CapBnd: 000000000000051b CapAmb: 0000000000000000
NOTE: We have the following capabilities available.
capsh --decode=000000000000051b 0x000000000000051b=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_setpcap,cap_net_bind_service
-
If we explicitly drop the caps in the list above on the pod definition it will work as expected:
cat <<EOF | oc -n ${NAMESPACE} create -f - apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: reversewords-app-captest-uid0-drop-explicitly name: reversewords-app-captest-uid0-drop-explicitly spec: replicas: 1 selector: matchLabels: app: reversewords-app-captest-uid0-drop-explicitly strategy: {} template: metadata: creationTimestamp: null labels: app: reversewords-app-captest-uid0-drop-explicitly spec: serviceAccountName: testuser containers: - image: quay.io/mavazque/reversewords:ubi8 name: reversewords command: ["sleep", "9999"] resources: {} env: - name: APP_PORT value: "80" securityContext: runAsUser: 0 capabilities: drop: - CHOWN - DAC_OVERRIDE - FOWNER - FSETID - SETPCAP - NET_BIND_SERVICE status: {} EOF
-
If we check the capabilities present on the pod we see they've been dropped:
oc -n ${NAMESPACE} exec -ti deployment/reversewords-app-captest-uid0-drop-explicitly -- cat /proc/1/status | grep Cap
NOTE: Effective capabilities are empty.
CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 0000000000000000 CapAmb: 0000000000000000