> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubelet Only Makes Use Of Strong Cryptographic Ciphers

### More Info:

Restricting tlsCipherSuites to strong ciphers prevents the kubelet from negotiating weak or deprecated cryptographic algorithms. This hardens the confidentiality of kubelet TLS connections.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, back up the existing kubelet config and (if present) the systemd drop-in:
           ```bash theme={null}
           sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%s) || true
           sudo cp -a /etc/systemd/system/kubelet.service.d/10-kubeadm.conf /etc/systemd/system/kubelet.service.d/10-kubeadm.conf.bak.$(date +%s) 2>/dev/null || true
           ```

        2. On every worker node, edit `/var/lib/kubelet/config.yaml` to define strong ciphers in the Kubelet config file (create or replace the `tlsCipherSuites` section as needed):
           ```bash theme={null}
           sudo sed -i '/^tlsCipherSuites:/,$d' /var/lib/kubelet/config.yaml
           sudo tee -a /var/lib/kubelet/config.yaml >/dev/null <<'EOF'
           ```

        tlsCipherSuites:

        * 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
          EOF

        ````

        3. On every worker node, if the kubelet is configured via flags, ensure `--tls-cipher-suites` is set in the systemd drop-in (adjust this file only if your kubelet actually uses it):  
        ```bash
        if [ -f /etc/systemd/system/kubelet.service.d/10-kubeadm.conf ]; then
          sudo sed -i '/--tls-cipher-suites=/d' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
          sudo sed -i 's#^\(ExecStart=.*kubelet\b\)\(.*\)$#\1\2 --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#' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
        fi
        ````

        4. On every worker node, reload systemd and restart the kubelet (this will disrupt kubelet on the node briefly, so do this node by node):
           ```bash theme={null}
           sudo systemctl daemon-reload
           sudo systemctl restart kubelet.service
           ```

        5. On every worker node, confirm the kubelet process is running with the desired cipher suites flag (if you use flags) and that it has restarted successfully:
           ```bash theme={null}
           /bin/ps -fC kubelet
           sudo systemctl status kubelet.service --no-pager
           ```

        6. Optionally, on every worker node, confirm that either the config file or the flag now specifies only strong ciphers:
           ```bash theme={null}
           grep -A10 '^tlsCipherSuites:' /var/lib/kubelet/config.yaml || true
           /bin/ps -fC kubelet | grep -- '--tls-cipher-suites' || true
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify kubelet host-level configuration such as `/var/lib/kubelet/config.yaml` or systemd units on worker nodes. To remediate this finding, you must change the kubelet configuration directly on each worker node; follow the guidance in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Harden kubelet TLS cipher suites on every worker node.
        # Usage: run as root on each worker node (or via SSH/Ansible).
        #

        set -euo pipefail

        CIPHERS="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"

        KUBELET_CONFIG_FILE="/var/lib/kubelet/config.yaml"
        KUBELET_SYSTEMD_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"

        echo "==> Hardening kubelet TLS cipher suites on node: $(hostname)"

        # Ensure jq and yq are available if needed
        need_cmd() {
          command -v "$1" >/dev/null 2>&1 || {
            echo "ERROR: required command '$1' not found in PATH" >&2
            exit 1
          }
        }

        # Prefer config file if it exists; otherwise fall back to systemd flag
        if [ -f "$KUBELET_CONFIG_FILE" ]; then
          echo "==> Detected kubelet config file at $KUBELET_CONFIG_FILE"

          need_cmd yq

          # Backup once per run if not already backed up in this session
          BACKUP="${KUBELET_CONFIG_FILE}.$(date +%Y%m%d%H%M%S).bak"
          cp -p "$KUBELET_CONFIG_FILE" "$BACKUP"
          echo "    Backup created: $BACKUP"

          # Idempotently set tlsCipherSuites
          TMP_FILE="$(mktemp)"
          yq -y ".tlsCipherSuites = [\"${CIPHERS//,/\",\"}\"]" "$KUBELET_CONFIG_FILE" > "$TMP_FILE"
          chmod --reference="$KUBELET_CONFIG_FILE" "$TMP_FILE"
          mv "$TMP_FILE" "$KUBELET_CONFIG_FILE"

          echo "    Updated tlsCipherSuites in $KUBELET_CONFIG_FILE"

        else
          echo "==> No kubelet config file at $KUBELET_CONFIG_FILE, using systemd flags"

          if [ ! -f "$KUBELET_SYSTEMD_DROPIN" ]; then
            echo "ERROR: $KUBELET_SYSTEMD_DROPIN not found; cannot set --tls-cipher-suites flag automatically." >&2
            echo "Create the file and define kubelet ExecStart with the desired --tls-cipher-suites." >&2
            exit 1
          fi

          # Backup
          BACKUP="${KUBELET_SYSTEMD_DROPIN}.$(date +%Y%m%d%H%M%S).bak"
          cp -p "$KUBELET_SYSTEMD_DROPIN" "$BACKUP"
          echo "    Backup created: $BACKUP"

          # Idempotently ensure --tls-cipher-suites flag is present with desired value
          TMP_FILE="$(mktemp)"
          # For simplicity and safety, replace any existing --tls-cipher-suites=... with the desired value,
          # or append it if missing, only on the ExecStart line.
          awk -v ciphers="$CIPHERS" '
            /^ExecStart=/ {
              # Remove existing --tls-cipher-suites=... occurrences
              gsub(/--tls-cipher-suites=[^ ]+/, "")
              # Ensure a single space before appending the flag
              sub(/[[:space:]]*$/,"")
              print $0 " --tls-cipher-suites=" ciphers
              next
            }
            { print }
          ' "$KUBELET_SYSTEMD_DROPIN" > "$TMP_FILE"

          chmod --reference="$KUBELET_SYSTEMD_DROPIN" "$TMP_FILE"
          mv "$TMP_FILE" "$KUBELET_SYSTEMD_DROPIN"

          echo "    Updated --tls-cipher-suites in $KUBELET_SYSTEMD_DROPIN"
        fi

        echo "==> Restarting kubelet (this will briefly disrupt workloads on this node)"
        systemctl daemon-reload
        systemctl restart kubelet.service

        sleep 3

        echo "==> Verification: kubelet process and configuration"

        # 1) Show kubelet process (as per audit command)
        echo "---- kubelet process (ps -fC kubelet) ----"
        if ! /bin/ps -fC kubelet; then
          echo "ERROR: kubelet process not found after restart." >&2
          exit 1
        fi

        # 2) Verify effective setting depending on method
        if [ -f "$KUBELET_CONFIG_FILE" ]; then
          need_cmd yq
          echo "---- tlsCipherSuites from $KUBELET_CONFIG_FILE ----"
          yq '.tlsCipherSuites' "$KUBELET_CONFIG_FILE"
        else
          echo "---- ExecStart from $KUBELET_SYSTEMD_DROPIN ----"
          sed -n 's/^ExecStart=/ExecStart=/p' "$KUBELET_SYSTEMD_DROPIN"
        fi

        echo "==> Completed on node: $(hostname)"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
