Kubernetes specific CIS configurations is a set of recommendations on the Kubernetes services setup and configuration.
With the v1.28 MicroK8s release a cis-hardening
addon is included as part of the core addons.
As described below, this addon reconfigures the cluster nodes to comply with the CIS recommendations v1.24.
On pre-1.28 releases you need to follow the remediation steps described below so as to manually configure MicroK8s according to the CIS recommendations.
CIS-hardening addons usage
The addon is enabled with:
microk8s enable cis-hardening
The addon assumes a default configuration and reconfigures the MicroK8s services to comply with the CIS-1.24 recommendations.
The CIS hardening actions need to be applied to each individual node before it joins a cluster.
To enable the addon through launch configurations during node deployment or at a later stage use the following configuration:
---
version: 0.1.0
addons:
- name: dns
- name: cis-hardening
To remove the CIS hardening process, disable the addon with:
microk8s disable cis-hardening
Unless the --install-kubebench
flag is set to false
, enabling the addon also installs kube-bench
as a plugin along with a revised version of CIS benchmark configurations applicable for MicroK8s. You may want to skip the kube-bench installation in offline deployments. Call kube-bench with:
sudo microk8s kube-bench
All kube-bench
arguments can be passed to the microk8s kube-bench
command. For example to check the results of a single test, 1.2.3:
sudo microk8s kube-bench --check 1.2.3
If you need to run kube-bench
before enabling the addon but also use the CIS benchmark configuration appropriate for MicroK8s you need to install kube-bench manually and point it to the configuration that comes with the addon.
To do so pass the following parameters to kube-bench
:
--version cis-1.24-microk8s
--config /var/snap/microk8s/common/addons/core/addons/cis-hardening/cfg/config.yaml
--config-dir /var/snap/microk8s/common/addons/core/addons/cis-hardening/cfg/
CIS hardening assessment
In this section we review each of the CIS recommendations so that the interested reader (auditors, security teams) can assess the level at which the respective security concerns are addressed. This section also shows how to CIS harden MicroK8s versions
where the cis-hardening
addon is not available for (pre 1.28 releases).
CIS recommendations are in one of the following categories:
- Control Plane Security Configuration, checks 1.x.y
- Etcd Node Configuration, checks 2.x.y. Tailored to dqlite instead of etcd.
- Control Plane Configuration, checks 3.x.y
- Worker Node Security Configuration, checks 4.x.y
- Kubernetes Policies, checks 5.x.y
Each check presented below includes the following information:
- Description of the check
- Remediation to handle the CIS security concerns
- Automated remediation through the
cis-hardening
addon - Audit and expected outcome for the automated tests when applicable
Control Plane Security Configuration
Check 1.1.1
Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)
Remediation
In MicroK8s the control plane is not self-hosted and therefore it does not run in pods. Instead the API server is a
systemd service with its configuration found at /var/snap/microk8s/current/args/kube-apiserver
. The permissions of this
file need to be set to 600 or more restrictive:
chmod 600 /var/snap/microk8s/current/args/kube-apiserver
Remediation by the cis-hardening addon
Yes. Permissions set to 600
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/kube-apiserver; then stat -c permissions=%a /var/snap/microk8s/current/args/kube-apiserver; fi'
Expected output:
permissions=600
Check 1.1.2
Ensure that the API server pod specification file ownership is set to root:root (Automated)
Remediation
In MicroK8s the control plane is not self-hosted and therefore it does not run in pods. Instead the API server is a
systemd service with its configuration found at /var/snap/microk8s/current/args/kube-apiserver
. The configuration file is owned by the
user root
and is editable by users in the microk8s
(or snap_microk8s
) group. To comply with the CIS recommendation:
chown root:root /var/snap/microk8s/current/args/kube-apiserver
Remediation by the cis-hardening addon
Yes. Ownership set to root:root
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/kube-apiserver; then stat -c %U:%G /var/snap/microk8s/current/args/kube-apiserver; fi'
Expected output:
root:root
Check 1.1.3
Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)
Remediation
In MicroK8s the control plane is not self-hosted and therefore it does not run in pods. Instead the controller manager is a
systemd service with its configuration found at /var/snap/microk8s/current/args/kube-controller-manager
. The permissions of this
file need to be set to 600 or more restrictive:
chmod 600 /var/snap/microk8s/current/args/kube-controller-manager
Remediation by the cis-hardening addon
Yes. Permissions set to 600
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/kube-controller-manager; then stat -c permissions=%a /var/snap/microk8s/current/args/kube-controller-manager; fi'
Expected output:
permissions=600
Check 1.1.4
Ensure that the controller manager pod specification file ownership is set to root:root (Automated)
Remediation
In MicroK8s the control plane is not self-hosted and therefore it does not run in pods. Instead the controller manager is a
systemd service with its configuration found at /var/snap/microk8s/current/args/kube-controller-manager
. The configuration file is owned by the
user root
and is editable by users in the microk8s
(or snap_microk8s
) group. To comply with the CIS recommendation:
chown root:root /var/snap/microk8s/current/args/kube-controller-manager
Remediation by the cis-hardening addon
Yes. Ownership set to root:root
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/kube-controller-manager; then stat -c %U:%G /var/snap/microk8s/current/args/kube-controller-manager; fi'
Expected output:
root:root
Check 1.1.5
Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)
Remediation
In MicroK8s the control plane is not self-hosted and therefore it does not run in pods. Instead the scheduler is a
systemd service with its configuration found at /var/snap/microk8s/current/args/kube-scheduler
. The permissions of this
file need to be set to 600 or more restrictive:
chmod 600 /var/snap/microk8s/current/args/kube-scheduler
Remediation by the cis-hardening addon
Yes. Permissions set to 600
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/kube-scheduler; then stat -c permissions=%a /var/snap/microk8s/current/args/kube-scheduler; fi'
Expected output:
permissions=600
Check 1.1.6
Ensure that the scheduler pod specification file ownership is set to root:root (Automated)
Remediation
In MicroK8s the control plane is not self-hosted and therefore it does not run in pods. Instead the controller manager is a
systemd service with its configuration found at /var/snap/microk8s/current/args/kube-scheduler
. The configuration file is owned by the
user root
and is editable by users in the microk8s
(or snap_microk8s
) group. To comply with the CIS recommendation:
chown root:root /var/snap/microk8s/current/args/kube-scheduler
Remediation by the cis-hardening addon
Yes. Ownership set to root:root
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/kube-scheduler; then stat -c %U:%G /var/snap/microk8s/current/args/kube-scheduler; fi'
Expected output:
root:root
Check 1.1.7
Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)
Remediation
Not applicable. MicroK8s does not use etcd as its datastore it uses dqlite.
Dqlite is a systemd service with its configuration found at /var/snap/microk8s/current/args/k8s-dqlite
.
To comply with the spirit of this CIS recommendation:
chmod 600 /var/snap/microk8s/current/args/k8s-dqlite
Remediation by the cis-hardening addon
Yes. Permissions set to 600
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/k8s-dqlite; then stat -c permissions=%a /var/snap/microk8s/current/args/k8s-dqlite; fi'
Expected output:
permissions=600
Check 1.1.8
Ensure that the etcd pod specification file ownership is set to root:root (Automated)
Remediation
Not applicable. MicroK8s does not use etcd as its datastore it uses dqlite.
Dqlite is a systemd service with its configuration found at /var/snap/microk8s/current/args/k8s-dqlite
.
The configuration file is owned by the user root
and is editable by users in the microk8s
(or snap_microk8s
) group.
To comply with the spirit of this CIS recommendation:
chown root:root /var/snap/microk8s/current/args/k8s-dqlite
Remediation by the cis-hardening addon
Yes. Ownership set to root:root
Audit
/bin/sh -c 'if test -e /var/snap/microk8s/current/args/k8s-dqlite; then stat -c %U:%G /var/snap/microk8s/current/args/k8s-dqlite; fi'
Expected output:
root:root
Check 1.1.9
Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)
Remediation
In MicroK8s the CNI configuration files are stored by default under /var/snap/microk8s/current/args/cni-network/
. To comply with the CIS recommendation:
chmod -R 600 /var/snap/microk8s/current/args/cni-network/
Remediation by the cis-hardening addon
Yes. Permission set to 600
Audit
As root:
find /var/snap/microk8s/current/args/cni-network/10-calico.conflist -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a
Expected output:
permissions=600
Check 1.1.10
Ensure that the Container Network Interface file ownership is set to root:root (Manual)
Remediation
In MicroK8s the CNI configuration files are stored by default under /var/snap/microk8s/current/args/cni-network/
. To comply with the CIS recommendation:
chown -R root:root /var/snap/microk8s/current/args/cni-network/
Remediation by the cis-hardening addon
Yes. Ownership set to root:root
Audit
As root:
find /var/snap/microk8s/current/args/cni-network/10-calico.conflist -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G
Expected output:
root:toot
Check 1.1.11
Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)
Remediation
Not applicable. MicroK8s uses dqlite as its datastore.
Dqlite data are kept by default under /var/snap/microk8s/current/var/kubernetes/backend/
.
To comply with the spirit of this CIS recommendation:
chmod -R 700 /var/snap/microk8s/current/var/kubernetes/backend/
Remediation by the cis-hardening addon
Yes. Permission set to 700
Audit
As root:
stat -c permissions=%a /var/snap/microk8s/current/var/kubernetes/backend/
Expected output:
permissions=700
Check 1.1.12
Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)
Remediation
Not applicable. MicroK8s uses dqlite as its datastore owned by root.
Dqlite data are kept by default under /var/snap/microk8s/current/var/kubernetes/backend/
.
To comply with the spirit of this CIS recommendation:
chown -R root:root /var/snap/microk8s/current/var/kubernetes/backend/
Remediation by the cis-hardening addon
Yes. Ownership set to root:root
Audit
As root:
stat -c %U:%G /var/snap/microk8s/current/var/kubernetes/backend/
Expected output:
root:toot
Check 1.1.13
Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)
Remediation
In MicroK8s the administration kubeconfig file is /var/snap/microk8s/current/credentials/client.config
. The permissions of this
file need to be set to 600 or more restrictive:
chmod 600 /var/snap/microk8s/current/credentials/client.config
Remediation by the cis-hardening addon
Yes. Permissions set to 600
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/client.config; then stat -c permissions=%a /var/snap/microk8s/current/credentials/client.config; fi'
Expected output:
permissions=600
Check 1.1.14
Ensure that the admin.conf file ownership is set to root:root (Automated)
Remediation
In MicroK8s the administration kubeconfig file is /var/snap/microk8s/current/credentials/client.config
. The ownership of this
file need to be set to root:root:
chown root:root /var/snap/microk8s/current/credentials/client.config
Remediation by the cis-hardening addon
Yes. Ownership is set to root:root
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/client.config; then stat -c %U:%G /var/snap/microk8s/current/credentials/client.config; fi'
Expected output:
root:root
Check 1.1.15
Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)
Remediation
In MicroK8s the scheduler kubeconfig file is /var/snap/microk8s/current/credentials/scheduler.config
. The permissions of this
file need to be set to 600 or more restrictive:
chmod 600 /var/snap/microk8s/current/credentials/scheduler.config
Remediation by the cis-hardening addon
Yes. Permissions set to 600
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/scheduler.config; then stat -c permissions=%a /var/snap/microk8s/current/credentials/scheduler.config; fi'
Expected output:
permissions=600
Check 1.1.16
Ensure that the scheduler.conf file ownership is set to root:root (Automated)
Remediation
In MicroK8s the scheduler kubeconfig file is /var/snap/microk8s/current/credentials/scheduler.config
. The ownership of this
file need to be set to root:root:
chown root:root /var/snap/microk8s/current/credentials/scheduler.config
Remediation by the cis-hardening addon
Yes. Ownership is set to root:root
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/scheduler.config; then stat -c %U:%G /var/snap/microk8s/current/credentials/scheduler.config; fi'
Expected output:
root:root
Check 1.1.17
Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)
Remediation
In MicroK8s the controller manager kubeconfig file is /var/snap/microk8s/current/credentials/controller.config
. The permissions of this
file need to be set to 600 or more restrictive:
chmod 600 /var/snap/microk8s/current/credentials/controller.config
Remediation by the cis-hardening addon
Yes. Permissions set to 600
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/controller.config; then stat -c permissions=%a /var/snap/microk8s/current/credentials/controller.config; fi'
Expected output:
permissions=600
Check 1.1.18
Ensure that the controller-manager.conf file ownership is set to root:root (Automated)
Remediation
In MicroK8s the controller manager kubeconfig file is /var/snap/microk8s/current/credentials/controller.config
. The ownership of this
file need to be set to root:root:
chown root:root /var/snap/microk8s/current/credentials/controller.config
Remediation by the cis-hardening addon
Yes. Ownership is set to root:root
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/controller.config; then stat -c %U:%G /var/snap/microk8s/current/credentials/controller.config; fi'
Expected output:
root:root
Check 1.1.19
Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)
Remediation
In MicroK8s the certificates are stored under /var/snap/microk8s/current/certs/
. The ownership of this
directory and the included files need to be set to root:root:
chown -R root:root /var/snap/microk8s/current/certs/
Remediation by the cis-hardening addon
Yes. Ownership is set to root:root
Audit
As root:
find /var/snap/microk8s/current/certs/ | xargs stat -c %U:%G
Expected output:
root:root
Check 1.1.20
Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)
Remediation
In MicroK8s the certificates are stored under /var/snap/microk8s/current/certs/
. The permissions of this
directory and the included files need to be set to 600 or more restrictive:
chmod -R 600 /var/snap/microk8s/current/certs/
Remediation by the cis-hardening addon
Yes. Permissions set to 600.
Audit
As root:
find /var/snap/microk8s/current/certs/ -name '*.crt' | xargs stat -c permissions=%a"
Expected output:
permissions=600
Check 1.1.21
Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)
Remediation
In MicroK8s the certificates are stored under /var/snap/microk8s/current/certs/
. The permissions of the keys
included in the directory need to be set to 600 or more restrictive:
chmod -R 600 /var/snap/microk8s/current/certs/
Remediation by the cis-hardening addon
Yes. Permissions set to 600.
Audit
As root:
find /var/snap/microk8s/current/certs/ -name '*.key' | xargs stat -c permissions=%a
Expected output:
permissions=600
Check 1.2.1
Ensure that the
--anonymous-auth
argument is set to false (Manual)
Remediation
In MicroK8s the API server arguments file is /var/snap/microk8s/current/args/kube-apiserver
. Make sure --anonymous-auth
is not present in this file.
Remediation by the cis-hardening addon
Yes.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep anonymous-auth ; echo $?
Expected output:
1
Check 1.2.2
Ensure that the --token-auth-file parameter is not set (Automated)
Remediation
Follow the documentation and configure alternate mechanisms for authentication. Then,
edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and remove the --token-auth-file= parameter. For example,
to switch to x509 certificate authentication as root first create certificates for the admin, kubelet,
kube-proxy, controller manager and kube-scheduler.
mkdir -p /var/tmp/certs
for user in client kubelet scheduler controller proxy; do
openssl genrsa -out /var/tmp/certs/${user}.key 2048
done
# client/admin cert
subject="/CN=admin/O=system:masters"
openssl req -new -sha256 -key /var/tmp/certs/client.key -out /var/tmp/certs/client.csr -subj ${subject}
# kubelet cert
hostname=$(hostname | tr '[:upper:]' '[:lower:]')
echo "subjectAltName=DNS:$hostname" > /var/tmp/certs/kubelet.csr.conf
subject="/CN=system:node:${hostname}/O=system:nodes"
openssl req -new -sha256 -key /var/tmp/certs/kubelet.key -out /var/tmp/certs/kubelet.csr -subj ${subject}
# kube-proxy cert
subject="/CN=system:kube-proxy"
openssl req -new -sha256 -key /var/tmp/certs/proxy.key -out /var/tmp/certs/proxy.csr -subj ${subject}
# kube-scheduler cert
subject="/CN=system:kube-scheduler"
openssl req -new -sha256 -key /var/tmp/certs/scheduler.key -out /var/tmp/certs/scheduler.csr -subj ${subject}
# kube-controller-manager cert
subject="/CN=system:kube-controller-manager"
openssl req -new -sha256 -key /var/tmp/certs/controller.key -out /var/tmp/certs/controller.csr -subj ${subject}
for user in client scheduler controller proxy; do
openssl x509 -req -sha256 -in /var/tmp/certs/${user}.csr -CA /var/snap/microk8s/current/certs/ca.crt -CAkey /var/snap/microk8s/current/certs/ca.key -CAcreateserial -out /var/tmp/certs/${user}.crt -days 3650
done
openssl x509 -req -sha256 -in /var/tmp/certs/kubelet.csr -CA /var/snap/microk8s/current/certs/ca.crt -CAkey /var/snap/microk8s/current/certs/ca.key -CAcreateserial -out /var/tmp/certs/kubelet.crt -days 3650 -extfile /var/tmp/certs/kubelet.csr.conf
Replace the kubeconfig files of the admin, kubelet, kube-proxy, controller manager and kube-scheduler:
create_x509_cert() {
# Create a kubeconfig file with x509 auth
# $1: the name of the config file
# $2: the user to use al login
# $3: path to certificate file
# $4: path to certificate key file
kubeconfig=$1
user=$2
cert=$3
key=$4
ca_data=$(cat /var/snap/microk8s/current/certs/ca.crt | base64 -w 0)
cert_data=$(cat ${cert} | base64 -w 0)
key_data=$(cat ${key} | base64 -w 0)
config_file=/var/snap/microk8s/current/credentials/${kubeconfig}
cp /snap/microk8s/current/client-x509.config.template ${config_file}
sed -i 's/CADATA/'"${ca_data}"'/g' ${config_file}
sed -i 's/NAME/'"${user}"'/g' ${config_file}
sed -i 's/PATHTOCERT/'"${cert_data}"'/g' ${config_file}
sed -i 's/PATHTOKEYCERT/'"${key_data}"'/g' ${config_file}
sed -i 's/client-certificate/client-certificate-data/g' ${config_file}
sed -i 's/client-key/client-key-data/g' ${config_file}
}
create_x509_cert "client.config" "admin" /var/tmp/certs/client.crt /var/tmp/certs/client.key
create_x509_cert "controller.config" "system:kube-controller-manager" /var/tmp/certs/controller.crt /var/tmp/certs/controller.key
create_x509_cert "proxy.config" "system:kube-proxy" /var/tmp/certs/proxy.crt /var/tmp/certs/proxy.key
create_x509_cert "scheduler.config" "system:kube-scheduler" /var/tmp/certs/scheduler.crt /var/tmp/certs/scheduler.key
create_x509_cert "kubelet.config" "system:node:${hostname}" /var/tmp/certs/kubelet.crt /var/tmp/certs/kubelet.key
Update the API server arguments:
sed -i '/--token-auth-file.*/d' /var/snap/microk8s/current/args/kube-apiserver
Restart kubelite
:
systemctl restart snap.microk8s.daemon-kubelite
Remediation by the cis-hardening addon
No. Starting from v1.28 the default MicroK8s setup does not use token based authentication.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep token-auth-file ; echo $?
Expected output:
1
Check 1.2.3
Ensure that the
--DenyServiceExternalIPs
is not set (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and remove the DenyServiceExternalIPs
from enabled admission plugins.
Remediation by the cis-hardening addon
No. The default MicroK8s setup does not enable the DenyServiceExternalIPs
admission plugin.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep DenyServiceExternalIPs ; echo $?
Expected output:
1
Check 1.2.4
Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the two arguments appropriately:
--kubelet-client-certificate=${SNAP_DATA}/certs/server.crt
--kubelet-client-key=${SNAP_DATA}/certs/server.key
Remediation by the cis-hardening addon
No. The default MicroK8s setup sets these arguments.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep kubelet-client-certificate && cat /var/snap/microk8s/current/args/kube-apiserver | grep kubelet-client-key
Expected output:
--kubelet-client-certificate=${SNAP_DATA}/certs/server.crt
--kubelet-client-key=${SNAP_DATA}/certs/server.key
Check 1.2.5
Ensure that the
--kubelet-certificate-authority
argument is set as appropriate (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set:
--kubelet-certificate-authority=${SNAP_DATA}/certs/ca.crt
Remediation by the cis-hardening addon
Yes, --kubelet-certificate-authority
is set.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep kubelet-certificate-authority
Expected output:
--kubelet-certificate-authority=${SNAP_DATA}/certs/ca.crt
Check 1.2.6
Ensure that the
--authorization-mode
argument is not set to AlwaysAllow (Automated)
Remediation
Enable RBAC by calling:
microk8s enable rbac
Remediation by the cis-hardening addon
Yes. The RBAC addon is enabled as part of the CIS hardening.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep -e "authorization-mode.*AlwaysAllow" ; echo $?
Expected output:
1
Check 1.2.7
Ensure that the
--authorization-mode
argument includes Node (Automated)
Remediation
Enable RBAC by calling:
microk8s enable rbac
Remediation by the cis-hardening addon
Yes. The RBAC addon is enabled as part of the CIS hardening.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep -e "authorization-mode.*Node"
Expected output:
--authorization-mode=RBAC,Node
Check 1.2.8
Ensure that the --authorization-mode argument includes RBAC (Automated)
Remediation
Enable RBAC by calling:
microk8s enable rbac
Remediation by the cis-hardening addon
Yes. The RBAC addon is enabled as part of the CIS hardening.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep -e "authorization-mode.*RBAC"
Expected output:
--authorization-mode=RBAC,Node
Check 1.2.9
Ensure that the admission control plugin EventRateLimit is set (Manual)
Remediation
Follow the Kubernetes documentation and set the desired event rate limits in a configuration file. One such example file would be:
apiVersion: eventratelimit.admission.k8s.io/v1alpha1
kind: Configuration
limits:
- type: Namespace
qps: 50
burst: 100
cacheSize: 2000
- type: User
qps: 10
burst: 50
Place this file in /var/snap/microk8s/current/args/
, and name it eventconfig.yaml
.
Create a file to point to the admission configurations:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: EventRateLimit
path: eventconfig.yaml
Place this file in /var/snap/microk8s/current/args/
and name it admission-control-config-file.yaml
.
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
and set the arguments:
--enable-admission-plugins=...,EventRateLimit,...,
--admission-control-config-file=${SNAP_DATA}/args/admission-control-config-file.yaml
Remediation by the cis-hardening addon
Yes. The above remediation is applied.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep EventRateLimit && cat /var/snap/microk8s/current/args/kube-apiserver | grep admission-control-config-file
Expected output:
--enable-admission-plugins=EventRateLimit,AlwaysPullImages,NodeRestriction
--admission-control-config-file=${SNAP_DATA}/args/admission-control-config-file.yaml
Check 1.2.10
Ensure that the admission control plugin AlwaysAdmit is not set (Automated)
Remediation
Follow the Kubernetes documentation and set the --enable-admission-plugins
in /var/snap/microk8s/current/args/kube-apiserver
to a value that does not include AlwaysAdmit
.
Remediation by the cis-hardening addon
Yes. --enable-admission-plugins
is set to EventRateLimit,AlwaysPullImages,NodeRestriction
.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep -e "--enable-admission-plugins.*AlwaysAdmit.*" ; echo $?
Expected output:
1
Check 1.2.11
Ensure that the admission control plugin AlwaysPullImages is set (Manual)
Remediation
Edit ``/var/snap/microk8s/current/args/kube-apiserverto include
AlwaysPullImagesin the
–enable-admission-plugins`.
Remediation by the cis-hardening addon
Yes. --enable-admission-plugins
is set to EventRateLimit,AlwaysPullImages,NodeRestriction
.
Audit
As root:
cat /var/snap/microk8s/current/args/kube-apiserver | grep -e "--enable-admission-plugins.*AlwaysPullImages.*"
Expected output:
--enable-admission-plugins=EventRateLimit,AlwaysPullImages,NodeRestriction
Check 1.2.12
Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)
Remediation
Not applicable. Both PodSecurityPolicy and SecurityContextDeny have been deprecated. See:
Remediation by the cis-hardening addon
No.
Audit
As root:
grep 'SecurityContextDeny\|PodSecurityPolicy' /var/snap/microk8s/current/args/kube-apiserver ; echo $?
Expected output:
1
Check 1.2.13
Ensure that the admission control plugin ServiceAccount is set (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
and ensure that the --disable-admission-plugins
parameter is set to a
value that does not include ServiceAccount.
Remediation by the cis-hardening addon
No. The default MicroK8s setup does not --disable-admission-plugins
.
Audit
As root:
grep -e 'disable-admission-plugins.*ServiceAccount.*' /var/snap/microk8s/current/args/kube-apiserver ; echo $?
Expected output:
1
Check 1.2.14
Ensure that the admission control plugin NamespaceLifecycle is set (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
and ensure that the --disable-admission-plugins
parameter is set to a
value that does not include NamespaceLifecycle.
Remediation by the cis-hardening addon
No. The default MicroK8s setup does not --disable-admission-plugins
.
Audit
As root:
grep -e 'disable-admission-plugins.*NamespaceLifecycle.*' /var/snap/microk8s/current/args/kube-apiserver ; echo $?
Expected output:
1
Check 1.2.15
Ensure that the admission control plugin NodeRestriction is set (Automated)
Remediation
Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the --enable-admission-plugins
parameter to a
value that includes NodeRestriction:
--enable-admission-plugins=...,NodeRestriction,...
Remediation by the cis-hardening addon
Yes. --enable-admission-plugins
is set to EventRateLimit,AlwaysPullImages,NodeRestriction
.
Audit
As root:
grep -e 'enable-admission-plugins.*NodeRestriction.*' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--enable-admission-plugins=EventRateLimit,AlwaysPullImages,NodeRestriction
Check 1.2.16
Ensure that the
--secure-port
argument is not set to 0 (Automated)
Remediation
Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
and either remove the --secure-port
parameter or set it to a different (non-zero) desired port.
Remediation by the cis-hardening addon
No. The default setup sets the --secure-port
parameter to 16443.
Audit
As root:
grep -e 'secure-port' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--secure-port=16443
Check 1.2.17
Ensure that the
--profiling
argument is set to false (Automated)
Remediation
Follow the Kubernetes documentation and configure the below parameter:
--profiling=false
Remediation by the cis-hardening addon
No. The default setup sets this parameter to a proper value.
Audit
As root:
grep -e '--profiling' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--profiling=false
Check 1.2.18
Ensure that the
--audit-log-path
argument is set (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the --audit-log-path
parameter to a suitable path and
file where you would like audit logs to be written, for example:
--audit-log-path=/var/log/apiserver/audit.log
Remediation by the cis-hardening addon
Yes. The --audit-log-path
is set to /var/log/apiserver/audit.log
.
Audit
As root:
grep -e '--audit-log-path' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--audit-log-path=/var/log/apiserver/audit.log
Check 1.2.19
Ensure that the
--audit-log-maxage
argument is set to 30 or as appropriate (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the --audit-log-maxage
parameter to 30
or as an appropriate number of days, for example:
--audit-log-maxage=30
Remediation by the cis-hardening addon
Yes. The --audit-log-maxage
is set to 30.
Audit
As root:
grep -e '--audit-log-maxage' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--audit-log-maxage=30
Check 1.2.20
Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the --audit-log-maxbackup
parameter to 10 or to an appropriate
value, for example:
--audit-log-maxbackup=10
Remediation by the cis-hardening addon
Yes. The --audit-log-maxbackup
is set to 10.
Audit
As root:
grep -e '--audit-log-maxbackup' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--audit-log-maxbackup=10
Check 1.2.21
Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the --audit-log-maxsize argument
parameter to 100 or to an appropriate
value, for example:
--audit-log-maxsize argument=100
Remediation by the cis-hardening addon
Yes. The --audit-log-maxsize
is set to 100.
Audit
As root:
grep -e '--audit-log-maxsize' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--audit-log-maxsize=100
Check 1.2.22
Ensure that the --request-timeout argument is set as appropriate (Manual)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
and set the below parameter as appropriate and if needed, for example:
--request-timeout=300s
Remediation by the cis-hardening addon
Yes. The --request-timeout
is set to 300s.
Audit
As root:
grep -e '--request-timeout' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--request-timeout=300s
Check 1.2.23
Ensure that the --service-account-lookup argument is set to true (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the below parameter.
--service-account-lookup=true
Alternatively, you can delete the --service-account-lookup
parameter from this file so
that the default takes effect.
Remediation by the cis-hardening addon
No. The default setup does not set this parameter.
Audit
As root:
grep -e '--service-account-lookup' /var/snap/microk8s/current/args/kube-apiserver ; echo $?
Expected output:
1
Check 1.2.24
Ensure that the --service-account-key-file argument is set as appropriate (Automated)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the --service-account-key-file parameter
to the public key file for service accounts. For example,
--service-account-key-file=${SNAP_DATA}/certs/serviceaccount.key
Remediation by the cis-hardening addon
No. The default setup sets this parameter properly.
Audit
As root:
grep -e '--service-account-key-file' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--service-account-key-file=${SNAP_DATA}/certs/serviceaccount.key
Check 1.2.25
Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)
Remediation
Not applicable. MicroK8s used dqlite and the communication to this service is done through a
local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379
) accessible
to users with root permissions.
Remediation by the cis-hardening addon
No. Not applicable.
Audit
Not applicable.
Check 1.2.26
Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)
Remediation
Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
Then, edit the API server pod specification file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the TLS certificate and private key file parameters.
--tls-cert-file=${SNAP_DATA}/certs/server.crt
--tls-private-key-file=${SNAP_DATA}/certs/server.key
Remediation by the cis-hardening addon
No. The default setup sets these parameters appropriately.
Audit
As root:
grep -e '--tls-cert-file\|--tls-private-key-file' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--tls-cert-file=${SNAP_DATA}/certs/server.crt
--tls-private-key-file=${SNAP_DATA}/certs/server.key
Check 1.2.27
Ensure that the --client-ca-file argument is set as appropriate (Automated)
Remediation
Follow the Kubernetes documentation and set up the TLS connection on the apiserver.
Then, edit the API server pod specification file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the client certificate authority file:
--client-ca-file=${SNAP_DATA}/certs/ca.crt
Remediation by the cis-hardening addon
No. The default setup sets this parameter appropriately.
Audit
As root:
grep -e '--client-ca-file' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--client-ca-file=${SNAP_DATA}/certs/ca.crt
Check 1.2.28
Ensure that the --etcd-cafile argument is set as appropriate (Automated)
Remediation
Not applicable. MicroK8s used dqlite and the communication to this service is done through a
local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379
) accessible
to users with root permissions.
Remediation by the cis-hardening addon
No. Not applicable.
Audit
Not applicable.
Check 1.2.29
Ensure that the --encryption-provider-config argument is set as appropriate (Manual)
Remediation
Follow the Kubernetes documentation and configure a EncryptionConfig file.
Then, edit the API server pod specification file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the --encryption-provider-config parameter to the path of that file.
For example,
--encryption-provider-config=</path/to/EncryptionConfig/File>
Remediation by the cis-hardening addon
No. This is a warning.
Audit
As root:
grep -e '--encryption-provider-config' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--encryption-provider-config=</path/to/EncryptionConfig/File>
Check 1.2.30
Ensure that encryption providers are appropriately configured (Manual)
Remediation
Follow the Kubernetes documentation and configure a EncryptionConfig file.
In this file, choose aescbc, kms or secretbox as the encryption provider.
Remediation by the cis-hardening addon
No. This is a warning.
Audit
As root:
grep -e 'aescbc\|kms\|secretbox' /path/to/encryption/providers/file ; echo $?
Expected output:
0
Check 1.2.31
Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)
Remediation
Edit the API server arguments file /var/snap/microk8s/current/args/kube-apiserver
on the control plane node and set the below parameter.
--tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384
Remediation by the cis-hardening addon
Yes, Strong Cryptographic Ciphers are configured.
Audit
As root:
grep -e '--tls-cipher-suites' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384
Check 1.3.1
Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-controller-manager
on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,
for example:
--terminated-pod-gc-threshold=10
Remediation by the cis-hardening addon
Yes. The parameter --terminated-pod-gc-threshold=10
is set.
Audit
As root:
grep -e '--terminated-pod-gc-threshold' /var/snap/microk8s/current/args/kube-controller-manager
Expected output:
--terminated-pod-gc-threshold=10
Check 1.3.2
Ensure that the
--profiling
argument is set to false (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-controller-manager
to configure the below parameter:
--profiling=false
Remediation by the cis-hardening addon
No. The default setup sets this parameter to a proper value.
Audit
As root:
grep -e '--profiling' /var/snap/microk8s/current/args/kube-controller-manager
Expected output:
--profiling=false
Check 1.3.3
Ensure that the --use-service-account-credentials argument is set to true (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-controller-manager
and set the below parameter:
--use-service-account-credentials=true
Remediation by the cis-hardening addon
No. The default setup sets this parameter to a proper value.
Audit
As root:
grep -e '--use-service-account-credentials' /var/snap/microk8s/current/args/kube-controller-manager
Expected output:
--use-service-account-credentials
Check 1.3.4
Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-controller-manager
and set the below parameter:
--service-account-private-key-file=${SNAP_DATA}/certs/serviceaccount.key
Remediation by the cis-hardening addon
No. The default setup sets this parameter to a proper value.
Audit
As root:
grep -e '--service-account-private-key-file' /var/snap/microk8s/current/args/kube-controller-manager
Expected output:
--service-account-private-key-file=${SNAP_DATA}/certs/serviceaccount.key
Check 1.3.5
Ensure that the --root-ca-file argument is set as appropriate (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-controller-manager
and set the --root-ca-file parameter to the certificate bundle file:
--root-ca-file=${SNAP_DATA}/certs/ca.crt
Remediation by the cis-hardening addon
No. The default setup sets this parameter to a proper value.
Audit
As root:
grep -e '--root-ca-file' /var/snap/microk8s/current/args/kube-controller-manager
Expected output:
--root-ca-file=${SNAP_DATA}/certs/ca.crt
Check 1.3.6
Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-controller-manager
and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.
--feature-gates=RotateKubeletServerCertificate=true
Remediation by the cis-hardening addon
No. The default setup does not set any feature-gates so the RotateKubeletServerCertificate is enabled by default.
Audit
As root:
grep -e '--feature-gates' /var/snap/microk8s/current/args/kube-controller-manager ; echo $?
Expected output:
1
Check 1.3.7
Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-controller-manager
and ensure the correct value for the --bind-address parameter.
Remediation by the cis-hardening addon
No. The default setup does not set --bind-address it defaults to an appropriate value.
Audit
As root:
grep -e '--bind-address' /var/snap/microk8s/current/args/kube-controller-manager ; echo $?
Expected output:
1
Check 1.4.1
Ensure that the
--profiling
argument is set to false (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-scheduler
to configure the below parameter:
--profiling=false
Remediation by the cis-hardening addon
No. The default setup sets this parameter to a proper value.
Audit
As root:
grep -e '--profiling' /var/snap/microk8s/current/args/kube-scheduler
Expected output:
--profiling=false
Check 1.4.2
Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)
Remediation
Edit the Controller Manager arguments file /var/snap/microk8s/current/args/kube-scheduler
and ensure the correct value for the --bind-address parameter.
Remediation by the cis-hardening addon
No. The default setup does not set --bind-address it defaults to an appropriate value.
Audit
As root:
grep -e '--bind-address' /var/snap/microk8s/current/args/kube-scheduler ; echo $?
Expected output:
1
Etcd Node Configuration, for dqlite
Check 2.1
Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)
Remediation
Not applicable. MicroK8s used dqlite and the communication to this service is done through a
local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379
) accessible
to users with root permissions.
Remediation by the cis-hardening addon
No. Not applicable.
Audit
Not applicable.
Check 2.2
Ensure that the --client-cert-auth argument is set to true (Automated)
Remediation
Not applicable. MicroK8s used dqlite and the communication to this service is done through a
local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379
) accessible
to users with root permissions.
Remediation by the cis-hardening addon
No. Not applicable.
Audit
Not applicable.
Check 2.3
Ensure that the --auto-tls argument is not set to true (Automated)
Remediation
Not applicable. MicroK8s used dqlite and the communication to this service is done through a
local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379
) accessible
to users with root permissions.
Remediation by the cis-hardening addon
No. Not applicable.
Audit
Not applicable.
Check 2.4
Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)
Remediation
MicroK8s used dqlite and tls peer communication uses the certificate pair
/var/snap/microk8s/current/var/kubernetes/backend/cluster.crt
and
/var/snap/microk8s/current/var/kubernetes/backend/cluster.key
.
Remediation by the cis-hardening addon
No. The default configuration enables TLS.
Audit
As root:
if [ -e /var/snap/microk8s/current/var/kubernetes/backend/cluster.crt ] &&
[ -e /var/snap/microk8s/current/var/kubernetes/backend/cluster.key ];
then
echo 'certs-found';
fi
Expected output:
certs-found
Check 2.5
Ensure that the --peer-client-cert-auth argument is set to true (Automated)
Remediation
MicroK8s used dqlite and tls peer communication always uses is TLS unless the --enable-tls
is set to false in
/var/snap/microk8s/current/args/k8s-dqlite
.
Remediation by the cis-hardening addon
No. The default configuration enables TLS.
Audit
As root:
grep enable-tls /var/snap/microk8s/current/args/k8s-dqlite
Expected no output or:
--enable-tls=true
Check 2.6
Ensure that the --peer-auto-tls argument is not set to true (Automated)
Remediation
Not applicable. MicroK8s used dqlite and tls peer communication uses the certificates
created upon the snap creation.
Remediation by the cis-hardening addon
No. Not applicable.
Audit
Not applicable.
Check 2.7
Ensure that a unique Certificate Authority is used for etcd (Manual)
Remediation
Not applicable. MicroK8s used dqlite and tls peer communication uses the certificates
created upon the snap creation.
Remediation by the cis-hardening addon
No. Not applicable.
Audit
Not applicable.
Control Plane Configuration
Check 3.1.1
Client certificate authentication should not be used for users (Manual)
Remediation
Alternative mechanisms provided by Kubernetes such as the use of OIDC should be
implemented in place of client certificates.
Remediation by the cis-hardening addon
No. This is a manual configuration step.
Check 3.2.1
Ensure that a minimal audit policy is created (Manual)
Remediation
Create an audit policy file for your cluster. Here is a minimal one:
# Log all requests at the Metadata level.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
Save this file under /var/snap/microk8s/current/args/audit-policy.yaml
and point to it
in the /var/snap/microk8s/current/args/kube-apiserver
with:
--audit-policy-file=${SNAP_DATA}/args/audit-policy.yaml
Remediation by the cis-hardening addon
Yes, the above minimal policy is applied.
Audit
As root:
grep -e '--audit-policy-file' /var/snap/microk8s/current/args/kube-apiserver
Expected output:
--audit-policy-file=${SNAP_DATA}/args/audit-policy.yaml
Check 3.2.2
Ensure that the audit policy covers key security concerns (Manual)
Remediation
Review the audit policy provided for the cluster and ensure that it covers
at least the following areas,
- Access to Secrets managed by the cluster. Care should be taken to only
log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in
order to avoid risk of logging sensitive data. - Modification of Pod and Deployment objects.
- Use of
pods/exec
,pods/portforward
,pods/proxy
andservices/proxy
.
For most requests, minimally logging at the Metadata level is recommended
(the most basic level of logging).
Remediation by the cis-hardening addon
No, this cannot be automated.
Worker Node Security Configuration
Check 4.1.1
Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)
Remediation
kubelet starts as part of the snap.microk8s.daemon-kubelite.service
systemd service.
Run the below command (based on the file location on your system) on the each worker node.
chmod 600 /etc/systemd/system/snap.microk8s.daemon-kubelite.service
Remediation by the cis-hardening addon
Yes, the addon sets the above permissions when enabled.
Audit
As root:
/bin/sh -c 'if test -e /etc/systemd/system/snap.microk8s.daemon-kubelite.service; then stat -c permissions=%a /etc/systemd/system/snap.microk8s.daemon-kubelite.service; fi'
Expected output:
permissions=600
Check 4.1.2
Ensure that the kubelet service file ownership is set to root:root (Automated)
Remediation
kubelet starts as part of the snap.microk8s.daemon-kubelite.service
systemd service.
Run the below command (based on the file location on your system) on the each worker node.
chown root:root /etc/systemd/system/snap.microk8s.daemon-kubelite.service
Remediation by the cis-hardening addon
Yes, the addon sets the root:root ownership.
Audit
As root:
/bin/sh -c 'if test -e /etc/systemd/system/snap.microk8s.daemon-kubelite.service; then stat -c %U:%G /etc/systemd/system/snap.microk8s.daemon-kubelite.service; fi'
Expected output:
root:root
Check 4.1.3
If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)
Remediation
Run the below command (based on the file location on your system) on the each worker node.
chmod 600 /var/snap/microk8s/current/credentials/proxy.config
Remediation by the cis-hardening addon
Yes, the addon sets the above permissions when enabled.
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/proxy.config; then stat -c permissions=%a /var/snap/microk8s/current/credentials/proxy.config; fi'
Expected output:
permissions=600
Check 4.1.4
If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)
Remediation
Run the below command (based on the file location on your system) on the each worker node.
chown root:root /var/snap/microk8s/current/credentials/proxy.config
Remediation by the cis-hardening addon
Yes, the addon sets the root:root ownership.
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/proxy.config; then stat -c %U:%G /var/snap/microk8s/current/credentials/proxy.config; fi'
Expected output:
root:root
Check 4.1.5
Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)
Remediation
Run the below command (based on the file location on your system) on the each worker node.
chmod 600 /var/snap/microk8s/current/credentials/kubelet.config
Remediation by the cis-hardening addon
Yes, the addon sets the above permissions when enabled.
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/kubelet.config; then stat -c permissions=%a /var/snap/microk8s/current/credentials/kubelet.config; fi'
Expected output:
permissions=600
Check 4.1.6
Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)
Remediation
Run the below command (based on the file location on your system) on the each worker node.
chown root:root /var/snap/microk8s/current/credentials/kubelet.config
Remediation by the cis-hardening addon
Yes, the addon sets the root:root ownership.
Audit
As root:
/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/kubelet.config; then stat -c %U:%G /var/snap/microk8s/current/credentials/kubelet.config; fi'
Expected output:
root:root
Check 4.1.7
Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)
Remediation
Run the following command to modify the file permissions of the --client-ca-file
chmod 600 /var/snap/microk8s/current/certs/ca.crt
Remediation by the cis-hardening addon
Yes, the addon sets the right permissions.
Audit
As root:
stat -c permissions=%a /var/snap/microk8s/current/certs/ca.crt
Expected output:
permissions=600
Check 4.1.8
Ensure that the client certificate authorities file ownership is set to root:root (Manual)
Remediation
Run the following command to modify the ownership of the --client-ca-file
.
chown root:root /var/snap/microk8s/current/certs/ca.crt
Remediation by the cis-hardening addon
Yes, the addon sets the right ownership.
Audit
As root:
stat -c %U:%G /var/snap/microk8s/current/certs/ca.crt
Expected output:
root:root
Check 4.1.9
If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Manual)
Remediation
Not applicable. MicroK8s does not use a config.yaml configuration file.
Check 4.1.10
If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Manual)
Remediation
Not applicable. MicroK8s does not use a config.yaml configuration file.
Check 4.2.1
Ensure that the
--anonymous-auth
argument is set to false (Manual)
Remediation
In MicroK8s the API server arguments file is /var/snap/microk8s/current/args/kubelet
.
Make sure --anonymous-auth
is not present in the file or set to false.
Remediation by the cis-hardening addon
Yes.
Audit
As root:
cat /var/snap/microk8s/current/args/kubelet | grep anonymous-auth
Expected output:
--anonymous-auth=false
Check 4.2.2
Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
set the parameter:
--authorization-mode=Webhook
Review and apply the following RBAC rules so calls from the API server to kubelet are authorized:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:kube-apiserver
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: 127.0.0.1
Remediation by the cis-hardening addon
Yes. The authorization mode is set to webhook.
Audit
As root:
cat /var/snap/microk8s/current/args/kubelet | grep authorization-mode
Expected output:
--authorization-mode=Webhook
Check 4.2.3
Ensure that the --client-ca-file argument is set as appropriate (Automated)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
set the parameter:
--client-ca-file=${SNAP_DATA}/certs/ca.crt
Remediation by the cis-hardening addon
No. The default setup sets this parameter appropriately.
Audit
As root:
grep -e '--client-ca-file' /var/snap/microk8s/current/args/kubelet
Expected output:
--client-ca-file=${SNAP_DATA}/certs/ca.crt
Check 4.2.4
Verify that the --read-only-port argument is set to 0 (Manual)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
set the parameter:
--read-only-port=0
or remove it.
Remediation by the cis-hardening addon
No. The default setup sets this parameter appropriately.
Audit
As root:
grep -e '--read-only-port' /var/snap/microk8s/current/args/kubelet ; echo $?
Expected output:
1
Check 4.2.5
Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
remove the parameter --streaming-connection-idle-timeout
.
Remediation by the cis-hardening addon
No. The default setup sets this parameter appropriately.
Audit
As root:
grep -e '--streaming-connection-idle-timeout' /var/snap/microk8s/current/args/kubelet ; echo $?
Expected output:
1
Check 4.2.6
Ensure that the --protect-kernel-defaults argument is set to true (Automated)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
set the parameter:
--protect-kernel-defaults=true
Mind you may need set in /etc/sysctl.conf
:
vm.panic_on_oom=0
vm.overcommit_memory=1
kernel.panic=10
kernel.panic_on_oops=1
kernel.keys.root_maxkeys=1000000
kernel.keys.root_maxbytes=25000000
Remediation by the cis-hardening addon
Yes. The --protect-kernel-defaults is set to true.
Audit
As root:
cat /var/snap/microk8s/current/args/kubelet | grep --protect-kernel-defaults
Expected output:
--protect-kernel-defaults=true
Check 4.2.7
Ensure that the --make-iptables-util-chains argument is set to true (Automated)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
remove the parameter --make-iptables-util-chains
.
Remediation by the cis-hardening addon
No. By default MicroKs does not set this parameter.
Audit
As root:
cat /var/snap/microk8s/current/args/kubelet | grep --make-iptables-util-chains ; echo $?
Expected output:
1
Check 4.2.8
Ensure that the --hostname-override argument is not set (Manual)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
remove the parameter --hostname-override
.
Remediation by the cis-hardening addon
No. By default MicroKs does not set this parameter.
Audit
As root:
cat /var/snap/microk8s/current/args/kubelet | grep hostname-override ; echo $?
Expected output:
1
Check 4.2.9
Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
set the parameter:
--event-qps=0
Remediation by the cis-hardening addon
Yes, the --event-qps is set to 0.
Audit
As root:
cat /var/snap/microk8s/current/args/kubelet | grep event-qps ; echo $?
Expected output:
--event-qps=0
Check 4.2.10
Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
set the parameters:
--tls-cert-file=${SNAP_DATA}/certs/kubelet.crt
--tls-private-key-file=${SNAP_DATA}/certs/kubelet.key
Remediation by the cis-hardening addon
Yes, both arguments are set to point to the self signed CA created by kubelet.
Audit
As root:
grep -e '--tls-cert-file\|--tls-private-key-file' /var/snap/microk8s/current/args/kubelet
Expected output:
--tls-cert-file=${SNAP_DATA}/certs/kubelet.crt
--tls-private-key-file=${SNAP_DATA}/certs/kubelet.key
Check 4.2.11
Ensure that the --rotate-certificates argument is not set to false (Automated)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
remove the parameter --rotate-certificates
.
Remediation by the cis-hardening addon
No. By default MicroKs does not set this parameter.
Audit
As root:
grep -e '--rotate-certificates' /var/snap/microk8s/current/args/kubelet ; echo $?
Expected output:
1
Check 4.2.12
Verify that the RotateKubeletServerCertificate argument is set to true (Manual)
Remediation
Edit the kubelet service arguments file /var/snap/microk8s/current/args/kubelet
and
remove the feature gate RotateKubeletServerCertificate
as it is set to true by default.
Remediation by the cis-hardening addon
No. By default MicroKs does not set this feature gate to false.
Audit
As root:
grep -e 'RotateKubeletServerCertificate' /var/snap/microk8s/current/args/kubelet ; echo $?
Expected output:
1
Check 4.2.13
Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)
Remediation
Edit the kubelet arguments file /var/snap/microk8s/current/args/kubelet
and set the below parameter.
--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
Remediation by the cis-hardening addon
Yes, Strong Cryptographic Ciphers are configured.
Audit
As root:
grep -e '--tls-cipher-suites' /var/snap/microk8s/current/args/kubelet
Expected output:
--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
Kubernetes Policies
The following CIS policy recommendations cannot be automated and therefore are out of the scope of the cis-hardening
addon.
The cluster administration should take proper action to comply with them whenever possible.
Check 5.1.1
Ensure that the cluster-admin role is only used where required (Manual)
Remediation
Identify all clusterrolebindings to the cluster-admin role. Check if they are used and
if they need this role or if they could use a role with fewer privileges.
Where possible, first bind users to a lower privileged role and then remove the
clusterrolebinding to the cluster-admin role :
kubectl delete clusterrolebinding [name]
Check 5.1.2
Minimize access to secrets (Manual)
Remediation
Where possible, remove get, list and watch access to Secret objects in the cluster.
Check 5.1.3
Minimize wildcard use in Roles and ClusterRoles (Manual)
Remediation
Where possible replace any use of wildcards in clusterroles and roles with specific
objects or actions.
Check 5.1.4
Minimize access to create pods (Manual)
Remediation
Where possible, remove create access to pod objects in the cluster.
Check 5.1.5
Ensure that default service accounts are not actively used. (Manual)
Remediation
Create explicit service accounts wherever a Kubernetes workload requires specific access
to the Kubernetes API server.
Modify the configuration of each default service account to include this value
automountServiceAccountToken: false
Check 5.1.6
Ensure that Service Account Tokens are only mounted where necessary (Manual)
Remediation
Modify the definition of pods and service accounts which do not need to mount service
account tokens to disable it.
Check 5.1.7
Avoid use of system:masters group (Manual)
Remediation
Remove the system:masters
group from all users in the cluster.
Check 5.1.8
Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)
Remediation
Where possible, remove the impersonate, bind and escalate rights from subjects.
Check 5.2.1
Ensure that the cluster has at least one active policy control mechanism in place (Manual)
Remediation
Ensure that either Pod Security Admission or an external policy control system is in place
for every namespace which contains user workloads.
Check 5.2.2
Minimize the admission of privileged containers (Manual)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of privileged containers.
Check 5.2.3
Minimize the admission of containers wishing to share the host process ID namespace (Automated)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of hostPID
containers.
Check 5.2.4
Minimize the admission of containers wishing to share the host IPC namespace (Automated)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of hostIPC
containers.
Check 5.2.5
Minimize the admission of containers wishing to share the host network namespace (Automated)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of hostNetwork
containers.
Check 5.2.6
Minimize the admission of containers with allowPrivilegeEscalation (Automated)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of containers with .spec.allowPrivilegeEscalation
set to true
.
Check 5.2.7
Minimize the admission of root containers (Automated)
Remediation
Create a policy for each namespace in the cluster, ensuring that either MustRunAsNonRoot
or MustRunAs
with the range of UIDs not including 0, is set.
Check 5.2.8
Minimize the admission of containers with the NET_RAW capability (Automated)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of containers with the NET_RAW
capability.
Check 5.2.9
Minimize the admission of containers with added capabilities (Automated)
Remediation
Ensure that allowedCapabilities
is not present in policies for the cluster unless
it is set to an empty array.
Check 5.2.10
Minimize the admission of containers with capabilities assigned (Manual)
Remediation
Review the use of capabilities in applications running on your cluster. Where a namespace
contains applications which do not require any Linux capabilities to operate consider adding
a PSP which forbids the admission of containers which do not drop all capabilities.
Check 5.2.11
Minimize the admission of Windows HostProcess containers (Manual)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of containers that have .securityContext.windowsOptions.hostProcess
set to true
.
Check 5.2.12
Minimize the admission of HostPath volumes (Manual)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of containers with hostPath
volumes.
Check 5.2.13
Minimize the admission of containers which use HostPorts (Manual)
Remediation
Add policies to each namespace in the cluster which has user workloads to restrict the
admission of containers which use hostPort
sections.
Check 5.3.1
Ensure that the CNI in use supports NetworkPolicies (Manual)
Remediation
Follow the documentation and create NetworkPolicy objects as you need them.
The default CNI in MicroK8s is calico that supports network policies.
Check 5.3.2
Ensure that all Namespaces have NetworkPolicies defined (Manual)
Remediation
Follow the documentation and create NetworkPolicy objects as you need them.
Check 5.4.1
Prefer using Secrets as files over Secrets as environment variables (Manual)
Remediation
If possible, rewrite application code to read Secrets from mounted secret files, rather than
from environment variables.
Check 5.4.2
Consider external secret storage (Manual)
Remediation
Refer to the Secrets management options offered by your cloud provider or a third-party
secrets management solution.
Check 5.5.1
Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)
Remediation
Follow the Kubernetes documentation and setup image provenance.
Check 5.7.1
Create administrative boundaries between resources using namespaces (Manual)
Remediation
Follow the documentation and create namespaces for objects in your deployment as you need
them.
Check 5.7.2
Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)
Remediation
Use securityContext
to enable the docker/default seccomp profile in your pod definitions.
For example:
securityContext:
seccompProfile:
type: RuntimeDefault
Check 5.7.3
Apply SecurityContext to your Pods and Containers (Manual)
Remediation
Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a
suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker
Containers.
Check 5.7.4
The default namespace should not be used (Manual)
Remediation
Ensure that namespaces are created to allow for appropriate segregation of Kubernetes
resources and that all new resources are created in a specific namespace.