From 00612a7b7ebab56687d48944095c3fa3163e3fae Mon Sep 17 00:00:00 2001 From: eaudetcobello <155978570+eaudetcobello@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:02:49 -0400 Subject: [PATCH] Add YAML to Markdown conversion script and generated Markdown files (#497) --- docs/src/_parts/cis/controlplane.md | 59 + docs/src/_parts/cis/etcd.md | 188 +++ docs/src/_parts/cis/master.md | 1557 +++++++++++++++++++++++++ docs/src/_parts/cis/node.md | 631 ++++++++++ docs/src/_parts/cis/policies.md | 345 ++++++ k8s/scripts/cis/README.md | 51 + k8s/scripts/cis/cis-template.jinja2 | 38 + k8s/scripts/cis/cis-yaml-to-md.py | 150 +++ k8s/scripts/cis/expected-outputs.yaml | 89 ++ k8s/scripts/cis/requirements.txt | 2 + 10 files changed, 3110 insertions(+) create mode 100644 docs/src/_parts/cis/controlplane.md create mode 100644 docs/src/_parts/cis/etcd.md create mode 100644 docs/src/_parts/cis/master.md create mode 100644 docs/src/_parts/cis/node.md create mode 100644 docs/src/_parts/cis/policies.md create mode 100644 k8s/scripts/cis/README.md create mode 100644 k8s/scripts/cis/cis-template.jinja2 create mode 100644 k8s/scripts/cis/cis-yaml-to-md.py create mode 100644 k8s/scripts/cis/expected-outputs.yaml create mode 100644 k8s/scripts/cis/requirements.txt diff --git a/docs/src/_parts/cis/controlplane.md b/docs/src/_parts/cis/controlplane.md new file mode 100644 index 000000000..f543d9950 --- /dev/null +++ b/docs/src/_parts/cis/controlplane.md @@ -0,0 +1,59 @@ +## Control Plane Configuration + +### Authentication and Authorization + +#### Control 3.1.1 + +Description: 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. + +### Logging + +#### Control 3.2.1 + +Description: Ensure that a minimal audit policy is created (Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--audit-policy-file=/var/snap/k8s/common/etc/audit-policy.yaml +``` + +Remediation: + +Create an audit policy file for your cluster. + +#### Control 3.2.2 + +Description: 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` and +`services/proxy`. +For most requests, minimally logging at the Metadata level is +recommended +(the most basic level of logging). + diff --git a/docs/src/_parts/cis/etcd.md b/docs/src/_parts/cis/etcd.md new file mode 100644 index 000000000..4bda0ed52 --- /dev/null +++ b/docs/src/_parts/cis/etcd.md @@ -0,0 +1,188 @@ +## Etcd Node Configuration + +### Etcd Node Configuration + +#### Control 2.1 + +Description: Ensure that the ETCD_CERT_FILE and ETCD_KEY_FILE environment +variables are set as appropriate (Automated) + +Audit: + +``` +cat /proc/$(pidof /usr/bin/etcd)/environ +``` + +Expected output: + +``` +ETCD_CERT_FILE and ETCD_KEY_FILE are set +``` + +Remediation: + +Follow the etcd service documentation and configure TLS +encryption. +Then, edit the etcd daemon configuration file /etc/default/etcd +on the master node and set the following variables. + +``` +ETCD_CERT_FILE= +ETCD_KEY_FILE= +``` + +#### Control 2.2 + +Description: Ensure that the ETCD_CLIENT_CERT_AUTH variable is set to true +(Automated) + +Audit: + +``` +cat /proc/$(pidof /usr/bin/etcd)/environ +``` + +Expected output: + +``` +ETCD_CLIENT_CERT_AUTH is set to true +``` + +Remediation: + +Edit the etcd daemon configuration file /etc/default/etcd on the master +node and set the following variable. + +`ETCD_CLIENT_CERT_AUTH=true` + +#### Control 2.3 + +Description: Ensure that the ETCD_AUTO_TLS argument is not set to true +(Automated) + +Audit: + +``` +cat /proc/$(pidof /usr/bin/etcd)/environ +``` + +Expected output: + +``` +ETCD_AUTO_TLS is not set +``` + +Remediation: + +Edit the etcd daemon configuration file /etc/default/etcd on the master +node and either remove the ETCD_AUTO_TLS variable or set it to +false. + +`ETCD_AUTO_TLS=false` + +#### Control 2.4 + +Description: Ensure that the ETCD_PEER_CERT_FILE and ETCD_PEER_KEY_FILE +variables are set as appropriate (Automated) + +Audit: + +``` +cat /proc/$(pidof /usr/bin/etcd)/environ +``` + +Expected output: + +``` +ETCD_PEER_CERT_FILE and ETCD_PEER_KEY_FILE are set +``` + +Remediation: + +Follow the etcd service documentation and configure peer TLS +encryption as appropriate +for your etcd cluster. +Then, edit the etcd daemon configuration file /etc/default/etcd on the +master node and set the following variables. + +``` +ETCD_PEER_CERT_FILE= +ETCD_PEER_KEY_FILE= +``` + +#### Control 2.5 + +Description: Ensure that the ETCD_PEER_CLIENT_CERT_AUTH variable is set to +true (Automated) + +Audit: + +``` +cat /proc/$(pidof /usr/bin/etcd)/environ +``` + +Expected output: + +``` +ETCD_PEER_CLIENT_CERT_AUTH is set to true +``` + +Remediation: + +Edit the etcd daemon configuration file /etc/default/etcd on the master +node and set the following argument. + +`ETCD_PEER_CLIENT_CERT_AUTH=true` + +#### Control 2.6 + +Description: Ensure that the ETCD_PEER_AUTO_TLS argument is not set to true +(Automated) + +Audit: + +``` +cat /proc/$(pidof /usr/bin/etcd)/environ +``` + +Expected output: + +``` +ETCD_PEER_AUTO_TLS is not set +``` + +Remediation: + +Edit the etcd daemon configuration file /etc/default/etcd on the master +node and either remove the ETCD_PEER_AUTO_TLS parameter or set +it to false. + +`ETCD_PEER_AUTO_TLS=false` + +#### Control 2.7 + +Description: Ensure that a unique Certificate Authority is used for etcd +(Manual) + +Audit: + +``` +cat /proc/$(pidof /usr/bin/etcd)/environ +``` + +Expected output: + +``` +ETCD_TRUSTED_CA_FILE is set +``` + +Remediation: + +Follow the etcd documentation and create a dedicated certificate +authority setup for the +etcd service. +Then, edit the etcd daemon configuration file /etc/default/etcd on the +master node and set the following argument. + +`ETCD_TRUSTED_CA_FILE=` + diff --git a/docs/src/_parts/cis/master.md b/docs/src/_parts/cis/master.md new file mode 100644 index 000000000..aa57201ab --- /dev/null +++ b/docs/src/_parts/cis/master.md @@ -0,0 +1,1557 @@ +## Control Plane Security Configuration + +### Control Plane Node Configuration Files + +#### Control 1.1.1 + +Description: Ensure that the API server configuration file permissions are +set to 600 or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kube-apiserver; then stat -c permissions=%a /var/snap/k8s/common/args/kube-apiserver; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 600 /var/snap/k8s/common/args/kube-apiserver` + +#### Control 1.1.2 + +Description: Ensure that the API server configuration file ownership is set +to root:root (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kube-apiserver; then stat -c %U:%G /var/snap/k8s/common/args/kube-apiserver; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root /var/snap/k8s/common/args/kube-apiserver` + +#### Control 1.1.3 + +Description: Ensure that the controller manager configuration file +permissions are set to 600 or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kube-controller-manager; then stat -c permissions=%a /var/snap/k8s/common/args/kube-controller-manager; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 600 /var/snap/k8s/common/args/kube-controller-manager` + +#### Control 1.1.4 + +Description: Ensure that the controller manager configuration file ownership +is set to root:root (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kube-controller-manager; then stat -c %U:%G /var/snap/k8s/common/args/kube-controller-manager; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root /var/snap/k8s/common/args/kube-controller-manager` + +#### Control 1.1.5 + +Description: Ensure that the scheduler configuration file permissions are set +to 600 or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kube-scheduler; then stat -c permissions=%a /var/snap/k8s/common/args/kube-scheduler; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 600 /var/snap/k8s/common/args/kube-scheduler` + +#### Control 1.1.6 + +Description: Ensure that the scheduler configuration file ownership is set to +root:root (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kube-scheduler; then stat -c %U:%G /var/snap/k8s/common/args/kube-scheduler; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root /var/snap/k8s/common/args/kube-scheduler` + +#### Control 1.1.7 + +Description: Ensure that the etcd configuration file permissions are set to +644 or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/default/etcd; then find /etc/default/etcd -name '*etcd*' | xargs stat -c permissions=%a; fi' +``` + +Expected output: + +``` +permissions=644 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 644 /etc/default/etcd` + +#### Control 1.1.8 + +Description: Ensure that the etcd configuration file ownership is set to +root:root (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/default/etcd; then find /etc/default/etcd -name '*etcd*' | xargs stat -c %U:%G; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root /etc/default/etcd` + +#### Control 1.1.9 + +Description: Ensure that the Container Network Interface file permissions are +set to 600 or more restrictive (Manual) + +Audit: + +``` +ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a +find /etc/cni/net.d/10-calico.conflist -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a +``` + +Expected output: + +``` +permissions=644 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 644 ` + +#### Control 1.1.10 + +Description: Ensure that the Container Network Interface file ownership is +set to root:root (Manual) + +Audit: + +``` +ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G +find /etc/cni/net.d/10-calico.conflist -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root ` + +#### Control 1.1.11 + +Description: Ensure that the etcd data directory permissions are set to 700 +or more restrictive (Automated) + +Audit: + +``` +DATA_DIR='/var/lib/etcd' +stat -c permissions=%a "$DATA_DIR" +``` + +Expected output: + +``` +permissions=700 +``` + +Remediation: + +On the etcd server node, get the etcd data directory, passed as +an argument --data-dir, +from the command 'ps -ef | grep etcd'. + +`chmod 700 /var/lib/etcd` + +#### Control 1.1.12 + +Description: Ensure that the etcd data directory ownership is set to +etcd:etcd (Automated) + +Audit: + +``` +DATA_DIR='/var/lib/etcd' +stat -c %U:%G "$DATA_DIR" +``` + +Expected output: + +``` +etcd:etcd +``` + +Remediation: + +On the etcd server node, get the etcd data directory, passed as +an argument --data-dir, +from the command 'ps -ef | grep etcd'. + +`chown root:root /var/lib/etcd` + +#### Control 1.1.13 + +Description: Ensure that the admin.conf file permissions are set to 600 or +more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 600 /etc/kubernetes/admin.conf` + +#### Control 1.1.14 + +Description: Ensure that the admin.conf file ownership is set to root:root +(Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root /etc/kubernetes/admin.conf` + +#### Control 1.1.15 + +Description: Ensure that the scheduler.conf file permissions are set to 600 +or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/scheduler.conf; then stat -c permissions=%a /etc/kubernetes/scheduler.conf; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 600 /etc/kubernetes/scheduler.conf` + +#### Control 1.1.16 + +Description: Ensure that the scheduler.conf file ownership is set to +root:root (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/scheduler.conf; then stat -c %U:%G /etc/kubernetes/scheduler.conf; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root /etc/kubernetes/scheduler.conf` + +#### Control 1.1.17 + +Description: Ensure that the controller-manager.conf file permissions are set +to 600 or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/controller.conf; then stat -c permissions=%a /etc/kubernetes/controller.conf; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod 600 /etc/kubernetes/controller.conf` + +#### Control 1.1.18 + +Description: Ensure that the controller-manager.conf file ownership is set to +root:root (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/controller.conf; then stat -c %U:%G /etc/kubernetes/controller.conf; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown root:root /etc/kubernetes/controller.conf` + +#### Control 1.1.19 + +Description: Ensure that the Kubernetes PKI directory and file ownership is +set to root:root (Automated) + +Audit: + +``` +find /etc/kubernetes/pki/ | xargs stat -c %U:%G +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the control plane node. + +`chown -R root:root /etc/kubernetes/pki/` + +#### Control 1.1.20 + +Description: Ensure that the Kubernetes PKI certificate file permissions are +set to 600 or more restrictive (Manual) + +Audit: + +``` +find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod -R 600 /etc/kubernetes/pki/*.crt` + +#### Control 1.1.21 + +Description: Ensure that the Kubernetes PKI key file permissions are set to +600 (Manual) + +Audit: + +``` +find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the control plane node. + +`chmod -R 600 /etc/kubernetes/pki/*.key` + +### API Server + +#### Control 1.2.1 + +Description: Ensure that the --anonymous-auth argument is set to false +(Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--anonymous-auth=false +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the following argument. + +`--anonymous-auth=false` + +#### Control 1.2.2 + +Description: Ensure that the --token-auth-file parameter is not set +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--token-auth-file is not set +``` + +Remediation: + +Follow the documentation and configure alternate mechanisms for +authentication. Then, +edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and remove the --token-auth- +file= argument. + +#### Control 1.2.3 + +Description: Ensure that the --DenyServiceExternalIPs is not set (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--enable-admission-plugins does not contain +DenyServiceExternalIPs +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and remove the +`DenyServiceExternalIPs` +from enabled admission plugins. + +#### Control 1.2.4 + +Description: Ensure that the --kubelet-client-certificate and --kubelet- +client-key arguments are set as appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--kubelet-client-certificate=/etc/kubernetes/pki/apiserver- +kubelet-client.crt and --kubelet-client- +key=/etc/kubernetes/pki/apiserver-kubelet-client.key +``` + +Remediation: + +Follow the Kubernetes documentation and set up the TLS +connection between the +apiserver and kubelets. Then, edit API server configuration file +/var/snap/k8s/common/args/kube-apiserver on the control plane node and set the +kubelet client certificate and key parameters as follows. + +``` +--kubelet-client-certificate= +--kubelet-client-key= +``` + +#### Control 1.2.5 + +Description: Ensure that the --kubelet-certificate-authority argument is set +as appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--kubelet-certificate-authority=/etc/kubernetes/pki/ca.crt +``` + +Remediation: + +Follow the Kubernetes documentation and setup the TLS connection +between +the apiserver and kubelets. Then, edit the API server +configuration file +/var/snap/k8s/common/args/kube-apiserver on the control plane node and set the +--kubelet-certificate-authority parameter to the path to the +cert file for the certificate authority. + +`--kubelet-certificate-authority=` + +#### Control 1.2.6 + +Description: Ensure that the --authorization-mode argument is not set to +AlwaysAllow (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--authorization-mode=Node,RBAC +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --authorization-mode +parameter to values other than AlwaysAllow. +One such example could be as follows. + +`--authorization-mode=Node,RBAC` + +#### Control 1.2.7 + +Description: Ensure that the --authorization-mode argument includes Node +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--authorization-mode=Node,RBAC +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --authorization-mode +parameter to a value that includes Node. + +`--authorization-mode=Node,RBAC` + +#### Control 1.2.8 + +Description: Ensure that the --authorization-mode argument includes RBAC +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--authorization-mode=Node,RBAC +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --authorization-mode +parameter to a value that includes RBAC, + +`--authorization-mode=Node,RBAC` + +#### Control 1.2.9 + +Description: Ensure that the admission control plugin EventRateLimit is set +(Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--enable-admission- +plugins=NodeRestriction,EventRateLimit,AlwaysPullImages +``` + +Remediation: + +Follow the Kubernetes documentation and set the desired limits +in a configuration file. +Then, edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +and set the following arguments. + +``` +--enable-admission-plugins=...,EventRateLimit,... +--admission-control-config-file= +``` + +#### Control 1.2.10 + +Description: Ensure that the admission control plugin AlwaysAdmit is not set +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--enable-admission- +plugins=NodeRestriction,EventRateLimit,AlwaysPullImages +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and either remove the --enable- +admission-plugins parameter, or set it to a +value that does not include AlwaysAdmit. + +#### Control 1.2.11 + +Description: Ensure that the admission control plugin AlwaysPullImages is set +(Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--enable-admission- +plugins=NodeRestriction,EventRateLimit,AlwaysPullImages +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --enable-admission-plugins +parameter to include +AlwaysPullImages. + +`--enable-admission-plugins=...,AlwaysPullImages,...` + +#### Control 1.2.12 + +Description: Ensure that the admission control plugin SecurityContextDeny is +set if PodSecurityPolicy is not used (Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--enable-admission- +plugins=NodeRestriction,EventRateLimit,AlwaysPullImages +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --enable-admission-plugins +parameter to include +SecurityContextDeny, unless PodSecurityPolicy is already in +place. + +`--enable-admission-plugins=...,SecurityContextDeny,...` + +#### Control 1.2.13 + +Description: Ensure that the admission control plugin ServiceAccount is set +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--disable-admission-plugins is not set +``` + +Remediation: + +Follow the documentation and create ServiceAccount objects as +per your environment. +Then, edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and ensure that the --disable- +admission-plugins parameter is set to a +value that does not include ServiceAccount. + +#### Control 1.2.14 + +Description: Ensure that the admission control plugin NamespaceLifecycle is +set (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--disable-admission-plugins is not set +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --disable-admission- +plugins parameter to +ensure it does not include NamespaceLifecycle. + +#### Control 1.2.15 + +Description: Ensure that the admission control plugin NodeRestriction is set +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--enable-admission- +plugins=NodeRestriction,EventRateLimit,AlwaysPullImages +``` + +Remediation: + +Follow the Kubernetes documentation and configure +NodeRestriction plug-in on kubelets. +Then, edit the API server configuration file /var/snap/k8s/common/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,...` + +#### Control 1.2.16 + +Description: Ensure that the --secure-port argument is not set to 0 +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--secure-port=6443 +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and either remove the --secure-port +parameter or +set it to a different (non-zero) desired port. + +#### Control 1.2.17 + +Description: Ensure that the --profiling argument is set to false (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--profiling=false +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the following argument. + +`--profiling=false` + +#### Control 1.2.18 + +Description: Ensure that the --audit-log-path argument is set (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--audit-log-path=/var/log/apiserver/audit.log +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/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. + +`--audit-log-path=/var/log/apiserver/audit.log` + +#### Control 1.2.19 + +Description: Ensure that the --audit-log-maxage argument is set to 30 or as +appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--audit-log-maxage=30 +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --audit-log-maxage +parameter to 30 +or as an appropriate number of days. + +`--audit-log-maxage=30` + +#### Control 1.2.20 + +Description: Ensure that the --audit-log-maxbackup argument is set to 10 or +as appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--audit-log-maxbackup=10 +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --audit-log-maxbackup +parameter to 10 or to an appropriate +value. + +`--audit-log-maxbackup=10` + +#### Control 1.2.21 + +Description: Ensure that the --audit-log-maxsize argument is set to 100 or as +appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--audit-log-maxsize=100 +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --audit-log-maxsize +parameter to an appropriate size in MB. + +`--audit-log-maxsize=100` + +#### Control 1.2.22 + +Description: Ensure that the --request-timeout argument is set as appropriate +(Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--request-timeout=300s +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +and set the following argument as appropriate and if needed. + +`--request-timeout=300s` + +#### Control 1.2.23 + +Description: Ensure that the --service-account-lookup argument is set to true +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--service-account-lookup is not set +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the following argument. + +`--service-account-lookup=true` + +Alternatively, you can delete the --service-account-lookup +argument from this file so +that the default takes effect. + +#### Control 1.2.24 + +Description: Ensure that the --service-account-key-file argument is set as +appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--service-account-key- +file=/etc/kubernetes/pki/serviceaccount.key +``` + +Remediation: + +Edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --service-account-key-file +parameter +to the public key file for service accounts. + +`--service-account-key-file=` + +#### Control 1.2.25 + +Description: Ensure that the --etcd-certfile and --etcd-keyfile arguments are +set as appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--etcd-certfile=/etc/kubernetes/pki/etcd/client.crt and --etcd- +keyfile=/etc/kubernetes/pki/etcd/client.key +``` + +Remediation: + +Follow the Kubernetes documentation and set up the TLS +connection between the apiserver and etcd. +Then, edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the etcd certificate and key +file parameters. + +``` +--etcd-certfile= +--etcd-keyfile= +``` + +#### Control 1.2.26 + +Description: Ensure that the --tls-cert-file and --tls-private-key-file +arguments are set as appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--tls-cert-file=/etc/kubernetes/pki/apiserver.crt and --tls- +private-key-file=/etc/kubernetes/pki/apiserver.key +``` + +Remediation: + +Follow the Kubernetes documentation and set up the TLS +connection on the apiserver. +Then, edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the TLS certificate and +private key file parameters. + +``` +--tls-cert-file= +--tls-private-key-file= +``` + +#### Control 1.2.27 + +Description: Ensure that the --client-ca-file argument is set as appropriate +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--client-ca-file=/etc/kubernetes/pki/client-ca.crt +``` + +Remediation: + +Follow the Kubernetes documentation and set up the TLS +connection on the apiserver. +Then, edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the client certificate +authority file. + +`--client-ca-file=` + +#### Control 1.2.28 + +Description: Ensure that the --etcd-cafile argument is set as appropriate +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt +``` + +Remediation: + +Follow the Kubernetes documentation and set up the TLS +connection between the apiserver and etcd. +Then, edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the etcd certificate authority +file parameter. + +`--etcd-cafile=` + +#### Control 1.2.29 + +Description: Ensure that the --encryption-provider-config argument is set as +appropriate (Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--encryption-provider-config is set +``` + +Remediation: + +Follow the Kubernetes documentation and configure a +EncryptionConfig file. +Then, edit the API server configuration file /var/snap/k8s/common/args/kube-apiserver +on the control plane node and set the --encryption-provider- +config parameter to the path of that file. + +`--encryption-provider-config=` + +#### Control 1.2.30 + +Description: Ensure that encryption providers are appropriately configured +(Manual) + +Audit: + +``` +ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep kube-apiserver | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\([^ ]*\).*%\1%') +if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o "[A-Za-z]*" | sed 's/^/provider=/'; fi +``` + +Expected output: + +``` +--encryption-provider-config is one of or all of +aescbc,kms,secretbox +``` + +Remediation: + +Follow the Kubernetes documentation and configure a +EncryptionConfig file. +In this file, choose aescbc, kms or secretbox as the encryption +provider. + +#### Control 1.2.31 + +Description: Ensure that the API Server only makes use of Strong +Cryptographic Ciphers (Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-apiserver | grep -v grep +``` + +Expected output: + +``` +--tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA38 +4,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_ECD +HE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_PO +LY1305_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_E +CDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA +384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHAC +HA20_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: + +Edit the API server configuration file +/etc/kubernetes/manifests/kube-apiserver.yaml +on the control plane node and set the following argument. + +``` +--tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA38 +4,TLS_CHACHA20_POLY1305_SHA256, +TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_12 +8_GCM_SHA256, +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_25 +6_GCM_SHA384, +TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHAC +HA20_POLY1305_SHA256, +TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_C +BC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, +TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GC +M_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, +TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_ED +E_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 +``` + +### Controller Manager + +#### Control 1.3.1 + +Description: Ensure that the --terminated-pod-gc-threshold argument is set as +appropriate (Manual) + +Audit: + +``` +/bin/ps -ef | grep kube-controller-manager | grep -v grep +``` + +Expected output: + +``` +--terminated-pod-gc-threshold=12500 +``` + +Remediation: + +Edit the Controller Manager configuration file +/var/snap/k8s/common/args/kube-controller-manager +on the control plane node and set the --terminated-pod-gc- +threshold to an appropriate threshold. + +`--terminated-pod-gc-threshold=10` + +#### Control 1.3.2 + +Description: Ensure that the --profiling argument is set to false (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-controller-manager | grep -v grep +``` + +Expected output: + +``` +--profiling=false +``` + +Remediation: + +Edit the Controller Manager configuration file +/var/snap/k8s/common/args/kube-controller-manager +on the control plane node and set the following argument. + +`--profiling=false` + +#### Control 1.3.3 + +Description: Ensure that the --use-service-account-credentials argument is +set to true (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-controller-manager | grep -v grep +``` + +Expected output: + +``` +--user-service-account-credentials=true +``` + +Remediation: + +Edit the Controller Manager configuration file +/var/snap/k8s/common/args/kube-controller-manager +on the control plane node to set the following argument. + +`--use-service-account-credentials=true` + +#### Control 1.3.4 + +Description: Ensure that the --service-account-private-key-file argument is +set as appropriate (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-controller-manager | grep -v grep +``` + +Expected output: + +``` +--service-account-private-key- +file=/etc/kubernetes/pki/serviceaccount.key +``` + +Remediation: + +Edit the Controller Manager configuration file +/var/snap/k8s/common/args/kube-controller-manager +on the control plane node and set the --service-account-private- +key-file parameter +to the private key file for service accounts. + +`--service-account-private-key-file=` + +#### Control 1.3.5 + +Description: Ensure that the --root-ca-file argument is set as appropriate +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-controller-manager | grep -v grep +``` + +Expected output: + +``` +--root-ca-file=/etc/kubernetes/pki/ca.crt +``` + +Remediation: + +Edit the Controller Manager configuration file +/var/snap/k8s/common/args/kube-controller-manager +on the control plane node and set the --root-ca-file parameter +to the certificate bundle file. + +`--root-ca-file=` + +#### Control 1.3.6 + +Description: Ensure that the RotateKubeletServerCertificate argument is set +to true (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-controller-manager | grep -v grep +``` + +Expected output: + +``` +--feature-gates is not set +``` + +Remediation: + +Edit the Controller Manager configuration file +/var/snap/k8s/common/args/kube-controller-manager +on the control plane node and set the --feature-gates parameter +to include RotateKubeletServerCertificate=true. + +`--feature-gates=RotateKubeletServerCertificate=true` + +#### Control 1.3.7 + +Description: Ensure that the --bind-address argument is set to 127.0.0.1 +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-controller-manager | grep -v grep +``` + +Remediation: + +Edit the Controller Manager configuration file +/var/snap/k8s/common/args/kube-controller-manager +on the control plane node and ensure the correct value for the +--bind-address parameter + +### Scheduler + +#### Control 1.4.1 + +Description: Ensure that the --profiling argument is set to false (Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-scheduler | grep -v grep +``` + +Remediation: + +Edit the Scheduler configuration file /var/snap/k8s/common/args/kube-scheduler file +on the control plane node and set the following argument. + +`--profiling=false` + +#### Control 1.4.2 + +Description: Ensure that the --bind-address argument is set to 127.0.0.1 +(Automated) + +Audit: + +``` +/bin/ps -ef | grep kube-scheduler | grep -v grep +``` + +Remediation: + +Edit the Scheduler configuration file /var/snap/k8s/common/args/kube-scheduler +on the control plane node and ensure the correct value for the +--bind-address parameter + diff --git a/docs/src/_parts/cis/node.md b/docs/src/_parts/cis/node.md new file mode 100644 index 000000000..4d1fc4136 --- /dev/null +++ b/docs/src/_parts/cis/node.md @@ -0,0 +1,631 @@ +## Worker Node Security Configuration + +### Worker Node Configuration Files + +#### Control 4.1.1 + +Description: Ensure that the kubelet service file permissions are set to 600 +or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/systemd/system/snap.k8s.kubelet.service; then stat -c permissions=%a /etc/systemd/system/snap.k8s.kubelet.service; fi' +``` + +Expected output: + +``` +permissions=644 +``` + +Remediation: + +Run the following command on each worker node. + + +`chmod 600 /etc/systemd/system/snap.k8s.kubelet.service` + +#### Control 4.1.2 + +Description: Ensure that the kubelet service file ownership is set to +root:root (Automated) + +Audit: + +``` +/bin/sh -c "if test -e /etc/systemd/system/snap.k8s.kubelet.service; then stat -c %U:%G /etc/systemd/system/snap.k8s.kubelet.service; else echo \"File not found\"; fi" +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on each worker node. + + +`chown root:root /etc/systemd/system/snap.k8s.kubelet.service` + +#### Control 4.1.3 + +Description: If proxy kubeconfig file exists ensure permissions are set to +600 or more restrictive (Manual) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/proxy.conf; then stat -c permissions=%a /etc/kubernetes/proxy.conf; fi' +``` + +Expected output: + +``` +permissions=644 +``` + +Remediation: + +Run the following command on the each worker node. + + +`chmod 600 /etc/kubernetes/proxy.conf` + +#### Control 4.1.4 + +Description: If proxy kubeconfig file exists ensure ownership is set to +root:root (Manual) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/proxy.conf; then stat -c %U:%G /etc/kubernetes/proxy.conf; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the each worker node. + + +`chown root:root /etc/kubernetes/proxy.conf` + +#### Control 4.1.5 + +Description: Ensure that the --kubeconfig kubelet.conf file permissions are +set to 600 or more restrictive (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/kubelet.conf; then stat -c permissions=%a /etc/kubernetes/kubelet.conf; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command on the each worker node. + + +`chmod 600 /etc/kubernetes/kubelet.conf` + +#### Control 4.1.6 + +Description: Ensure that the --kubeconfig kubelet.conf file ownership is set +to root:root (Automated) + +Audit: + +``` +/bin/sh -c 'if test -e /etc/kubernetes/kubelet.conf; then stat -c %U:%G /etc/kubernetes/kubelet.conf; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command on the each worker node. + + +`chown root:root /etc/kubernetes/kubelet.conf` + +#### Control 4.1.7 + +Description: Ensure that the certificate authorities file permissions are set +to 600 or more restrictive (Manual) + +Audit: + +``` +CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq) +if test -z $CAFILE; then CAFILE=/etc/kubernetes/pki/client-ca.crt; fi +if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command to modify the file permissions of the +--client-ca-file. + + +`chmod 600 ` + +#### Control 4.1.8 + +Description: Ensure that the client certificate authorities file ownership is +set to root:root (Manual) + +Audit: + +``` +CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq) +if test -z $CAFILE; then CAFILE=/etc/kubernetes/pki/client-ca.crt; fi +if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command to modify the ownership of the +--client-ca-file. + + +`chown root:root ` + +#### Control 4.1.9 + +Description: If the kubelet config.yaml configuration file is being used +validate permissions set to 600 or more restrictive (Manual) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kubelet; then stat -c permissions=%a /var/snap/k8s/common/args/kubelet; fi' +``` + +Expected output: + +``` +permissions=600 +``` + +Remediation: + +Run the following command (using the config file location +identified in the Audit step) + + +`chmod 600 /var/snap/k8s/common/args/kubelet` + +#### Control 4.1.10 + +Description: If the kubelet config.yaml configuration file is being used +validate file ownership is set to root:root (Manual) + +Audit: + +``` +/bin/sh -c 'if test -e /var/snap/k8s/common/args/kubelet; then stat -c %U:%G /var/snap/k8s/common/args/kubelet; fi' +``` + +Expected output: + +``` +root:root +``` + +Remediation: + +Run the following command (using the config file location +identified in the Audit step) + + +`chown root:root /var/snap/k8s/common/args/kubelet` + +### Kubelet + +#### Control 4.2.1 + +Description: Ensure that the --anonymous-auth argument is set to false +(Automated) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--anonymous-auth=false +``` + +Remediation: + +Edit the kubelet configuration file +/var/snap/k8s/common/args/kubelet on each worker node and set the following argument. + + +`--anonymous-auth=false` + + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.2 + +Description: Ensure that the --authorization-mode argument is not set to +AlwaysAllow (Automated) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--authorization-mode=Webhook +``` + +Remediation: + +Edit the kubelet configuration file +/var/snap/k8s/common/args/kubelet on each worker node and set the following argument. + +`--authorization-mode=Webhook` + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.3 + +Description: Ensure that the --client-ca-file argument is set as appropriate +(Automated) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--client-ca-file=/etc/kubernetes/pki/client-ca.crt +``` + +Remediation: + +Edit the kubelet configuration file +/var/snap/k8s/common/args/kubelet on each worker node and set the following argument. + +`--client-ca-file=` + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.4 + +Description: Verify that the --read-only-port argument is set to 0 (Manual) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--read-only-port=0 +``` + +Remediation: + +Edit the kubelet configuration file +/var/snap/k8s/common/args/kubelet on each worker node and set the following argument. + +`--read-only-port=0` + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.5 + +Description: Ensure that the --streaming-connection-idle-timeout argument is +not set to 0 (Manual) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--streaming-connection-idle-timeout is not set +``` + +Remediation: + +Edit the kubelet configuration file +/var/snap/k8s/common/args/kubelet on each worker node and set the following argument. + +`--streaming-connection-idle-timeout=5m` + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.6 + +Description: Ensure that the --protect-kernel-defaults argument is set to +true (Automated) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--protect-kernel-defaults=true +``` + +Remediation: + +Edit the kubelet configuration file +/var/snap/k8s/common/args/kubelet on each worker node and set the following argument. + +`--protect-kernel-defaults=true` + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.7 + +Description: Ensure that the --make-iptables-util-chains argument is set to +true (Automated) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--make-iptables-util-chains is not set +``` + +Remediation: + +Edit the kubelet configuration file +/var/snap/k8s/common/args/kubelet on each worker node and +remove the --make-iptables-util-chains argument. + +Restart the kubelet service. + +For example: `snap restart k8s.kubelet` + +#### Control 4.2.8 + +Description: Ensure that the --hostname-override argument is not set (Manual) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--hostname-override is set to false +``` + +Remediation: + +Edit the kubelet configuration file /var/snap/k8s/common/args/kubelet +on each worker node and remove the --hostname-override argument. + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.9 + +Description: Ensure that the eventRecordQPS argument is set to a level which +ensures appropriate event capture (Manual) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--event-qps is not set +``` + +Remediation: + +Edit the kubelet configuration file /var/snap/k8s/common/args/kubelet on each worker +node and +set the --event-qps parameter as appropriate. + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.10 + +Description: Ensure that the --tls-cert-file and --tls-private-key-file +arguments are set as appropriate (Manual) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--tls-cert-file=/etc/kubernetes/pki/kubelet.crt and --tls- +private-key-file=/etc/kubernetes/pki/kubelet.key +``` + +Remediation: + +Edit the kubelet configuration file /var/snap/k8s/common/args/kubelet on each worker +node and +set the following arguments: + +``` +--tls-cert-file= +--tls-cert-file= +``` + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.11 + +Description: Ensure that the --rotate-certificates argument is not set to +false (Automated) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +--rotate-certificates is not set +``` + +Remediation: + +Edit the kubelet configuration file /var/snap/k8s/common/args/kubelet on each worker +node and +remove the --rotate-certificates=false argument. + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.12 + +Description: Verify that the RotateKubeletServerCertificate argument is set +to true (Manual) + +Audit: + +``` +/bin/ps -fC kubelet +``` + +Expected output: + +``` +the RotateKubeletServerCertificate feature gate is not set +``` + +Remediation: + +Edit the kubelet configuration file /var/snap/k8s/common/args/kubelet on each worker +node and +set the argument --feature- +gates=RotateKubeletServerCertificate=true +on each worker node. + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + +#### Control 4.2.13 + +Description: Ensure that the Kubelet only makes use of Strong Cryptographic +Ciphers (Manual) + +Audit: + +``` +/bin/ps -fC 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_WIT +H_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: + +Edit the kubelet configuration file /var/snap/k8s/common/args/kubelet on each worker +node and +set the --tls-cipher-suites parameter as follows, or to a subset +of these values. + +``` +--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_WIT +H_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ +RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256 +``` + +Restart the kubelet service. + +For example, `snap restart k8s.kubelet` + diff --git a/docs/src/_parts/cis/policies.md b/docs/src/_parts/cis/policies.md new file mode 100644 index 000000000..08275b187 --- /dev/null +++ b/docs/src/_parts/cis/policies.md @@ -0,0 +1,345 @@ +## Kubernetes Policies + +### RBAC and Service Accounts + +#### Control 5.1.1 + +Description: 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] + +#### Control 5.1.2 + +Description: Minimize access to secrets (Manual) + +Remediation: + +Where possible, remove get, list and watch access to Secret +objects in the cluster. + +#### Control 5.1.3 + +Description: 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. + +#### Control 5.1.4 + +Description: Minimize access to create pods (Manual) + +Remediation: + +Where possible, remove create access to pod objects in the +cluster. + +#### Control 5.1.5 + +Description: 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 + +#### Control 5.1.6 + +Description: 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. + +#### Control 5.1.7 + +Description: Avoid use of system:masters group (Manual) + +Remediation: + +Remove the system:masters group from all users in the cluster. + +#### Control 5.1.8 + +Description: 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. + +### Pod Security Standards + +#### Control 5.2.1 + +Description: 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. + +#### Control 5.2.2 + +Description: 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. + +#### Control 5.2.3 + +Description: 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. + +#### Control 5.2.4 + +Description: 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. + +#### Control 5.2.5 + +Description: 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. + +#### Control 5.2.6 + +Description: 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`. + +#### Control 5.2.7 + +Description: 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. + +#### Control 5.2.8 + +Description: 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. + +#### Control 5.2.9 + +Description: 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. + +#### Control 5.2.10 + +Description: Minimize the admission of containers with capabilities assigned +(Manual) + +Remediation: + +Review the use of capabilites in applications running on your +cluster. Where a namespace +contains applicaions which do not require any Linux capabities +to operate consider adding +a PSP which forbids the admission of containers which do not +drop all capabilities. + +#### Control 5.2.11 + +Description: 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`. + +#### Control 5.2.12 + +Description: 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. + +#### Control 5.2.13 + +Description: 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. + +### Network Policies and CNI + +#### Control 5.3.1 + +Description: Ensure that the CNI in use supports NetworkPolicies (Manual) + +Remediation: + +If the CNI plugin in use does not support network policies, +consideration should be given to +making use of a different plugin, or finding an alternate +mechanism for restricting traffic +in the Kubernetes cluster. + +#### Control 5.3.2 + +Description: Ensure that all Namespaces have NetworkPolicies defined (Manual) + +Remediation: + +Follow the documentation and create NetworkPolicy objects as you +need them. + +### Secrets Management + +#### Control 5.4.1 + +Description: 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. + +#### Control 5.4.2 + +Description: Consider external secret storage (Manual) + +Remediation: + +Refer to the Secrets management options offered by your cloud +provider or a third-party +secrets management solution. + +### Extensible Admission Control + +#### Control 5.5.1 + +Description: Configure Image Provenance using ImagePolicyWebhook admission +controller (Manual) + +Remediation: + +Follow the Kubernetes documentation and setup image provenance. + +### General Policies + +#### Control 5.7.1 + +Description: Create administrative boundaries between resources using +namespaces (Manual) + +Remediation: + +Follow the documentation and create namespaces for objects in +your deployment as you need +them. + +#### Control 5.7.2 + +Description: 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. +An example is as follows: + securityContext: + seccompProfile: + type: RuntimeDefault + +#### Control 5.7.3 + +Description: 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. + +#### Control 5.7.4 + +Description: 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. + diff --git a/k8s/scripts/cis/README.md b/k8s/scripts/cis/README.md new file mode 100644 index 000000000..9ed964c1d --- /dev/null +++ b/k8s/scripts/cis/README.md @@ -0,0 +1,51 @@ +# cis-yaml-to-md + +## Description + +This script parses YAML files from an input directory and generates corresponding Markdown files in an output directory using a Jinja2 template. + +This allows us to define a set of input files that contain CIS benchmarks and generate a complete report in Markdown format. + +The input directory is expected to contain a config.yaml and kube-bench files. +For example, the current set of markdown files in docs/src/_parts/cis were generated using the following folder as the input directory: [cis-1.24-ck8s](https://github.com/canonical/kube-bench/tree/ck8s/cfg/cis-1.24-ck8s) + +This script processes each input YAML file one at a time, and produces a corresponding Markdown file. Therefore, if there are 5 input files that are not named *config.yaml*, there will be 5 output files. The script uses the config.yaml file but does not render it to Markdown. + +## Usage + +Clone our fork of the kube-bench repository + +```sh +git clone git@github.com:canonical/kube-bench.git +cd kube-bench && git checkout ck8s # TODO remove when merged +cd .. +``` + +Create a virtual environment + +```sh +python3 -m venv venv +source /venv/bin/activate +``` + +Install dependencies + +```sh +pip install -r requirements.txt +``` + +Run the script + +```sh +python3 cis-yaml-to-md.py --input-dir=./kube-bench/cfg/cis-1.24-ck8s --output-dir=../../../docs/src/_parts/cis/ +``` + +You should see the following output: + +```sh +INFO:__main__:Rendered kube-bench/cfg/cis-1.24-ck8s/policies.yaml to ../../../docs/src/_parts/cis/policies.md. +INFO:__main__:Rendered kube-bench/cfg/cis-1.24-ck8s/node.yaml to ../../../docs/src/_parts/cis/node.md. +INFO:__main__:Rendered kube-bench/cfg/cis-1.24-ck8s/controlplane.yaml to ../../../docs/src/_parts/cis/controlplane.md. +INFO:__main__:Rendered kube-bench/cfg/cis-1.24-ck8s/master.yaml to ../../../docs/src/_parts/cis/master.md. +INFO:__main__:Rendered kube-bench/cfg/cis-1.24-ck8s/etcd.yaml to ../../../docs/src/_parts/cis/etcd.md +``` diff --git a/k8s/scripts/cis/cis-template.jinja2 b/k8s/scripts/cis/cis-template.jinja2 new file mode 100644 index 000000000..f9d54148e --- /dev/null +++ b/k8s/scripts/cis/cis-template.jinja2 @@ -0,0 +1,38 @@ +## {{ kube_bench_control_file.text | trim }} + +{% for group in kube_bench_control_file.groups %} +{% if group.text != title %} +### {{group.text}} + +{% endif %} +{% for check in group.checks %} +#### Control {{ check.id }} + +{% if check.text %} +Description: {{ check.text | trim | wordwrap(64) }} + +{% endif %} +{% if check.audit %} +Audit: + +``` +{{ check.audit | trim }} +``` + +{% endif %} +{% if custom_outputs_by_control_id[check.id] %} +Expected output: + +``` +{{ custom_outputs_by_control_id[check.id] | trim | wordwrap(64) }} +``` + +{% endif %} +{% if check.remediation %} +Remediation: + +{{ check.remediation | trim | wordwrap(64)}} + +{% endif %} +{% endfor %} +{% endfor %} diff --git a/k8s/scripts/cis/cis-yaml-to-md.py b/k8s/scripts/cis/cis-yaml-to-md.py new file mode 100644 index 000000000..5c297272b --- /dev/null +++ b/k8s/scripts/cis/cis-yaml-to-md.py @@ -0,0 +1,150 @@ +import argparse +import logging +from pathlib import Path + +import yaml +from jinja2 import Environment, FileSystemLoader + +from typing import Any + +USAGE = """ +python3 cis-yaml-to-md.py --input-directory=INPUT_DIR --output-directory=OUTPUT_DIR +""" + +DESCRIPTION = """ +Parse the YAML files in the input directory and generate +Markdown files in the output directory. The Markdown files are generated using the +Jinja2 template file. + +It is expected that the input directory contains a config.yaml file. +(See https://raw.githubusercontent.com/canonical/kube-bench/ck8s/cfg/cis-1.24-ck8s/config.yaml) + +It is also expected that the input directory contains the control files. +(See controlplane.md, etcd.yaml, master.yaml, node.yaml and policies.yaml from the same repo.) + +The config.yaml file will not be rendered to Markdown, but it will be used to extract variables +that will be replaced when generating the markdown files. +""" + +logging.basicConfig(level=logging.INFO) + +LOG = logging.getLogger(__name__) + +DIR = Path(__file__).absolute().parent + +JINJA_TEMPLATE = "cis-template.jinja2" +KUBE_BENCH_CONFIG_FILE = "config.yaml" +KUBE_BENCH_CONTROL_OUTPUTS = "expected-outputs.yaml" + + +def get_variable_substitutions(data: Any) -> dict[str, str]: + return { + "$apiserverbin": data["master"]["apiserver"]["bins"][0], + "$apiserverconf": data["master"]["apiserver"]["confs"][0], + "$controllermanagerbin": data["master"]["controllermanager"]["bins"][0], + "$controllermanagerconf": data["master"]["controllermanager"]["confs"][0], + "$controllermanagerkubeconfig": data["master"]["controllermanager"][ + "kubeconfig" + ][0], + "$etcdbin": data["master"]["etcd"]["bins"][0], + "$etcdconf": data["master"]["etcd"]["confs"][0], + "$kubeletbin": data["node"]["kubelet"]["bins"][0], + "$kubeletcafile": data["node"]["kubelet"]["cafile"][0], + "$kubeletconf": data["node"]["kubelet"]["confs"][0], + "$kubeletkubeconfig": data["node"]["kubelet"]["kubeconfig"][0], + "$kubeletsvc": data["node"]["kubelet"]["svc"][0], + "$proxykubeconfig": data["node"]["proxy"]["kubeconfig"][0], + "$schedulerbin": data["master"]["scheduler"]["bins"][0], + "$schedulerconf": data["master"]["scheduler"]["confs"][0], + "$schedulerkubeconfig": data["master"]["scheduler"]["kubeconfig"][0], + } + + +def render_jinja_template(**kwargs) -> str: + def to_yaml_filter(value): + return yaml.dump(value, default_flow_style=False).strip() + + env = Environment( + loader=FileSystemLoader(DIR), + trim_blocks=True, + lstrip_blocks=True, + ) + env.filters["to_yaml"] = to_yaml_filter + + return env.get_template(JINJA_TEMPLATE).render(**kwargs) + + +def generate_markdown_from_yaml_file( + original_yaml_file: Path, + substitutions: dict[str, str] | None = None, + custom_outputs_by_control_id: dict[str, str] | None = None, +): + markdown_content = render_jinja_template( + kube_bench_control_file=yaml.safe_load(original_yaml_file.read_text()), + custom_outputs_by_control_id=custom_outputs_by_control_id, + ) + + if substitutions: + for old, new in substitutions.items(): + markdown_content = markdown_content.replace(old, new) + + return markdown_content + + +def setup_directories(input_dir: str, output_dir: str) -> tuple[Path, Path]: + input_path = Path(input_dir).expanduser() + output_path = Path(output_dir).expanduser() + output_path.mkdir(exist_ok=True) + return input_path, output_path + + +def get_kube_bench_input_files(input_dir: Path) -> list[Path]: + return [ + file + for file in input_dir.iterdir() + if file.is_file() + and file.suffix == ".yaml" + and file.name != KUBE_BENCH_CONFIG_FILE + ] + + +def process_files(input_dir, output_dir, substitutions, custom_outputs_by_control_id): + for file in get_kube_bench_input_files(input_dir): + output_file = output_dir / f"{file.stem}.md" + markdown_content = generate_markdown_from_yaml_file( + file, substitutions, custom_outputs_by_control_id + ) + output_file.write_text(markdown_content) + + LOG.info(f"Rendered {file} to {output_file}.") + + +def parse_arguments(): + parser = argparse.ArgumentParser(usage=USAGE, description=DESCRIPTION) + parser.add_argument( + "--input-dir", type=str, required=True, help="Input directory path" + ) + parser.add_argument( + "--output-dir", type=str, required=True, help="Output directory path" + ) + return parser.parse_args() + + +def main(): + args = parse_arguments() + + input_dir, output_dir = setup_directories(args.input_dir, args.output_dir) + + substitutions = get_variable_substitutions( + yaml.safe_load((input_dir / KUBE_BENCH_CONFIG_FILE).read_text()) + ) + + custom_outputs_by_control_id: dict[str, str] = yaml.safe_load( + (DIR / KUBE_BENCH_CONTROL_OUTPUTS).read_text() + ) + + process_files(input_dir, output_dir, substitutions, custom_outputs_by_control_id) + + +if __name__ == "__main__": + main() diff --git a/k8s/scripts/cis/expected-outputs.yaml b/k8s/scripts/cis/expected-outputs.yaml new file mode 100644 index 000000000..e1c6df113 --- /dev/null +++ b/k8s/scripts/cis/expected-outputs.yaml @@ -0,0 +1,89 @@ +1.1.1: "permissions=600" +1.1.2: "root:root" +1.1.3: "permissions=600" +1.1.4: "root:root" +1.1.5: "permissions=600" +1.1.6: "root:root" +1.1.7: "permissions=644" +1.1.8: "root:root" +1.1.9: "permissions=644" +1.1.10: "root:root" +1.1.11: "permissions=700" +1.1.12: "etcd:etcd" +1.1.13: "permissions=600" +1.1.14: "root:root" +1.1.15: "permissions=600" +1.1.16: "root:root" +1.1.17: "permissions=600" +1.1.18: "root:root" +1.1.19: "root:root" +1.1.20: "permissions=600" +1.1.21: "permissions=600" +1.2.1: "--anonymous-auth=false" +1.2.2: "--token-auth-file is not set" +1.2.3: "--enable-admission-plugins does not contain DenyServiceExternalIPs" +1.2.4: "--kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt and --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key" +1.2.5: "--kubelet-certificate-authority=/etc/kubernetes/pki/ca.crt" +1.2.6: "--authorization-mode=Node,RBAC" +1.2.7: "--authorization-mode=Node,RBAC" +1.2.8: "--authorization-mode=Node,RBAC" +1.2.9: "--enable-admission-plugins=NodeRestriction,EventRateLimit,AlwaysPullImages" +1.2.10: "--enable-admission-plugins=NodeRestriction,EventRateLimit,AlwaysPullImages" +1.2.11: "--enable-admission-plugins=NodeRestriction,EventRateLimit,AlwaysPullImages" +1.2.12: "--enable-admission-plugins=NodeRestriction,EventRateLimit,AlwaysPullImages" +1.2.13: "--disable-admission-plugins is not set" +1.2.14: "--disable-admission-plugins is not set" +1.2.15: "--enable-admission-plugins=NodeRestriction,EventRateLimit,AlwaysPullImages" +1.2.16: "--secure-port=6443" +1.2.17: "--profiling=false" +1.2.18: "--audit-log-path=/var/log/apiserver/audit.log" +1.2.19: "--audit-log-maxage=30" +1.2.20: "--audit-log-maxbackup=10" +1.2.21: "--audit-log-maxsize=100" +1.2.22: "--request-timeout=300s" +1.2.23: "--service-account-lookup is not set" +1.2.24: "--service-account-key-file=/etc/kubernetes/pki/serviceaccount.key" +1.2.25: "--etcd-certfile=/etc/kubernetes/pki/etcd/client.crt and --etcd-keyfile=/etc/kubernetes/pki/etcd/client.key" +1.2.26: "--tls-cert-file=/etc/kubernetes/pki/apiserver.crt and --tls-private-key-file=/etc/kubernetes/pki/apiserver.key" +1.2.27: "--client-ca-file=/etc/kubernetes/pki/client-ca.crt" +1.2.28: "--etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt" +1.2.29: "--encryption-provider-config is set" +1.2.30: "--encryption-provider-config is one of or all of aescbc,kms,secretbox" +1.2.31: "--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" +1.3.1: "--terminated-pod-gc-threshold=12500" +1.3.2: "--profiling=false" +1.3.3: "--user-service-account-credentials=true" +1.3.4: "--service-account-private-key-file=/etc/kubernetes/pki/serviceaccount.key" +1.3.5: "--root-ca-file=/etc/kubernetes/pki/ca.crt" +1.3.6: "--feature-gates is not set" +2.1: "ETCD_CERT_FILE and ETCD_KEY_FILE are set" +2.2: "ETCD_CLIENT_CERT_AUTH is set to true" +2.3: "ETCD_AUTO_TLS is not set" +2.4: "ETCD_PEER_CERT_FILE and ETCD_PEER_KEY_FILE are set" +2.5: "ETCD_PEER_CLIENT_CERT_AUTH is set to true" +2.6: "ETCD_PEER_AUTO_TLS is not set" +2.7: "ETCD_TRUSTED_CA_FILE is set" +3.2.1: "--audit-policy-file=/var/snap/k8s/common/etc/audit-policy.yaml" +4.1.1: "permissions=644" +4.1.2: "root:root" +4.1.3: "permissions=644" +4.1.4: "root:root" +4.1.5: "permissions=600" +4.1.6: "root:root" +4.1.7: "permissions=600" +4.1.8: "root:root" +4.1.9: "permissions=600" +4.1.10: "root:root" +4.2.1: "--anonymous-auth=false" +4.2.2: "--authorization-mode=Webhook" +4.2.3: "--client-ca-file=/etc/kubernetes/pki/client-ca.crt" +4.2.4: "--read-only-port=0" +4.2.5: "--streaming-connection-idle-timeout is not set" +4.2.6: "--protect-kernel-defaults=true" +4.2.7: "--make-iptables-util-chains is not set" +4.2.8: "--hostname-override is set to false" +4.2.9: "--event-qps is not set" +4.2.10: "--tls-cert-file=/etc/kubernetes/pki/kubelet.crt and --tls-private-key-file=/etc/kubernetes/pki/kubelet.key" +4.2.11: "--rotate-certificates is not set" +4.2.12: "the RotateKubeletServerCertificate feature gate is not set" +4.2.13: "--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" diff --git a/k8s/scripts/cis/requirements.txt b/k8s/scripts/cis/requirements.txt new file mode 100644 index 000000000..28e89435f --- /dev/null +++ b/k8s/scripts/cis/requirements.txt @@ -0,0 +1,2 @@ +Jinja2==3.1.4 +PyYAML==6.0.1