--- controls: version: 1.11 id: 1 text: "Master Node Security Configuration" type: "master" groups: - id: 1.1 text: "API Server" checks: - id: 1.1.1 text: "Ensure that the --anonymous-auth argument is set to false (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--anonymous-auth" compare: op: eq value: false set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the below parameter. --anonymous-auth=false scored: true - id: 1.1.2 text: "Ensure that the --basic-auth-file argument is not set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--basic-auth-file" set: false remediation: | Follow the documentation and configure alternate mechanisms for authentication. Then, edit the API server pod specification file $apiserverconf on the master node and remove the --basic-auth-file= parameter. scored: true - id: 1.1.3 text: "Ensure that the --insecure-allow-any-token argument is not set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--insecure-allow-any-token" set: false remediation: | Edit the API server pod specification file $apiserverconf on the master node and remove the --insecure-allow-any-token parameter. scored: true - id: 1.1.4 text: "Ensure that the --kubelet-https argument is set to true (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: or test_items: - flag: "--kubelet-https" compare: op: eq value: true set: true - flag: "--kubelet-https" set: false remediation: | Edit the API server pod specification file $apiserverconf on the master node and remove the --kubelet-https parameter. scored: true - id: 1.1.5 text: "Ensure that the --insecure-bind-address argument is not set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--insecure-bind-address" set: false remediation: | Edit the API server pod specification file $apiserverconf on the master node and remove the --insecure-bind-address parameter. scored: true - id: 1.1.6 text: "Ensure that the --insecure-port argument is set to 0 (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--insecure-port" compare: op: eq value: 0 set: true remediation: | Edit the API server pod specification file $apiserverconf apiserver.yaml on the master node and set the below parameter. --insecure-port=0 scored: true - id: 1.1.7 text: "Ensure that the --secure-port argument is not set to 0 (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: or test_items: - flag: "--secure-port" compare: op: gt value: 0 set: true - flag: "--secure-port" set: false remediation: | Edit the API server pod specification file $apiserverconf on the master node and either remove the --secure-port parameter or set it to a different (non-zero) desired port. scored: true - id: 1.1.8 text: "Ensure that the --profiling argument is set to false (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--profiling" compare: op: eq value: false set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the below parameter. --profiling=false scored: true - id: 1.1.9 text: "Ensure that the --repair-malformed-updates argument is set to false (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--repair-malformed-updates" compare: op: eq value: false set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the below parameter. --repair-malformed-updates=false scored: true - id: 1.1.10 text: "Ensure that the admission control plugin AlwaysAdmit is not set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: or test_items: - flag: "--enable-admission-plugins" compare: op: nothave value: AlwaysAdmit set: true - flag: "--enable-admission-plugins" set: false remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --enable-admission-plugins parameter to a value that does not include AlwaysAdmit. scored: true - id: 1.1.11 text: "Ensure that the admission control plugin AlwaysPullImages is set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--enable-admission-plugins" compare: op: has value: "AlwaysPullImages" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --enable-admission-plugins to include AlwaysPullImages. --enable-admission-plugins=...,AlwaysPullImages,... scored: true - id: 1.1.12 text: "Ensure that the admission control plugin DenyEscalatingExec is set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--enable-admission-plugins" compare: op: has value: "DenyEscalatingExec" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --enable-admission-plugins parameter to a value that includes DenyEscalatingExec. --enable-admission-plugins=...,DenyEscalatingExec,... scored: true - id: 1.1.13 text: "Ensure that the admission control plugin SecurityContextDeny is set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--enable-admission-plugins" compare: op: has value: "SecurityContextDeny" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --enable-admission-plugins parameter to include SecurityContextDeny. --enable-admission-plugins=...,SecurityContextDeny,... scored: true - id: 1.1.14 text: "Ensure that the admission control plugin NamespaceLifecycle is set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: or test_items: - flag: "--disable-admission-plugins" compare: op: nothave value: "NamespaceLifecycle" set: true - flag: "--disable-admission-plugins" set: false remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --disable-admission-plugins parameter to ensure it does not include NamespaceLifecycle. --disable-admission-plugins=...,NamespaceLifecycle,... scored: true - id: 1.1.15 text: "Ensure that the --audit-log-path argument is set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--audit-log-path" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --audit-log-path parameter to a suitable path and file where you would like audit logs to be written, for example: --audit-log-path=/var/log/apiserver/audit.log scored: true - id: 1.1.16 text: "Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--audit-log-maxage" compare: op: gte value: 30 set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days: --audit-log-maxage=30 scored: true - id: 1.1.17 text: "Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--audit-log-maxbackup" compare: op: gte value: 10 set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate value. --audit-log-maxbackup=10 scored: true - id: 1.1.18 text: "Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--audit-log-maxsize" compare: op: gte value: 100 set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --audit-log-maxsize parameter to an appropriate size in MB. For example, to set it as 100 MB: --audit-log-maxsize=100 scored: true - id: 1.1.19 text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--authorization-mode" compare: op: nothave value: "AlwaysAllow" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --authorization-mode parameter to values other than AlwaysAllow. One such example could be as below. --authorization-mode=RBAC scored: true - id: 1.1.20 text: "Ensure that the --token-auth-file parameter is not set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--token-auth-file" set: false remediation: | Follow the documentation and configure alternate mechanisms for authentication. Then, edit the API server pod specification file $apiserverconf on the master node and remove the --token-auth-file= parameter. scored: true - id: 1.1.21 text: "Ensure that the --kubelet-certificate-authority argument is set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--kubelet-certificate-authority" set: true remediation: | Follow the Kubernetes documentation and setup the TLS connection between the apiserver and kubelets. Then, edit the API server pod specification file $apiserverconf on the master node and set the --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority. --kubelet-certificate-authority= scored: true - id: 1.1.22 text: "Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: and test_items: - flag: "--kubelet-client-certificate" set: true - flag: "--kubelet-client-key" set: true remediation: | Follow the Kubernetes documentation and set up the TLS connection between the apiserver and kubelets. Then, edit API server pod specification file $apiserverconf on the master node and set the kubelet client certificate and key parameters as below. --kubelet-client-certificate= --kubelet-client-key= scored: true - id: 1.1.23 text: "Ensure that the --service-account-lookup argument is set to true (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--service-account-lookup" compare: op: eq value: true set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the below parameter. --service-account-lookup=true scored: true - id: 1.1.24 text: "Ensure that the admission control plugin PodSecurityPolicy is set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--enable-admission-plugins" compare: op: has value: "PodSecurityPolicy" set: true remediation: | Follow the documentation and create Pod Security Policy objects as per your environment. Then, edit the API server pod specification file $apiserverconf on the master node and set the --enable-admission-plugins parameter to a value that includes PodSecurityPolicy : --enable-admission-plugins=...,PodSecurityPolicy,... Then restart the API Server. scored: true - id: 1.1.25 text: "Ensure that the --service-account-key-file argument is set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--service-account-key-file" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --service-account-key-file parameter to the public key file for service accounts: --service-account-key-file= scored: true - id: 1.1.26 text: "Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: and test_items: - flag: "--etcd-certfile" set: true - flag: "--etcd-keyfile" set: true remediation: | Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd. Then, edit the API server pod specification file $apiserverconf on the master node and set the etcd certificate and key file parameters. --etcd-certfile= --etcd-keyfile= scored: true - id: 1.1.27 text: "Ensure that the admission control plugin ServiceAccount is set(Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: or test_items: - flag: "--enable-admission-plugins" compare: op: has value: "ServiceAccount" set: true - flag: "--enable-admission-plugins" set: false remediation: | Follow the documentation and create ServiceAccount objects as per your environment. Then, edit the API server pod specification file $apiserverconf on the master node and set the --enable-admission-plugins parameter to a value that includes ServiceAccount. --enable-admission-plugins=...,ServiceAccount,... scored: true - id: 1.1.28 text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: and test_items: - flag: "--tls-cert-file" set: true - flag: "--tls-private-key-file" set: true remediation: | Follow the Kubernetes documentation and set up the TLS connection on the apiserver. Then, edit the API server pod specification file $apiserverconf on the master node and set the TLS certificate and private key file parameters. --tls-cert-file= --tls-private-key-file= scored: true - id: 1.1.29 text: "Ensure that the --client-ca-file argument is set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--client-ca-file" set: true remediation: | Follow the Kubernetes documentation and set up the TLS connection on the apiserver. Then, edit the API server pod specification file $apiserverconf on the master node and set the client certificate authority file. --client-ca-file= scored: true - id: 1.1.30 text: "Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Not Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--tls-cipher-suites" compare: op: has value: "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" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the below parameter. --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256 scored: false - id: 1.1.31 text: "Ensure that the --etcd-cafile argument is set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--etcd-cafile" set: true remediation: | Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd. Then, edit the API server pod specification file $apiserverconf on the master node and set the etcd certificate authority file parameter. --etcd-cafile= scored: true - id: 1.1.32 text: "Ensure that the --authorization-mode argument is set to Node (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--authorization-mode" compare: op: has value: "Node" set: true remediation: | Edit the API server pod specification file $apiserverconf on the master node and set the --authorization-mode parameter to a value that includes Node. --authorization-mode=Node,RBAC scored: true - id: 1.1.33 text: "Ensure that the admission control plugin NodeRestriction is set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--enable-admission-plugins" compare: op: has value: "NodeRestriction" set: true remediation: | Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets. Then, edit the API server pod specification file $apiserverconf on the master node and set the --enable-admission-plugins parameter to a value that includes NodeRestriction. --enable-admission-plugins=...,NodeRestriction,... scored: true - id: 1.1.34 text: "Ensure that the --experimental-encryption-provider-config argument is set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--experimental-encryption-provider-config" set: true remediation: | Follow the Kubernetes documentation and configure a EncryptionConfig file. Then, edit the API server pod specification file $apiserverconf on the master node and set the --experimental-encryption-provider-config parameter to the path of that file: --experimental-encryption-provider-config= scored: true - id: 1.1.35 text: "Ensure that the encryption provider is set to aescbc (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" type: "manual" remediation: | [Manual test] Follow the Kubernetes documentation and configure a EncryptionConfig file. In this file, choose aescbc as the encryption provider. For example, kind: EncryptionConfig apiVersion: v1 resources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: <32-byte base64-encoded secret> scored: true - id: 1.1.36 text: "Ensure that the admission control plugin EventRateLimit is set (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--enable-admission-plugins" compare: op: has value: "EventRateLimit" set: true remediation: | Follow the Kubernetes documentation and set the desired limits in a configuration file. Then, edit the API server pod specification file $apiserverconf and set the below parameters. --enable-admission-plugins=...,EventRateLimit,... --admission-control-config-file= scored: true - id: 1.1.37a text: "Ensure that the AdvancedAuditing argument is not set to false (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: or test_items: - flag: "--feature-gates" compare: op: nothave value: "AdvancedAuditing=false" set: true - flag: "--feature-gates" set: false remediation: | Follow the Kubernetes documentation and set the desired audit policy in the /etc/kubernetes/audit-policy.yaml file. Then, edit the API server pod specification file $apiserverconf and set the below parameters. --audit-policy-file=/etc/kubernetes/audit-policy.yaml scored: true - id: 1.1.37b text: "Ensure that the AdvancedAuditing argument is not set to false (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--audit-policy-file" compare: op: eq value: "/etc/kubernetes/audit-policy.yaml" set: true remediation: | Follow the Kubernetes documentation and set the desired audit policy in the /etc/kubernetes/audit-policy.yaml file. Then, edit the API server pod specification file $apiserverconf and set the below parameters. --audit-policy-file=/etc/kubernetes/audit-policy.yaml scored: true - id: 1.1.38 text: "Ensure that the --request-timeout argument is set as appropriate (Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: bin_op: or test_items: - flag: "--request-timeout" set: false - flag: "--request-timeout" set: true remediation: | Edit the API server pod specification file $apiserverconf and set the below parameter as appropriate and if needed. For example, --request-timeout=300s scored: true - id: 1.1.39 text: "Ensure that the API Server only makes use of Strong Cryptographic Ciphers ( Not Scored)" audit: "ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--tls-cipher-suites" compare: op: eq value: "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" set: true remediation: | Edit the API server pod specification file /etc/kubernetes/manifests kube-apiserver.yaml on the master node and set the below parameter. --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256 scored: false - id: 1.2 text: "Scheduler" checks: - id: 1.2.1 text: "Ensure that the --profiling argument is set to false (Scored)" audit: "ps -ef | grep $schedulerbin | grep -v grep" tests: test_items: - flag: "--profiling" compare: op: eq value: false set: true remediation: | Edit the Scheduler pod specification file $schedulerconf file on the master node and set the below parameter. --profiling=false scored: true - id: 1.2.2 text: "Ensure that the --address argument is set to 127.0.0.1 (Scored)" audit: "ps -ef | grep $schedulerbin | grep -v grep" tests: bin_op: or test_items: - flag: "--address" compare: op: eq value: "127.0.0.1" set: true - flag: "--address" set: false remediation: | Edit the Scheduler pod specification file $schedulerconf file on the master node and ensure the correct value for the --address parameter. scored: true - id: 1.3 text: "Controller Manager" checks: - id: 1.3.1 text: "Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Scored)" audit: "ps -ef | grep $controllermanagerbin | grep -v grep" tests: test_items: - flag: "--terminated-pod-gc-threshold" set: true remediation: | Edit the Controller Manager pod specification file $controllermanagerconf on the master node and set the --terminated-pod-gc-threshold to an appropriate threshold, for example: --terminated-pod-gc-threshold=10 scored: true - id: 1.3.2 text: "Ensure that the --profiling argument is set to false (Scored)" audit: "ps -ef | grep $controllermanagerbin | grep -v grep" tests: test_items: - flag: "--profiling" compare: op: eq value: false set: true remediation: | Edit the Controller Manager pod specification file $controllermanagerconf on the master node and set the below parameter. --profiling=false scored: true - id: 1.3.3 text: "Ensure that the --use-service-account-credentials argument is set to true (Scored)" audit: "ps -ef | grep $controllermanagerbin | grep -v grep" tests: test_items: - flag: "--use-service-account-credentials" compare: op: eq value: true set: true remediation: | Edit the Controller Manager pod specification file $controllermanagerconf on the master node to set the below parameter. --use-service-account-credentials=true scored: true - id: 1.3.4 text: "Ensure that the --service-account-private-key-file argument is set as appropriate (Scored)" audit: "ps -ef | grep $controllermanagerbin | grep -v grep" tests: test_items: - flag: "--service-account-private-key-file" set: true remediation: | Edit the Controller Manager pod specification file $controllermanagerconf on the master node and set the --service-account-private- key-file parameter to the private key file for service accounts. --service-account-private-key-file= scored: true - id: 1.3.5 text: "Ensure that the --root-ca-file argument is set as appropriate (Scored)" audit: "ps -ef | grep $controllermanagerbin | grep -v grep" tests: test_items: - flag: "--root-ca-file" set: true remediation: | Edit the Controller Manager pod specification file $controllermanagerconf on the master node and set the --root-ca-file parameter to the certificate bundle file. --root-ca-file= scored: true - id: 1.3.6 text: "Ensure that the RotateKubeletServerCertificate argument is set to true (Scored)" audit: "ps -ef | grep $controllermanagerbin | grep -v grep" tests: test_items: - flag: "--feature-gates" compare: op: eq value: "RotateKubeletServerCertificate=true" set: true remediation: | Edit the Controller Manager pod specification file $controllermanagerconf controller-manager.yaml on the master node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true. --feature-gates=RotateKubeletServerCertificate=true scored: true - id: 1.3.7 text: "Ensure that the --address argument is set to 127.0.0.1 (Scored)" audit: "ps -ef | grep $controllermanagerbin | grep -v grep" tests: bin_op: or test_items: - flag: "--address" compare: op: eq value: "127.0.0.1" set: true - flag: "--address" set: false remediation: | Edit the Controller Manager pod specification file $controllermanagerconf controller-manager.yaml on the master node and ensure the correct value for the --address parameter. scored: true - id: 1.4 text: "Configuration Files" checks: - id: 1.4.1 text: "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Scored)" audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c %a $apiserverconf; fi'" tests: bin_op: or test_items: - flag: "644" compare: op: eq value: "644" set: true - flag: "640" compare: op: eq value: "640" set: true - flag: "600" compare: op: eq value: "600" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chmod 644 $apiserverconf scored: true - id: 1.4.2 text: "Ensure that the API server pod specification file ownership is set to root:root (Scored)" audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'" tests: test_items: - flag: "root:root" compare: op: eq value: "root:root" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chown root:root $apiserverconf scored: true - id: 1.4.3 text: "Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Scored)" audit: "/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %a $controllermanagerconf; fi'" tests: bin_op: or test_items: - flag: "644" compare: op: eq value: "644" set: true - flag: "640" compare: op: eq value: "640" set: true - flag: "600" compare: op: eq value: "600" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chmod 644 $controllermanagerconf scored: true - id: 1.4.4 text: "Ensure that the controller manager pod specification file ownership is set to root:root (Scored)" audit: "/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'" tests: test_items: - flag: "root:root" compare: op: eq value: "root:root" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chown root:root $controllermanagerconf scored: true - id: 1.4.5 text: "Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Scored)" audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c %a $schedulerconf; fi'" tests: bin_op: or test_items: - flag: "644" compare: op: eq value: "644" set: true - flag: "640" compare: op: eq value: "640" set: true - flag: "600" compare: op: eq value: "600" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chmod 644 $schedulerconf scored: true - id: 1.4.6 text: "Ensure that the scheduler pod specification file ownership is set to root:root (Scored)" audit: "/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'" tests: test_items: - flag: "root:root" compare: op: eq value: "root:root" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chown root:root $schedulerconf scored: true - id: 1.4.7 text: "Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Scored)" audit: "/bin/sh -c 'if test -e $etcdconf; then stat -c %a $etcdconf; fi'" tests: bin_op: or test_items: - flag: "644" compare: op: eq value: "644" set: true - flag: "640" compare: op: eq value: "640" set: true - flag: "600" compare: op: eq value: "600" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chmod 644 $etcdconf scored: true - id: 1.4.8 text: "Ensure that the etcd pod specification file ownership is set to root:root (Scored)" audit: "/bin/sh -c 'if test -e $etcdconf; then stat -c %U:%G $etcdconf; fi'" tests: test_items: - flag: "root:root" compare: op: eq value: "root:root" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chown root:root $etcdconf scored: true - id: 1.4.9 text: "Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Not Scored)" audit: "stat -c %a " type: "manual" remediation: | [Manual test] Run the below command (based on the file location on your system) on the master node. For example, chmod 644 scored: true - id: 1.4.10 text: "Ensure that the Container Network Interface file ownership is set to root:root (Not Scored)" audit: "stat -c %U:%G " type: "manual" remediation: | [Manual test] Run the below command (based on the file location on your system) on the master node. For example, chown root:root scored: true - id: 1.4.11 text: "Ensure that the etcd data directory permissions are set to 700 or more restrictive (Scored)" audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c %a tests: test_items: - flag: "700" compare: op: eq value: "700" set: true remediation: | On the etcd server node, get the etcd data directory, passed as an argument --data-dir , from the below command: ps -ef | grep $etcdbin Run the below command (based on the etcd data directory found above). For example, chmod 700 /var/lib/etcd scored: true - id: 1.4.12 text: "Ensure that the etcd data directory ownership is set to etcd:etcd (Scored)" audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%' | xargs stat -c %U:%G tests: test_items: - flag: "etcd:etcd" set: true remediation: | On the etcd server node, get the etcd data directory, passed as an argument --data-dir , from the below command: ps -ef | grep $etcdbin Run the below command (based on the etcd data directory found above). For example, chown etcd:etcd /var/lib/etcd scored: true - id: 1.4.13 text: "Ensure that the admin.conf file permissions are set to 644 or more restrictive (Scored)" audit: "/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %a /etc/kubernetes/admin.conf; fi'" tests: bin_op: or test_items: - flag: "644" compare: op: eq value: "644" set: true - flag: "640" compare: op: eq value: "640" set: true - flag: "600" compare: op: eq value: "600" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chmod 644 /etc/kubernetes/admin.conf scored: true - id: 1.4.14 text: "Ensure that the admin.conf file ownership is set to root:root (Scored)" audit: "/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'" tests: test_items: - flag: "root:root" compare: op: eq value: "root:root" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chown root:root /etc/kubernetes/admin.conf scored: true - id: 1.4.15 text: "Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Scored)" audit: "/bin/sh -c 'if test -e /etc/kubernetes/scheduler.conf; then stat -c %a /etc/kubernetes/scheduler.conf; fi'" tests: bin_op: or test_items: - flag: "644" compare: op: eq value: "644" set: true - flag: "640" compare: op: eq value: "640" set: true - flag: "600" compare: op: eq value: "600" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chmod 644 /etc/kubernetes/scheduler.conf scored: true - id: 1.4.16 text: "Ensure that the scheduler.conf file ownership is set to root:root (Scored)" audit: "/bin/sh -c 'if test -e /etc/kubernetes/scheduler.conf; then stat -c %U:%G /etc/kubernetes/scheduler.conf; fi'" tests: test_items: - flag: "root:root" compare: op: eq value: "root:root" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chown root:root /etc/kubernetes/scheduler.conf scored: true - id: 1.4.17 text: "Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Scored)" audit: "/bin/sh -c 'if test -e /etc/kubernetes/controller-manager.conf; then stat -c %a /etc/kubernetes/controller-manager.conf; fi'" tests: bin_op: or test_items: - flag: "644" compare: op: eq value: "644" set: true - flag: "640" compare: op: eq value: "640" set: true - flag: "600" compare: op: eq value: "600" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chmod 644 /etc/kubernetes/controller-manager.conf scored: true - id: 1.4.18 text: "Ensure that the controller-manager.conf file ownership is set to root:root (Scored)" audit: "/bin/sh -c 'if test -e /etc/kubernetes/controller-manager.conf; then stat -c %U:%G /etc/kubernetes/controller-manager.conf; fi'" tests: test_items: - flag: "root:root" compare: op: eq value: "root:root" set: true remediation: | Run the below command (based on the file location on your system) on the master node. For example, chown root:root /etc/kubernetes/controller-manager.conf scored: true - id: 1.5 text: "etcd" checks: - id: 1.5.1 text: "Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)" audit: "ps -ef | grep $etcdbin | grep -v grep" tests: test_items: - flag: "--cert-file" set: true - flag: "--key-file" set: true remediation: | Follow the etcd service documentation and configure TLS encryption. Then, edit the etcd pod specification file $etcdconf on the master node and set the below parameters. --ca-file= --key-file= scored: true - id: 1.5.2 text: "Ensure that the --client-cert-auth argument is set to true (Scored)" audit: "ps -ef | grep $etcdbin | grep -v grep" tests: test_items: - flag: "--client-cert-auth" compare: op: noteq value: false set: true remediation: | Edit the etcd pod specification file $etcdconf on the master node and set the below parameter. --client-cert-auth="true" scored: true - id: 1.5.3 text: "Ensure that the --auto-tls argument is not set to true (Scored)" audit: "ps -ef | grep $etcdbin | grep -v grep" tests: bin_op: or test_items: - flag: "--auto-tls" set: false - flag: "--auto-tls" compare: op: eq value: false remediation: | Edit the etcd pod specification file $etcdconf on the master node and either remove the --auto-tls parameter or set it to false. --auto-tls=false scored: true - id: 1.5.4 text: "Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Scored)" audit: "ps -ef | grep $etcdbin | grep -v grep" tests: bin_op: and test_items: - flag: "--peer-cert-file" set: true - flag: "--peer-key-file" set: true remediation: | Follow the etcd service documentation and configure peer TLS encryption as appropriate for your etcd cluster. Then, edit the etcd pod specification file $etcdconf on the master node and set the below parameters. --peer-client-file= --peer-key-file= scored: true - id: 1.5.5 text: "Ensure that the --peer-client-cert-auth argument is set to true (Scored)" audit: "ps -ef | grep $etcdbin | grep -v grep" tests: test_items: - flag: "--peer-client-cert-auth" compare: op: eq value: true set: true remediation: | Edit the etcd pod specification file $etcdconf on the master node and set the below parameter. --peer-client-cert-auth=true scored: true - id: 1.5.6 text: "Ensure that the --peer-auto-tls argument is not set to true (Scored)" audit: "ps -ef | grep $etcdbin | grep -v grep" tests: bin_op: or test_items: - flag: "--peer-auto-tls" set: false - flag: "--peer-auto-tls" compare: op: eq value: false set: true remediation: | Edit the etcd pod specification file $etcdconf on the master node and either remove the --peer-auto-tls parameter or set it to false. --peer-auto-tls=false scored: true - id: 1.5.7 text: "Ensure that a unique Certificate Authority is used for etcd (Not Scored)" audit: "ps -ef | grep $etcdbin | grep -v grep" type: "manual" tests: test_items: - flag: "--trusted-ca-file" set: true remediation: | [Manual test] Follow the etcd documentation and create a dedicated certificate authority setup for the etcd service. Then, edit the etcd pod specification file $etcdconf on the master node and set the below parameter. --trusted-ca-file= scored: false - id: 1.6 text: "General Security Primitives" checks: - id: 1.6.1 text: "Ensure that the cluster-admin role is only used where required (Not Scored)" type: "manual" remediation: | [Manual test] Remove any unneeded clusterrolebindings : kubectl delete clusterrolebinding [name] scored: false - id: 1.6.2 text: "Create administrative boundaries between resources using namespaces (Not Scored)" type: "manual" remediation: | [Manual test] Follow the documentation and create namespaces for objects in your deployment as you need them. scored: false - id: 1.6.3 text: "Create network segmentation using Network Policies (Not Scored)" type: "manual" remediation: | [Manual test] Follow the documentation and create NetworkPolicy objects as you need them. scored: false - id: 1.6.4 text: "Ensure that the seccomp profile is set to docker/default in your pod definitions (Not Scored)" type: "manual" remediation: | [Manual test] 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 $apiserverconf 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: 1.6.5 text: "Apply Security Context to Your Pods and Containers (Not Scored)" type: "manual" remediation: | [Manual test] 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: 1.6.6 text: "Configure Image Provenance using ImagePolicyWebhook admission controller (Not Scored)" type: "manual" remediation: | [Manual test] Follow the Kubernetes documentation and setup image provenance. scored: false - id: 1.6.7 text: "Configure Network policies as appropriate (Not Scored)" type: "manual" remediation: | [Manual test] Follow the Kubernetes documentation and setup network policies as appropriate. For example, you could create a "default" isolation policy for a Namespace by creating a NetworkPolicy that selects all pods but does not allow any traffic: apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: scored: false - id: 1.6.8 text: "Place compensating controls in the form of PSP and RBAC for privileged containers usage (Not Scored)" type: "manual" remediation: | [Manual test] Follow Kubernetes documentation and setup PSP and RBAC authorization for your cluster. scored: false - id: 1.7 text: "PodSecurityPolicies" checks: - id: 1.7.1 text: "Do not admit privileged containers (Not Scored)" type: "manual" remediation: | [Manual test] Create a PSP as described in the Kubernetes documentation, ensuring that the .spec.privileged field is omitted or set to false. scored: false - id: 1.7.2 text: "Do not admit containers wishing to share the host process ID namespace (Not Scored)" type: "manual" remediation: | [Manual test] Create a PSP as described in the Kubernetes documentation, ensuring that the .spec.hostPID field is omitted or set to false. scored: false - id: 1.7.3 text: "Do not admit containers wishing to share the host IPC namespace (Not Scored)" type: "manual" remediation: | [Manual test] Create a PSP as described in the Kubernetes documentation, ensuring that the .spec.hostIPC field is omitted or set to false. scored: false - id: 1.7.4 text: "Do not admit containers wishing to share the host network namespace (Not Scored)" type: "manual" remediation: | [Manual test] Create a PSP as described in the Kubernetes documentation, ensuring that the .spec.hostNetwork field is omitted or set to false. scored: false - id: 1.7.5 text: "Do not admit containers with allowPrivilegeEscalation (Not Scored)" type: "manual" remediation: | [Manual test] Create a PSP as described in the Kubernetes documentation, ensuring that the .spec.allowPrivilegeEscalation field is omitted or set to false. scored: false - id: 1.7.6 text: "Do not admit root containers (Not Scored)" type: "manual" remediation: | [Manual test] Create a PSP as described in the Kubernetes documentation, ensuring that the .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of UIDs not including 0. scored: false - id: 1.7.7 text: "Do not admit containers with dangerous capabilities (Not Scored)" type: "manual" remediation: | [Manual test] Create a PSP as described in the Kubernetes documentation, ensuring that the .spec.requiredDropCapabilities is set to include either NET_RAW or ALL. scored: false