DEV Community

Cover image for CIS Benchmark Compliance Across Multiple Kubernetes Clusters
Gianluca
Gianluca

Posted on

CIS Benchmark Compliance Across Multiple Kubernetes Clusters

CIS Kubernetes Benchmarks are a set of security best practices and recommendations developed by the Center for Internet Security (CIS) specifically for Kubernetes environments. These benchmarks provide a comprehensive guide to secure configuration, helping organizations reduce the risk of common vulnerabilities and attacks.

kube-bench is a tool that checks whether Kubernetes is deployed securely by running the checks documented in the CIS Kubernetes Benchmark. Tests are configured with YAML files, making this tool easy to update as test specifications evolve.

kube-bench result

Sveltos is a set of Kubernetes controllers that run in the management cluster. From the management cluster, Sveltos can manage add-ons and applications on a fleet of managed Kubernetes clusters. It is a declarative tool to ensure that the desired state of an application is always reflected in the actual state of the Kubernetes managed clusters.

Sveltos: add-on deployment

This article demonstrates how Sveltos can deploy Kube-bench in each managed cluster, and finally leverage event mechanisms to post-process and collect kube-bench from each managed cluster.

Lab Setup

A Kind cluster is used as management cluster. Then two extra Civo clusters and a GKE cluster all with label env=production.

+------------------------+-------------+-------------------------------------+
|    Cluster Name        |   Version   |             Comments                |
+------------------------+-------------+-------------------------------------+
|    civo/cluster1       | v1.28.7+k3s1| Civo 3 Node - Medium Standard       |
|    civo/cluster2       | v1.29.2+k3s1| Civo 3 Node - Medium Standard       |
|    gke/cluster         | v1.30.3-gke | GKE 3 Node                          |
+------------------------+-------------+-------------------------------------+
Enter fullscreen mode Exit fullscreen mode

Step 1: Install Sveltos on Managament Cluster

For this tutorial, we will install Sveltos in the management cluster. Sveltos installation details can be found here.

kubectl apply -f https://raw.githubusercontent.com/projectsveltos/sveltos/v0.38.3/manifest/manifest.yaml
kubectl apply -f https://raw.githubusercontent.com/projectsveltos/sveltos/v0.38.3/manifest/default-classifier.yaml
Enter fullscreen mode Exit fullscreen mode

Step 2: Register Clusters with Sveltos

Using Civo UI, download the Kubeconfigs, then:

kubectl create ns civo
sveltosctl register cluster --namespace=civo --cluster=cluster1 --kubeconfig=civo-cluster1-kubeconfig --labels=env=production
sveltosctl register cluster --namespace=civo --cluster=cluster2 --kubeconfig=civo-cluster2-kubeconfig --labels=env=production
Enter fullscreen mode Exit fullscreen mode

Using sveltosctl, pointing to the GKE cluster:

sveltosctl generate kubeconfig --create --expirationSeconds=86400 > gke_kubeconfig
sveltosctl register cluster --namespace=gke --cluster=cluster --kubeconfig=gke_kubeconfig --labels=env=production
Enter fullscreen mode Exit fullscreen mode

Verify your Civo and GKE clusters were successfully registered:

kubectl get sveltoscluster -A --show-labels                                                               
NAMESPACE   NAME       READY   VERSION               LABELS
civo        cluster1   true    v1.28.7+k3s1          env=production,projectsveltos.io/k8s-version=v1.28.7,sveltos-agent=present
civo        cluster2   true    v1.29.2+k3s1          env=production,projectsveltos.io/k8s-version=v1.29.2,sveltos-agent=present
gke         cluster    true    v1.30.3-gke.1969001   env=production,projectsveltos.io/k8s-version=v1.30.3,sveltos-agent=present
mgmt        mgmt       true    v1.31.0               projectsveltos.io/k8s-version=v1.31.0,sveltos-agent=present
Enter fullscreen mode Exit fullscreen mode

Step 3: Deploy kube-bench

Sveltos: deploy kube-bench to all production clusters

Sveltos is used to deploy kube-bench in all production clusters:

kubectl apply -f https://raw.githubusercontent.com/projectsveltos/demos/main/cis-scan/kube-bench.yaml
kubectl apply -f https://raw.githubusercontent.com/projectsveltos/demos/main/cis-scan/clusterprofile-deploy-kube-bench.yaml
Enter fullscreen mode Exit fullscreen mode

