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