--- controls: version: "cis-1.6-k3s" id: 5 text: "Kubernetes Policies" type: "policies" groups: - id: 5.1 text: "RBAC and Service Accounts" checks: - id: 5.1.1 text: "Ensure that the cluster-admin role is only used where required (Manual)" type: "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] scored: false - id: 5.1.2 text: "Minimize access to secrets (Manual)" type: "manual" remediation: | Where possible, remove get, list and watch access to secret objects in the cluster. scored: false - id: 5.1.3 text: "Minimize wildcard use in Roles and ClusterRoles (Manual)" type: "manual" remediation: | Where possible replace any use of wildcards in clusterroles and roles with specific objects or actions. kubectl get roles --all-namespaces -o yaml kubectl get clusterroles -o yaml scored: false - id: 5.1.4 text: "Minimize access to create pods (Manual)" type: "manual" remediation: | Where possible, remove create access to pod objects in the cluster. scored: false - id: 5.1.5 text: "Ensure that default service accounts are not actively used. (Manual)" type: "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 scored: false - id: 5.1.6 text: "Ensure that Service Account Tokens are only mounted where necessary (Manual)" type: "manual" remediation: | Modify the definition of pods and service accounts which do not need to mount service account tokens to disable it. scored: false - id: 5.2 text: "Pod Security Policies" checks: - id: 5.2.1 text: "Minimize the admission of privileged containers (Manual)" type: "manual" remediation: | kubectl describe psp | grep MustRunAsNonRoot An operator should apply a PodSecurityPolicy that sets the Rule value to MustRunAsNonRoot. An example of this can be found in the Hardening Guide https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.2 text: "Minimize the admission of containers wishing to share the host process ID namespace (Manual)" type: "manual" remediation: | kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostPID == null) or (.spec.hostPID == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}' An operator should apply a PodSecurityPolicy that sets the hostPID value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.3 text: "Minimize the admission of containers wishing to share the host IPC namespace (Manual)" type: "manual" remediation: | kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostIPC == null) or (.spec.hostIPC == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}' An operator should apply a PodSecurityPolicy that sets the HostIPC value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.4 text: "Minimize the admission of containers wishing to share the host network namespace (Manual)" type: "manual" remediation: | kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostNetwork == null) or (.spec.hostNetwork == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}' An operator should apply a PodSecurityPolicy that sets the HostNetwork value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.5 text: "Minimize the admission of containers with allowPrivilegeEscalation (Manual)" type: "manual" remediation: | kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.allowPrivilegeEscalation == null) or (.spec.allowPrivilegeEscalation == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}' An operator should apply a PodSecurityPolicy that sets the allowPrivilegeEscalation value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.6 text: "Minimize the admission of root containers (Manual)" type: "manual" remediation: | kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.allowPrivilegeEscalation == null) or (.spec.allowPrivilegeEscalation == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}' An operator should apply a PodSecurityPolicy that sets the runAsUser.Rule value to MustRunAsNonRoot. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.7 text: "Minimize the admission of containers with the NET_RAW capability (Manual)" type: "manual" remediation: | kubectl get psp -o json | jq .spec.requiredDropCapabilities[] An operator should apply a PodSecurityPolicy that sets .spec.requiredDropCapabilities[] to a value of All. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.8 text: "Minimize the admission of containers with added capabilities (Manual)" type: "manual" remediation: | kubectl get psp An operator should apply a PodSecurityPolicy that sets allowedCapabilities to anything other than an empty array. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.2.9 text: "Minimize the admission of containers with capabilities assigned (Manual)" type: "manual" remediation: | kubectl get psp An operator should apply a PodSecurityPolicy that sets requiredDropCapabilities to ALL. An example of this can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.3 text: "Network Policies and CNI" checks: - id: 5.3.1 text: "Ensure that the CNI in use supports Network Policies (Manual)" type: "manual" remediation: | By default, K3s use Canal (Calico and Flannel) and fully supports network policies. scored: false - id: 5.3.2 text: "Ensure that all Namespaces have Network Policies defined (Manual)" type: "manual" remediation: | Run the below command on the master node. for i in kube-system kube-public default; do kubectl get networkpolicies -n $i; done Verify that there are network policies applied to each of the namespaces. An operator should apply NetworkPolcyies that prevent unneeded traffic from traversing networks unnecessarily. An example of applying a NetworkPolcy can be found in the Hardening Guide. https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index scored: false - id: 5.4 text: "Secrets Management" checks: - id: 5.4.1 text: "Prefer using secrets as files over secrets as environment variables (Manual)" type: "manual" remediation: | Run the following command to find references to objects which use environment variables defined from secrets. kubectl get all -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind} {.metadata.name} {"\n"}{end}' -A if possible, rewrite application code to read secrets from mounted secret files, rather than from environment variables. scored: false - id: 5.4.2 text: "Consider external secret storage (Manual)" type: "manual" remediation: | Refer to the secrets management options offered by your cloud provider or a third-party secrets management solution. scored: false - id: 5.5 text: "Extensible Admission Control" checks: - id: 5.5.1 text: "Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)" type: "manual" remediation: | Follow the Kubernetes documentation and setup image provenance. scored: false - id: 5.7 text: "General Policies" checks: - id: 5.7.1 text: "Create administrative boundaries between resources using namespaces (Manual)" audit: kubectl get namespaces type: "manual" remediation: | Ensure that these namespaces are the ones you need and are adequately administered as per your requirements. Follow the documentation and create namespaces for objects in your deployment as you need them. scored: false - id: 5.7.2 text: "Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)" type: "manual" remediation: | Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you would need to enable alpha features in the apiserver by passing "--feature- gates=AllAlpha=true" argument. Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS parameter to "--feature-gates=AllAlpha=true" KUBE_API_ARGS="--feature-gates=AllAlpha=true" Based on your system, restart the kube-apiserver service. For example: systemctl restart kube-apiserver.service Use annotations to enable the docker/default seccomp profile in your pod definitions. An example is as below: apiVersion: v1 kind: Pod metadata: name: trustworthy-pod annotations: seccomp.security.alpha.kubernetes.io/pod: docker/default spec: containers: - name: trustworthy-container image: sotrustworthy:latest scored: false - id: 5.7.3 text: "Apply Security Context to Your Pods and Containers (Manual)" type: "manual" remediation: | Follow the Kubernetes documentation and apply security contexts to your pods. For a suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker Containers. scored: false - id: 5.7.4 text: "The default namespace should not be used (Manual)" type: "manual" remediation: | Run the below command on the master node. kubectl get all -n default The only entries there should be system-managed resources such as the kubernetes service. Ensure that namespaces are created to allow for appropriate segregation of Kubernetes resources and that all new resources are created in a specific namespace. scored: false