Above creates a ConfigMap in the management cluster containing kube-bench in its data section. And a ClusterProfile resource that targets all production clusters. The ClusterProfile deploys kube-bench.

Verify all resources are deployed:

sveltosctl show addons
+---------------+---------------+------------+------------+---------+--------------------------------+----------------------------------+
|    CLUSTER    | RESOURCE TYPE | NAMESPACE  |    NAME    | VERSION |              TIME              |             PROFILES             |
+---------------+---------------+------------+------------+---------+--------------------------------+----------------------------------+
| civo/cluster1 | batch:Job     | kube-bench | kube-bench | N/A     | 2024-09-24 14:33:27 +0200 CEST | ClusterProfile/deploy-kube-bench |
| civo/cluster2 | batch:Job     | kube-bench | kube-bench | N/A     | 2024-09-24 14:33:49 +0200 CEST | ClusterProfile/deploy-kube-bench |
| gke/cluster   | batch:Job     | kube-bench | kube-bench | N/A     | 2024-09-24 14:33:37 +0200 CEST | ClusterProfile/deploy-kube-bench |
+---------------+---------------+------------+------------+---------+--------------------------------+-----------
Enter fullscreen mode Exit fullscreen mode

Step 4: Use Event Frameworks to Collect Kube-bench Results

kubectl apply -f https://raw.githubusercontent.com/projectsveltos/demos/main/cis-scan/clusterprofile-deploy-kube-bench.yaml
kubectl apply -f https://raw.githubusercontent.com/projectsveltos/demos/main/cis-scan/events.yaml
Enter fullscreen mode Exit fullscreen mode

Kube-bench results are initially stored in the kube-bench logs. To facilitate analysis and reporting, this process deploys a Job in each managed cluster. This Job post-processes the kube-bench logs, extracting and storing all failure information in a ConfigMap. These ConfigMaps are then automatically collected by Sveltos and sent to the management cluster for centralized review and action.

Sveltos: post-process and collect kube-bench results

Step 5: Use sveltosctl to display all failures

sveltosctl provides a comprehensive overview of issues identified by kube-bench across our managed production clusters.

