First Look - Kubeaudit
Table of Contents
I wanted to call this article “Gleaming the Kube” but someone already did that.
Kubernetes is a relatively complex system, and I typically deal with OpenStack so that is saying something. With any new and complex (and valuable) system it’s easy to use that system to build, shall we say, services with less than desirable security settings. And thus we have people building tools that help to ensure systems and definitions are as secure as is reasonably possible. Enter kubeaudit.
Kubeaudit
Kubeaudit is a helpful tool from the folks at Shopify. A Canadian company by the way!
kubeaudit is a command line tool to audit Kubernetes clusters for various different security concerns: run the container as a non-root user, use a read only root filesystem, drop scary capabilities, don’t add new ones, don’t run privileged, … You get the gist of it and more on that later. Just know: kubeaudit makes sure you deploy secure containers!
Because go compiles into a nice clean binary, it’s easy to install kubeaudit.
wget -P /tmp https://github.com/Shopify/kubeaudit/releases/download/v0.5.3/kubeaudit_0.5.3_linux_amd64.tar.gz
mkdir ~/bin # if you don't have one
export PATH=$PATH:~/bin
# only untar kubeaudit, there is a licence and readme file in there as well which we don't need
tar zxvf /tmp/kubeaudit_0.5.3_linux_amd64.tar.gz -C ~/bin kubeaudit
Check version.
$ kubeaudit version
INFO[0000] Kubeaudit version BuildDate="2019-03-29T15:36:37Z" Commit=b19f6509d92abc22a8cf2789a98a740af20831e6 Version=0.5.3
INFO[0000] Not running inside cluster, using local config
INFO[0000] Kubernetes server version Major=1 Minor=13 Platform=linux/amd64
Note that this will check the Kubernetes version as well through reading the .kube/config
.
Audit
Let’s deploy an nginx container.
NOTE: I alias kubectl to k
$ k run nginx --image=nginxinc/nginx-unprivileged --port=8080
It’s up and running.
$ k get all
NAME READY STATUS RESTARTS AGE
pod/nginx-6c6d45d55d-ckhzw 1/1 Running 0 51s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 51s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-6c6d45d55d 1 1 1 51s
Now audit it with kubeaudit
, but we’ll only check for nonroot.
$ kubeaudit nonroot -n nginx-unpriv
INFO[0000] Not running inside cluster, using local config
ERRO[0000] RunAsNonRoot is not set in ContainerSecurityContext, which results in root user being allowed! Container=nginx KubeType=deployment Name=nginx Namespace=nginx-unpriv
ERRO[0000] RunAsNonRoot is not set in ContainerSecurityContext, which results in root user being allowed! Container=nginx KubeType=pod Name=nginx-6c6d45d55d-ckhzw Namespace=nginx-unpriv
Ok let’s fix that by patching the deployment.
Here is the patch:
$ cat nginx-unpriv-runasnonroot.yml
spec:
template:
spec:
containers:
- image: nginxinc/nginx-unprivileged
name: nginx
securityContext:
runAsNonRoot: true
securityContext:
runAsNonRoot: true
Apply the patch.
$ k patch deployment nginx --patch "$(cat nginx-unpriv-runasnonroot.yml)"
deployment.extensions/nginx patched
A new pod should be created.
~$ k get all
NAME READY STATUS RESTARTS AGE
pod/nginx-686cc9b75c-jfc8t 1/1 Running 0 24s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 3m50s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-686cc9b75c 1 1 1 24s
replicaset.apps/nginx-6c6d45d55d 0 0 0 3m50s
And now to run audit again:
$ kubeaudit nonroot -n nginx-unpriv
INFO[0000] Not running inside cluster, using local config
No errors.
That’s it. A simple example of using kubeaudit
.