Kubernetes - Security Contexts
Lab assignment for understanding security contexts in Kubernetes
Kubernetes - Security Contexts
Prerequisites
- Kubernetes
- kubectl
Assignment
- Create a Security Contexts which define privilege and access control settings for a Pod or Container.
- We will use a custom image that includes a rogue binary for demonstration purposes.
- This binary allows escalation from a normal user to root in a Kubernetes pod.
1
kubectl run ubuntu --image=spurin/rootshell:latest -o yaml --dry-run=client -- sleep infinity | tee ubuntu_secure.yaml
1
kubectl apply -f ubuntu_secure.yaml
- With the pod running, let’s execute into it and observe the current user privileges. You’ll notice that we have root access:
1
kubectl exec -it ubuntu -- bash
1
exit
- Modify our YAML file to include a Security Context that specifies running as a non-root user with a specific UID and GID:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat <<EOF > ubuntu_secure.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: ubuntu
name: ubuntu
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
containers:
- args:
- sleep
- infinity
image: spurin/rootshell:latest
name: ubuntu
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
EOF
- Let’s replace the existing pod with our updated configuration. This replacement might take a little longer:
1
kubectl replace --force -f ubuntu_secure.yaml
- Let’s exec into the pod again. This time, you’ll observe that we’re logged in as a non-root user:
1
kubectl exec -it ubuntu -- bash
- If we run id, this will confirm we are a non root user:
1
id
- However, if we run the /rootshell binary this will allow privilege escalation:
1
/rootshell
- We can even run commands that require root access like apt update -
1
apt update
- Repeat this command until we exit the container:
1
exit
- To further secure our pod, we will add an additional Security Context to the container specification, disallowing privilege escalation.:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
cat <<EOF > ubuntu_secure.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: ubuntu
name: ubuntu
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
containers:
- args:
- sleep
- infinity
image: spurin/rootshell:latest
name: ubuntu
resources: {}
securityContext:
allowPrivilegeEscalation: false
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
EOF
- Again, let’s replace the pod with our new security settings:
1
kubectl replace --force -f ubuntu_secure.yaml
- Now, exec into the pod one more time:
1
kubectl exec -it ubuntu -- bash
- And try to escalate privileges, you can try this multiple times, the command will succeed but without root priviledge:
1
/rootshell
- And issue exit until we fully exit the container:
1
exit
- Finally, let’s clean up by deleting the pod and removing the YAML file -
1
kubectl delete -f ubuntu_secure.yaml --now ; rm -rf ubuntu_secure.yaml
This post is licensed under CC BY 4.0 by the author.