1. Introduction
Kubescape can improve Kubernetes security in many ways, including vulnerability scanning, compliance analysis, and misconfiguration scanning. It scans clusters, helm charts, and manifest files (YAML or JSON) against security frameworks like MITRE ATT&CK and the NSA framework. Kubescape can also patch container image vulnerabilities and suggest resolutions to manifest file misconfigurations.
In this tutorial, we describe how to secure Kubernetes with Kubescape.
2. Installing Kubescape
We can install Kubescape by downloading the script file with curl. Alternatively, we can install Kubescape using a default package manager such as apt, dnf, and zypper.
2.1. Installing With curl
To install Kubescape with curl, we simply download the installation script from the GitHub repository:
$ curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | /bin/bash
Typically, this method will install the latest version of Kubescape. However, it won’t update automatically.
2.2. Installing With apt
We can install Kubescape on Ubuntu and Debian using apt since they use the same package manager.
On Ubuntu, we’ll add the PPA repository:
$ sudo add-apt-repository ppa:kubescape/kubescape
After that, we’ll update apt and install Kubescape:
$ sudo apt update && sudo apt install kubescape
To install Kubescape on Debian, we’ll add the corresponding repository for the Debian version to /etc/apt/sources.list.d:
$ echo 'deb http://download.opensuse.org/repositories/home:/kubescape/Debian_[VERSION_NUMBER]/ /'
| sudo tee /etc/apt/sources.list.d/home:kubescape.list
In the command above, we’ll replace [VERSION_NUMBER] with our Debian’s version number. Let’s try this on a Debian 10 system:
$ echo 'deb http://download.opensuse.org/repositories/home:/kubescape/Debian_10/ /'
| sudo tee /etc/apt/sources.list.d/home:kubescape.list
Next, we’ll download the repository’s GPG keyring:
$ curl -fsSL https://download.opensuse.org/repositories/home:kubescape/Debian_10/Release.key
| gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/home_kubescape.gpg > /dev/null
Finally, we’ll update apt and install Kubescape:
$ sudo apt update && sudo apt install kubescape
2.3. Installing With zypper
When installing Kubescape on OpenSUSE, we simply refresh zypper and run zypper install:
$ sudo zypper refresh && sudo zypper install kubescape
2.4. Installing With dnf
To install Kubescape on Fedora, we’ll add the repository:
$ dnf config-manager --add-repo https://download.opensuse.org/repositories/home:kubescape/Fedora_Rawhide/home:kubescape.repo
Then we install:
$ dnf install kubescape
2.5. Other Installation Methods
We can also install Kubescape by downloading the package directly and installing it with a package manager. However, we may not get the latest version. To use this method on Ubuntu 22.04, we’ll download the package using wget:
$ wget https://download.opensuse.org/repositories/home:/kubescape/xUbuntu_22.04/arm64/kubescape_3.0.3_amd64.deb
Once downloaded, we’ll install the package using dpkg:
$ sudo dpkg -i kubescape_3.0.3_amd64.deb
On Fedora, we’ll download the package using wget:
$ wget https://download.opensuse.org/repositories/home:/kubescape/Fedora_Rawhide/x86_64/kubescape-3.0.8-1.121.x86_64.rpm
Then, we’ll install it using the rpm command:
$ sudo rpm -i kubescape-3.0.8-1.121.x86_64.rpm
Packages for various distros and architecture are available on OpenSUSE.
3. Scanning Kubernetes With Kubescape
We can get an overview of our cluster’s security posture by running kubescape scan:
$ kubescape scan
...truncated...
Control plane
┌────┬─────────────────────────────────────┬────────────────────────────────────┐
│ │ Control name │ Docs │
├────┼─────────────────────────────────────┼────────────────────────────────────┤
│ ✅ │ API server insecure port is enabled │ https://hub.armosec.io/docs/c-0005 │
│ ❌ │ Anonymous access enabled │ https://hub.armosec.io/docs/c-0262 │
│ ...truncated... │
└────┴─────────────────────────────────────┴────────────────────────────────────┘
Access control
┌────────────────────────────────────────────────────┬───────────┬────────────────────────────────────┐
│ Control name │ Resources │ View details │
├────────────────────────────────────────────────────┼───────────┼────────────────────────────────────┤
│ Administrative Roles │ 1 │ $ kubescape scan control C-0035 -v │
│ List Kubernetes secrets │ 1 │ $ kubescape scan control C-0015 -v │
│ Minimize access to create pods │ 1 │ $ kubescape scan control C-0188 -v │
│ ...truncated... │
└────────────────────────────────────────────────────┴───────────┴────────────────────────────────────┘
...truncated...
Compliance Score
────────────────
The compliance score is calculated by multiplying control failures by the number of failures against supported compliance frameworks.
Remediate controls, or configure your cluster baseline with exceptions, to improve this score.
* MITRE: 80.03%
* NSA: 75.93%
View a full compliance report by running '$ kubescape scan framework nsa' or '$ kubescape scan framework mitre'
Then again, we can run specific scans using frameworks or Kubescape Controls.
3.1. Kubescape Controls
Kubescape Controls are tests based on best security practices. They offer proactive measures to improve security posture and corrective solutions to contain security breaches.
To run scans with Kubescape Controls, we need the CONTROL_ID of the preferred control:
$ kubescape scan controls [CONTROL_ID] -v
The -v flag prints verbose outputs, and we often use it because when dealing with security, we need as much information as possible.
Typically, after running kubescape scan, the View details column would have a kubescape scan control command with the corresponding CONTROL_ID. However, we can get a list of all Kubescape Controls and their IDs using kubescape list controls:
$ kubescape list controls
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Controls │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ...truncated... │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Control ID : C-0002 │
│ Control Name : Prevent containers from allowing command execution │
│ Docs : https://hub.armosec.io/docs/c-0002 │
│ Frameworks : AllControls, MITRE, NSA, ArmoBest, ClusterScan │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
...truncated...
Once we know the CONTROL_ID, we can scan our cluster using a control. Let’s scan our cluster using control C-0002:
$ kubescape scan control C-0002 -v
...truncated...
################################################################################
ApiVersion: rbac.authorization.k8s.io
Kind: Group
Name: kubeadm:cluster-admins
Controls: 1 (Failed: 1, action required: 0)
┌───────────────────────────────────────────────────────────────────────────┐
│ Resources │
├───────────────────────────────────────────────────────────────────────────┤
│ Severity : Medium │
│ Control Name : Prevent containers from allowing command execution │
│ Docs : https://hub.armosec.io/docs/c-0002 │
│ ...truncated... │
└───────────────────────────────────────────────────────────────────────────┘
...truncated...
┌─────────────────────────────────────────────────────────────────────────┐
│ Controls │
├─────────────────────────────────────────────────────────────────────────┤
│ Severity : Medium │
│ Control Name : Prevent containers from allowing command execution │
│ Failed Resources : 1 │
│ All Resources : 73 │
│ % Compliance-Score : 99% │
├─────────────────────────────────────────────────────────────────────────┤
│ Resource Summary │
│ │
│ Failed Resources : 1 │
│ All Resources : 73 │
│ % Compliance-Score : 98.63% │
└─────────────────────────────────────────────────────────────────────────┘
Control C-0002 checks for RBAC permissions that can allow attackers to execute commands in pods. The output above indicates that the kubeadm:cluster-admins resource failed the test. Why? Well, said resource has permission to execute commands in pods.
For information on a control, we can visit the Docs URL in the Resources table of a kubescape scan control output.
Besides the default controls, we can create our own controls. We can also create custom control configurations even for the default controls. Control configurations are parameters that define the values a control should check for during a scan.
3.2. Scanning With Frameworks
kubescape allows us to scan clusters using standard security frameworks such as the NSA framework and MITRE framework. To scan our cluster against any of these frameworks, we use kubescape scan framework:
$ kubescape scan framework [FRAMEWORK_NAME] -v
Let’s scan our cluster against the NSA framework:
$ kubescape scan framework nsa -v
...truncated...
Framework scanned: NSA
┌─────────────────┬────┐
│ Controls │ 25 │
│ Passed │ 9 │
│ Failed │ 14 │
│ Action Required │ 2 │
└─────────────────┴────┘
Failed resources by severity:
┌──────────┬────┐
│ Critical │ 0 │
│ High │ 3 │
│ Medium │ 11 │
│ Low │ 2 │
└──────────┴────┘
Run with '--verbose'/'-v' to see control failures for each resource.
┌─────────────────────────────────────────────────────────────────────────┐
│ Controls │
├─────────────────────────────────────────────────────────────────────────┤
│ Severity : Critical │
│ Control Name : Disable anonymous access to Kubelet service │
│ Failed Resources : 0 │
│ All Resources : 0 │
│ % Compliance-Score : Action Required * │
├─────────────────────────────────────────────────────────────────────────┤
...truncated...
We can also scan our cluster using all frameworks and controls:
$ kubescape scan framework all
...truncated...
Frameworks scanned: AllControls (compliance score: 86.50), NSA (compliance score: 75.93), MITRE (compliance score: 80.03),
AllControls (compliance score: 86.50), MITRE (compliance score: 80.03), NSA (compliance score: 75.93),
ArmoBest (compliance score: 77.85), DevOpsBest (compliance score: 89.88), SOC2 (compliance score: 83.07),
cis-v1.23-t1.0.1 (compliance score: 49.94)
┌─────────────────┬─────┐
│ Controls │ 190 │
│ Passed │ 85 │
│ Failed │ 54 │
│ Action Required │ 51 │
└─────────────────┴─────┘
Failed resources by severity:
┌──────────┬────┐
│ Critical │ 0 │
│ High │ 16 │
│ Medium │ 42 │
│ Low │ 11 │
└──────────┴────┘
...truncated...
4. Fixing Misconfigurations
kubescape can suggest security fixes for misconfigured manifest files using kubescape fix. To illustrate how this works, we’ll create a simple manifest:
$ cat manifest.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: nginx
image: nginx
To get security recommendations from kubescape fix, we must scan the manifest first and save the output in JSON format:
$ kubescape scan manifest.yaml --format json --output output.json
After that, we’ll run kubescape fix on the JSON output for the suggestions:
$ kubescape fix output.json
ℹ️ Reading report file...
ℹ️ The following changes will be applied:
File: /home/ubuntu/manifest.yaml
Resource: my-app
Kind: Pod
Changes:
1) spec.containers[0].securityContext.runAsNonRoot = true
2) spec.containers[0].securityContext.runAsGroup = 1000
3) spec.containers[0].securityContext.allowPrivilegeEscalation = false
4) spec.containers[0].securityContext.privileged = false
5) spec.containers[0].securityContext.readOnlyRootFilesystem = true
------
Would you like to apply the changes to the files above? [y|n]:
And voila! We have suggestions for improving the security of our manifest. If we are okay with the suggestions, we only need to respond ‘y’ to the prompt, and Kubescape will adjust our manifest file:
$ cat manifest.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: nginx
image: nginx
securityContext:
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1000
runAsNonRoot: true
5. Patching Vulnerable Images
We can patch image vulnerabilities using the kubescape patch command:
$ kubescape patch --image=[IMAGE_NAME:IMAGE_TAG] -v
However, to use kubescape patch we need the BuildKit daemon, so we must install BuildKit first. To install BuildKit, we git clone the repository:
$ git clone https://github.com/moby/buildkit.git
After that, we cd into the directory and run make then make install:
$ cd buildkit && make && sudo make install
With BuildKit installed, we’ll run the BuildKit daemon, buildkitd in the background:
$ sudo buildkitd &
We used sudo in the command because we didn’t install Buildkit in rootless mode. Of course, it may be more ideal to do that in production.
Finally, we’ll run kubescape patch:
$ sudo kubescape patch --image nginx -v
⚠️ Image name has no tag or digest, using latest as tag
✅ Successfully scanned image: docker.io/library/nginx:latest
✅ Patched image successfully. Loaded image: nginx:latest-patched
✅ Successfully re-scanned image: nginx:latest-patched
┌──────────┬────────────────┬───────────────┬─────────────────────────┬──────────┐
│ Severity │ Vulnerability │ Component │ Version │ Fixed in │
├──────────┼────────────────┼───────────────┼─────────────────────────┼──────────┤
│ Critical │ CVE-2023-6879 │ libaom3 │ 3.6.0-1 │ wont-fix │
│ Critical │ CVE-2023-45853 │ zlib1g │ 1:1.2.13.dfsg-1 │ wont-fix │
│ High │ CVE-2023-50387 │ libsystemd0 │ 252.22-1~deb12u1 │ wont-fix │
│ High │ CVE-2023-52356 │ libtiff6 │ 4.5.0-6+deb12u1 │ wont-fix │
│ ...truncated... │
└──────────┴────────────────┴───────────────┴─────────────────────────┴──────────┘
...truncated...
kubescape patch can only resolve OS-level vulnerabilities; it’s ineffective against application vulnerabilities.
6. Conclusion
In this article, we discussed some of Kubescape’s main security features. We discussed the kubescape scan command, which assesses clusters, manifests, and stdin for security and compliance using controls and frameworks.
After that, we looked into the kubescape fix and kubescape patch commands, which provide security improvements to manifests and container images.