github.com/khulnasoft-lab/kube-bench@v0.2.1-0.20240330183753-9df52345ae58/cfg/rh-1.0/node.yaml (about)

     1  ---
     2  controls:
     3  version: rh-1.0
     4  id: 4
     5  text: "Worker Node Security Configuration"
     6  type: "node"
     7  groups:
     8    - id: 4.1
     9      text: "Worker Node Configuration Files"
    10      checks:
    11        - id: 4.1.1
    12          text: "Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)"
    13          audit: |
    14            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
    15            do
    16              oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /etc/systemd/system/kubelet.service
    17            done 2> /dev/null
    18          use_multiple_values: true
    19          tests:
    20            test_items:
    21              - flag: "permissions"
    22                compare:
    23                  op: bitmask
    24                  value: "644"
    25          remediation: |
    26            By default, the kubelet service file has permissions of 644.
    27          scored: true
    28  
    29        - id: 4.1.2
    30          text: "Ensure that the kubelet service file ownership is set to root:root (Automated)"
    31          audit: |
    32            # Should return root:root for each node
    33            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
    34            do
    35              oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /etc/systemd/system/kubelet.service
    36            done 2> /dev/null
    37          use_multiple_values: true
    38          tests:
    39            test_items:
    40              - flag: root:root
    41          remediation: |
    42            By default, the kubelet service file has ownership of root:root.
    43          scored: true
    44  
    45        - id: 4.1.3
    46          text: "If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)"
    47          audit: |
    48            for i in $(oc get pods -n openshift-sdn -l app=sdn -oname)
    49            do
    50              oc exec -n openshift-sdn $i -- stat -Lc "$i %n permissions=%a" /config/kube-proxy-config.yaml
    51            done 2> /dev/null
    52          use_multiple_values: true
    53          tests:
    54            bin_op: or
    55            test_items:
    56              - flag: "permissions"
    57                set: true
    58                compare:
    59                  op: bitmask
    60                  value: "644"
    61          remediation: |
    62            None needed.
    63          scored: false
    64  
    65        - id: 4.1.4
    66          text: "Ensure that the proxy kubeconfig file ownership is set to root:root (Manual)"
    67          audit: |
    68            for i in $(oc get pods -n openshift-sdn -l app=sdn -oname)
    69            do
    70              oc exec -n openshift-sdn $i -- stat -Lc "$i %n %U:%G" /config/kube-proxy-config.yaml
    71            done 2> /dev/null
    72          use_multiple_values: true
    73          tests:
    74            bin_op: or
    75            test_items:
    76              - flag: root:root
    77          remediation: |
    78            None required. The configuration is managed by OpenShift operators.
    79          scored: false
    80  
    81        - id: 4.1.5
    82          text: "Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Manual)"
    83          audit: |
    84            # Check permissions
    85            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
    86            do
    87              oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /etc/kubernetes/kubelet.conf
    88            done 2> /dev/null
    89          use_multiple_values: true
    90          tests:
    91            test_items:
    92              - flag: "permissions"
    93                compare:
    94                  op: bitmask
    95                  value: "644"
    96          remediation: |
    97            None required.
    98          scored: false
    99  
   100        - id: 4.1.6
   101          text: "Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)"
   102          audit: |
   103            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   104            do
   105              oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /etc/kubernetes/kubelet.conf
   106            done 2> /dev/null
   107          use_multiple_values: true
   108          tests:
   109            test_items:
   110              - flag: root:root
   111          remediation: |
   112            None required.
   113          scored: false
   114  
   115        - id: 4.1.7
   116          text: "Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Automated)"
   117          audit: |
   118            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   119            do
   120              oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /etc/kubernetes/kubelet-ca.crt
   121            done 2> /dev/null
   122          use_multiple_values: true
   123          tests:
   124            test_items:
   125              - flag: "permissions"
   126                compare:
   127                  op: bitmask
   128                  value: "644"
   129          remediation: |
   130            None required.
   131          scored: true
   132  
   133        - id: 4.1.8
   134          text: "Ensure that the client certificate authorities file ownership is set to root:root (Automated)"
   135          audit: |
   136            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   137            do
   138              oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /etc/kubernetes/kubelet-ca.crt
   139            done 2> /dev/null
   140          use_multiple_values: true
   141          tests:
   142            test_items:
   143              - flag: root:root
   144          remediation: |
   145            None required.
   146          scored: true
   147  
   148        - id: 4.1.9
   149          text: "Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)"
   150          audit: |
   151            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   152            do
   153              oc debug node/${node} -- chroot /host stat -c "$node %n permissions=%a" /var/lib/kubelet/kubeconfig
   154            done 2> /dev/null
   155          use_multiple_values: true
   156          tests:
   157            test_items:
   158              - flag: "permissions"
   159                compare:
   160                  op: bitmask
   161                  value: "644"
   162          remediation: |
   163            None required.
   164          scored: true
   165  
   166        - id: 4.1.10
   167          text: "Ensure that the kubelet configuration file ownership is set to root:root (Automated)"
   168          audit: |
   169            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   170            do
   171              oc debug node/${node} -- chroot /host stat -c "$node %n %U:%G" /var/lib/kubelet/kubeconfig
   172            done 2> /dev/null
   173          use_multiple_values: true
   174          tests:
   175            test_items:
   176              - flag: root:root
   177          remediation: |
   178            None required.
   179          scored: true
   180  
   181    - id: 4.2
   182      text: "Kubelet"
   183      checks:
   184        - id: 4.2.1
   185          text: "Ensure that the --anonymous-auth argument is set to false (Automated)"
   186          audit: |
   187            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   188            do
   189              oc debug node/${node} -- chroot /host grep -B4 -A1 anonymous /etc/kubernetes/kubelet.conf
   190            done
   191          use_multiple_values: true
   192          tests:
   193            test_items:
   194              - flag: "enabled: true"
   195                set: false
   196          remediation: |
   197            Follow the instructions in the documentation to create a Kubelet config CRD
   198            and set the anonymous-auth is set to false.
   199          scored: true
   200  
   201        - id: 4.2.2
   202          text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Manual)"
   203          type: manual
   204          # Takes a lot of time for connection to fail and
   205          audit: |
   206            POD=$(oc -n openshift-kube-apiserver get pod -l app=openshift-kube-apiserver -o jsonpath='{.items[0].metadata.name}')
   207            TOKEN=$(oc whoami -t)
   208            for name in $(oc get nodes -ojsonpath='{.items[*].metadata.name}')
   209            do
   210              oc exec -n openshift-kube-apiserver $POD -- curl -sS https://172.25.0.1/api/v1/nodes/$name/proxy/configz -k -H "Authorization:Bearer $TOKEN" | jq -r '.kubeletconfig.authorization.mode'
   211            done
   212          use_multiple_values: true
   213          tests:
   214            test_items:
   215              - flag: "Connection timed out"
   216          remediation: |
   217            None required. Unauthenticated/Unauthorized users have no access to OpenShift nodes.
   218          scored: false
   219  
   220        - id: 4.2.3
   221          text: "Ensure that the --client-ca-file argument is set as appropriate (Automated)"
   222          audit: |
   223            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   224            do
   225              oc debug node/${node} -- chroot /host grep clientCAFile /etc/kubernetes/kubelet.conf
   226            done 2> /dev/null
   227          use_multiple_values: true
   228          tests:
   229            test_items:
   230              - flag: "clientCAFile"
   231                compare:
   232                  op: eq
   233                  value: "/etc/kubernetes/kubelet-ca.crt"
   234          remediation: |
   235            None required. Changing the clientCAFile value is unsupported.
   236          scored: true
   237  
   238        - id: 4.2.4
   239          text: "Verify that the read only port is not used or is set to 0 (Automated)"
   240          audit: |
   241            echo `oc -n openshift-kube-apiserver get cm kube-apiserver-pod -o yaml | grep --color read-only-port` 2> /dev/null
   242            echo `oc -n openshift-kube-apiserver get cm config -o yaml | grep --color "read-only-port"` 2> /dev/null
   243          tests:
   244            bin_op: or
   245            test_items:
   246              - flag: "read-only-port"
   247                compare:
   248                  op: has
   249                  value: "[\"0\"]"
   250              - flag: "read-only-port"
   251                set: false
   252          remediation: |
   253            In earlier versions of OpenShift 4, the read-only-port argument is not used.
   254            Follow the instructions in the documentation to create a Kubelet config CRD
   255            and set the --read-only-port is set to 0.
   256          scored: true
   257  
   258        - id: 4.2.5
   259          text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)"
   260          audit: |
   261            # Should return 1 for each node
   262            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   263            do
   264              oc debug node/${node} -- chroot /host ps -ef | grep kubelet | grep streaming-connection-idle-timeout
   265              echo exit_code=$?
   266            done 2>/dev/null
   267            # Should return 1 for each node
   268            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   269            do
   270              oc debug node/${node} -- chroot /host grep streamingConnectionIdleTimeout /etc/kubernetes/kubelet.conf
   271              echo exit_code=$?
   272            done 2>/dev/null
   273          use_multiple_values: true
   274          tests:
   275            bin_op: or
   276            test_items:
   277              - flag: --streaming-connection-idle-timeout
   278                compare:
   279                  op: noteq
   280                  value: 0
   281              - flag: "exit_code"
   282                compare:
   283                  op: eq
   284                  value: 1
   285          remediation: |
   286            Follow the instructions in the documentation to create a Kubelet config CRD and set
   287            the --streaming-connection-idle-timeout to the desired value. Do not set the value to 0.
   288          scored: true
   289  
   290        - id: 4.2.6
   291          text: "Ensure that the --protect-kernel-defaults argument is not set (Manual)"
   292          audit: |
   293            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}');
   294            do
   295              oc debug node/${node} -- chroot /host more /etc/kubernetes/kubelet.conf;
   296            done
   297          tests:
   298            test_items:
   299              - flag: protectKernelDefaults
   300                set: false
   301          remediation: |
   302            None required. The OpenShift 4 kubelet modifies the system tunable;
   303            using the protect-kernel-defaults flag will cause the kubelet to fail on start if the tunables
   304            don't match the kubelet configuration and the OpenShift node will fail to start.
   305          scored: false
   306  
   307        - id: 4.2.7
   308          text: "Ensure that the --make-iptables-util-chains argument is set to true (Manual)"
   309          audit: |
   310            /bin/bash
   311            flag=make-iptables-util-chains
   312            opt=makeIPTablesUtilChains
   313            # look at each machineconfigpool
   314            while read -r pool nodeconfig; do
   315              # true by default
   316              value='true'
   317              # first look for the flag
   318              oc get machineconfig $nodeconfig -o json | jq -r '.spec.config.systemd[][] | select(.name=="kubelet.service") | .contents' | sed -n "/^ExecStart=/,/^\$/ { /^\\s*--$flag=false/ q 100 }"
   319              # if the above command exited with 100, the flag was false
   320              [ $? == 100 ] && value='false'
   321              # now look in the yaml KubeletConfig
   322              yamlconfig=$(oc get machineconfig $nodeconfig -o json | jq -r '.spec.config.storage.files[] | select(.path=="/etc/kubernetes/kubelet.conf") | .contents.source ' | sed 's/^data:,//' | while read; do echo -e ${REPLY//%/\\x}; done)
   323              echo "$yamlconfig" | sed -n "/^$opt:\\s*false\\s*$/ q 100"
   324              [ $? == 100 ] && value='false'
   325              echo "Pool $pool has $flag ($opt) set to $value"
   326            done < <(oc get machineconfigpools -o json | jq -r '.items[] | select(.status.machineCount>0) | .metadata.name + " " + .spec.configuration.name')
   327          use_multiple_values: true
   328          tests:
   329            test_items:
   330              - flag: "set to true"
   331          remediation: |
   332            None required. The --make-iptables-util-chains argument is set to true by default.
   333          scored: false
   334  
   335        - id: 4.2.8
   336          text: "Ensure that the --hostname-override argument is not set (Manual)"
   337          audit: |
   338            echo `oc get machineconfig 01-worker-kubelet -o yaml | grep hostname-override`
   339            echo `oc get machineconfig 01-master-kubelet -o yaml | grep hostname-override`
   340          tests:
   341            test_items:
   342              - flag: hostname-override
   343                set: false
   344          remediation: |
   345            By default, --hostname-override argument is not set.
   346          scored: false
   347  
   348        - id: 4.2.9
   349          text: "Ensure that the kubeAPIQPS [--event-qps] argument is set to 0 or a level which ensures appropriate event capture (Manual)"
   350          audit: |
   351            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}');
   352            do
   353              oc debug node/${node} -- chroot /host more /etc/kubernetes/kubelet.conf;
   354            done
   355            oc get machineconfig 01-worker-kubelet -o yaml | grep --color kubeAPIQPS%3A%2050
   356            oc get machineconfig 01-master-kubelet -o yaml | grep --color kubeAPIQPS%3A%2050
   357          type: "manual"
   358          remediation: |
   359            Follow the documentation to edit kubelet parameters
   360            https://docs.openshift.com/container-platform/4.5/scalability_and_performance/recommended-host-practices.html#create-a-kubeletconfig-crd-to-edit-kubelet-parameters
   361            KubeAPIQPS: <QPS>
   362          scored: false
   363  
   364        - id: 4.2.10
   365          text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)"
   366          audit: |
   367            oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data["config.yaml"]' | jq '.kubeletClientInfo'
   368          tests:
   369            bin_op: and
   370            test_items:
   371              - flag: "/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.crt"
   372              - flag: "/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.key"
   373          remediation: |
   374            OpenShift automatically manages TLS authentication for the API server communication with the node/kublet.
   375            This is not configurable.
   376          scored: true
   377  
   378        - id: 4.2.11
   379          text: "Ensure that the --rotate-certificates argument is not set to false (Manual)"
   380          audit: |
   381            #Verify the rotateKubeletClientCertificate feature gate is not set to false
   382            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   383            do
   384              oc debug node/${node} -- chroot /host cat /etc/kubernetes/kubelet.conf | grep RotateKubeletClientCertificate
   385            done 2> /dev/null
   386            # Verify the rotateCertificates argument is set to true
   387            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   388            do
   389              oc debug node/${node} -- chroot host grep rotate /etc/kubernetes/kubelet.conf;
   390            done 2> /dev/null
   391          use_multiple_values: true
   392          tests:
   393            bin_op: or
   394            test_items:
   395              - flag: rotateCertificates
   396                compare:
   397                  op: eq
   398                  value: true
   399              - flag: rotateKubeletClientCertificates
   400                compare:
   401                  op: noteq
   402                  value: false
   403              - flag: rotateKubeletClientCertificates
   404                set: false
   405          remediation: |
   406            None required.
   407          scored: false
   408  
   409        - id: 4.2.12
   410          text: "Verify that the RotateKubeletServerCertificate argument is set to true (Manual)"
   411          audit: |
   412            #Verify the rotateKubeletServerCertificate feature gate is on
   413            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}');
   414            do
   415              oc debug node/${node} -- chroot /host grep RotateKubeletServerCertificate /etc/kubernetes/kubelet.conf;
   416            done 2> /dev/null
   417            # Verify the rotateCertificates argument is set to true
   418            for node in $(oc get nodes -o jsonpath='{.items[*].metadata.name}')
   419            do
   420              oc debug node/${node} -- chroot host grep rotate /etc/kubernetes/kubelet.conf;
   421            done 2> /dev/null
   422          use_multiple_values: true
   423          tests:
   424            bin_op: or
   425            test_items:
   426              - flag: RotateKubeletServerCertificate
   427                compare:
   428                  op: eq
   429                  value: true
   430              - flag: rotateCertificates
   431                compare:
   432                  op: eq
   433                  value: true
   434          remediation: |
   435            By default, kubelet server certificate rotation is disabled.
   436          scored: false
   437  
   438        - id: 4.2.13
   439          text: "Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)"
   440          audit: |
   441            # needs verification
   442            # verify cipher suites
   443            oc describe --namespace=openshift-ingress-operator ingresscontroller/default
   444            oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo
   445            oc get openshiftapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo
   446            oc get cm -n openshift-authentication v4-0-config-system-cliconfig -o jsonpath='{.data.v4\-0\-config\-system\-cliconfig}' | jq .servingInfo
   447            #check value for tlsSecurityProfile; null is returned if default is used
   448            oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.tlsSecurityProfile
   449          type: manual
   450          remediation: |
   451            Follow the directions above and in the OpenShift documentation to configure the tlsSecurityProfile.
   452            Configuring Ingress
   453          scored: false