sveltosctl show resources --kind=configmap 
+---------------+---------------------+------------+---------------------+--------------------------------+
|    CLUSTER    |         GVK         | NAMESPACE  |        NAME         |            MESSAGE             |
+---------------+---------------------+------------+---------------------+--------------------------------+
| civo/cluster1 | /v1, Kind=ConfigMap | kube-bench | kube-bench-failures | [FAIL] 4.1.1 Ensure that       |
|               |                     |            |                     | the kubelet service file       |
|               |                     |            |                     | permissions are set to 600 or  |
|               |                     |            |                     | more restrictive (Automated)   |
|               |                     |            |                     | [FAIL] 4.1.5 Ensure that the   |
|               |                     |            |                     | --kubeconfig kubelet.conf      |
|               |                     |            |                     | file permissions are set       |
|               |                     |            |                     | to 600 or more restrictive     |
|               |                     |            |                     | (Automated) [FAIL] 4.1.6       |
|               |                     |            |                     | Ensure that the --kubeconfig   |
|               |                     |            |                     | kubelet.conf file ownership is |
|               |                     |            |                     | set to root:root (Automated)   |
|               |                     |            |                     | [FAIL] 4.1.9 If the kubelet    |
|               |                     |            |                     | config.yaml configuration      |
|               |                     |            |                     | file is being used validate    |
|               |                     |            |                     | permissions set to 600 or      |
|               |                     |            |                     | more restrictive (Automated)   |
|               |                     |            |                     | [FAIL] 4.1.10 If the kubelet   |
|               |                     |            |                     | config.yaml configuration      |
|               |                     |            |                     | file is being used validate    |
|               |                     |            |                     | file ownership is set          |
|               |                     |            |                     | to root:root (Automated)       |
|               |                     |            |                     | [FAIL] 4.2.1 Ensure that the   |
|               |                     |            |                     | --anonymous-auth argument      |
|               |                     |            |                     | is set to false (Automated)    |
|               |                     |            |                     | [FAIL] 4.2.2 Ensure that       |
|               |                     |            |                     | the --authorization-mode       |
|               |                     |            |                     | argument is not set to         |
|               |                     |            |                     | AlwaysAllow (Automated)        |
|               |                     |            |                     | [FAIL] 4.2.3 Ensure that the   |
|               |                     |            |                     | --client-ca-file argument is   |
|               |                     |            |                     | set as appropriate (Automated) |
|               |                     |            |                     | [FAIL] 4.2.6 Ensure that the   |
|               |                     |            |                     | --make-iptables-util-chains    |
|               |                     |            |                     | argument is set to             |
|               |                     |            |                     | true (Automated) [FAIL]        |
|               |                     |            |                     | 4.2.10 Ensure that the         |
|               |                     |            |                     | --rotate-certificates          |
|               |                     |            |                     | argument is not set to false   |
|               |                     |            |                     | (Automated) [FAIL] 4.3.1       |
|               |                     |            |                     | Ensure that the kube-proxy     |
|               |                     |            |                     | metrics service is bound       |
|               |                     |            |                     | to localhost (Automated)       |
|               |                     |            |                     | [FAIL] 5.1.1 Ensure that       |
|               |                     |            |                     | the cluster-admin role is      |
|               |                     |            |                     | only used where required       |
|               |                     |            |                     | (Automated) [FAIL] 5.1.2       |
|               |                     |            |                     | Minimize access to secrets     |
|               |                     |            |                     | (Automated) [FAIL] 5.1.3       |
|               |                     |            |                     | Minimize wildcard use in Roles |
|               |                     |            |                     | and ClusterRoles (Automated)   |
|               |                     |            |                     | [FAIL] 5.1.4 Minimize access   |
|               |                     |            |                     | to create pods (Automated)     |
|               |                     |            |                     | [FAIL] 5.1.5 Ensure that       |
|               |                     |            |                     | default service accounts are   |
|               |                     |            |                     | not actively used. (Automated) |
|               |                     |            |                     | [FAIL] 5.1.6 Ensure that       |
|               |                     |            |                     | Service Account Tokens are     |
|               |                     |            |                     | only mounted where necessary   |
|               |                     |            |                     | (Automated)                    |
| civo/cluster2 |                     | kube-bench | kube-bench-failures | [FAIL] 4.1.1 Ensure that       |
|               |                     |            |                     | the kubelet service file       |
|               |                     |            |                     | permissions are set to 600 or  |
|               |                     |            |                     | more restrictive (Automated)   |
|               |                     |            |                     | [FAIL] 4.1.5 Ensure that the   |
|               |                     |            |                     | --kubeconfig kubelet.conf      |
|               |                     |            |                     | file permissions are set       |
|               |                     |            |                     | to 600 or more restrictive     |
|               |                     |            |                     | (Automated) [FAIL] 4.1.6       |
|               |                     |            |                     | Ensure that the --kubeconfig   |
|               |                     |            |                     | kubelet.conf file ownership is |
|               |                     |            |                     | set to root:root (Automated)   |
|               |                     |            |                     | [FAIL] 4.1.9 If the kubelet    |
|               |                     |            |                     | config.yaml configuration      |
|               |                     |            |                     | file is being used validate    |
|               |                     |            |                     | permissions set to 600 or      |
|               |                     |            |                     | more restrictive (Automated)   |
|               |                     |            |                     | [FAIL] 4.1.10 If the kubelet   |
|               |                     |            |                     | config.yaml configuration      |
|               |                     |            |                     | file is being used validate    |
|               |                     |            |                     | file ownership is set          |
|               |                     |            |                     | to root:root (Automated)       |
|               |                     |            |                     | [FAIL] 4.2.1 Ensure that the   |
|               |                     |            |                     | --anonymous-auth argument      |
|               |                     |            |                     | is set to false (Automated)    |
|               |                     |            |                     | [FAIL] 4.2.2 Ensure that       |
|               |                     |            |                     | the --authorization-mode       |
|               |                     |            |                     | argument is not set to         |
|               |                     |            |                     | AlwaysAllow (Automated)        |
|               |                     |            |                     | [FAIL] 4.2.3 Ensure that the   |
|               |                     |            |                     | --client-ca-file argument is   |
|               |                     |            |                     | set as appropriate (Automated) |
|               |                     |            |                     | [FAIL] 4.2.6 Ensure that the   |
|               |                     |            |                     | --make-iptables-util-chains    |
|               |                     |            |                     | argument is set to             |
|               |                     |            |                     | true (Automated) [FAIL]        |
|               |                     |            |                     | 4.2.10 Ensure that the         |
|               |                     |            |                     | --rotate-certificates          |
|               |                     |            |                     | argument is not set to false   |
|               |                     |            |                     | (Automated) [FAIL] 4.3.1       |
|               |                     |            |                     | Ensure that the kube-proxy     |
|               |                     |            |                     | metrics service is bound       |
|               |                     |            |                     | to localhost (Automated)       |
|               |                     |            |                     | [FAIL] 5.1.1 Ensure that       |
|               |                     |            |                     | the cluster-admin role is      |
|               |                     |            |                     | only used where required       |
|               |                     |            |                     | (Automated) [FAIL] 5.1.2       |
|               |                     |            |                     | Minimize access to secrets     |
|               |                     |            |                     | (Automated) [FAIL] 5.1.3       |
|               |                     |            |                     | Minimize wildcard use in Roles |
|               |                     |            |                     | and ClusterRoles (Automated)   |
|               |                     |            |                     | [FAIL] 5.1.4 Minimize access   |
|               |                     |            |                     | to create pods (Automated)     |
|               |                     |            |                     | [FAIL] 5.1.5 Ensure that       |
|               |                     |            |                     | default service accounts are   |
|               |                     |            |                     | not actively used. (Automated) |
|               |                     |            |                     | [FAIL] 5.1.6 Ensure that       |
|               |                     |            |                     | Service Account Tokens are     |
|               |                     |            |                     | only mounted where necessary   |
|               |                     |            |                     | (Automated)                    |
| gke/cluster   |                     | kube-bench | kube-bench-failures | [FAIL] 3.2.1 Ensure that the   |
|               |                     |            |                     | --anonymous-auth argument      |
|               |                     |            |                     | is set to false (Automated)    |
|               |                     |            |                     | [FAIL] 3.2.2 Ensure that       |
|               |                     |            |                     | the --authorization-mode       |
|               |                     |            |                     | argument is not set to         |
|               |                     |            |                     | AlwaysAllow (Automated)        |
|               |                     |            |                     | [FAIL] 3.2.3 Ensure that the   |
|               |                     |            |                     | --client-ca-file argument is   |
|               |                     |            |                     | set as appropriate (Automated) |
|               |                     |            |                     | [FAIL] 3.2.6 Ensure that the   |
|               |                     |            |                     | --protect-kernel-defaults      |
|               |                     |            |                     | argument is set to true        |
|               |                     |            |                     | (Manual) [FAIL] 3.2.9 Ensure   |
|               |                     |            |                     | that the --event-qps argument  |
|               |                     |            |                     | is set to 0 or a level which   |
|               |                     |            |                     | ensures appropriate event      |
|               |                     |            |                     | capture (Automated) [FAIL]     |
|               |                     |            |                     | 3.2.12 Ensure that the         |
|               |                     |            |                     | RotateKubeletServerCertificate |
|               |                     |            |                     | argument is set to true        |
|               |                     |            |                     | (Automated)                    |
+---------------+---------------------+------------+---------------------+--------------------------------+
Enter fullscreen mode Exit fullscreen mode

Conclusion

This article has demonstrated how Sveltos can be leveraged to achieve centralized and automated security auditing of Kubernetes clusters using CIS Benchmarks and kube-bench.
By utilizing Sveltos and kube-bench together, organizations can gain a comprehensive overview of the security posture of their Kubernetes clusters and take necessary steps to address any identified vulnerabilities.

Contact Information

If you have some questions, would like to have a friendly chat or just network to not miss any topics, then donโ€™t use the comment function at medium, just feel free to add me to your LinkedIn network!

๐Ÿ‘ Support this project

If you enjoyed this article, please check out the Projectsveltos GitHub repo.

The GitHub repo is a great resource for getting started with the project. It contains the code, documentation, and examples. You can also find the latest news and updates on the project on the GitHub repo.

You can also star ๐ŸŒŸ the project if you found it helpful.

Thank you for reading!

Top comments (0)