> ## 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 Client CA File Argument Set As Appropriate

### More Info:

The kubelet --client-ca-file argument should be set to enable client certificate authentication. Without a client CA, the kubelet cannot verify the identity of API clients.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, confirm the current kubelet process arguments:
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```
           Check whether a `--client-ca-file` argument is present and whether it points to the intended CA (for example `/etc/kubernetes/ca.crt`).

        2. On every worker node, ensure the client CA file exists and is readable by kubelet (adjust the source path if your CA is elsewhere):
           ```bash theme={null}
           ls -l /etc/kubernetes/ca.crt || sudo cp /etc/kubernetes/pki/ca.crt /etc/kubernetes/ca.crt
           sudo chown root:root /etc/kubernetes/ca.crt
           sudo chmod 644 /etc/kubernetes/ca.crt
           ```

        3. On every worker node, edit the kubelet systemd drop-in to add the `--client-ca-file` argument:
           ```bash theme={null}
           sudo sed -i '/KUBELET_KUBEADM_ARGS=/d' /etc/systemd/system/kubelet.service.d/00-default.conf
           ```
           Then open the file and ensure the `ExecStart` or environment line includes the flag, for example:
           ```bash theme={null}
           sudo vi /etc/systemd/system/kubelet.service.d/00-default.conf
           ```
           Add or adjust so it contains:
           ```ini theme={null}
           [Service]
           Environment="KUBELET_KUBEADM_ARGS=--client-ca-file=/etc/kubernetes/ca.crt"
           ```
           or, if `ExecStart` uses inline flags, append:
           ```ini theme={null}
           ExecStart=... --client-ca-file=/etc/kubernetes/ca.crt
           ```

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

        5. On every worker node, confirm kubelet is healthy:
           ```bash theme={null}
           sudo systemctl status kubelet -l
           ```

        6. On every worker node, verify that the `--client-ca-file` argument is now set correctly:
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```
           Confirm the output shows `--client-ca-file=/etc/kubernetes/ca.crt` (or your chosen CA path) in the kubelet command line.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot configure the kubelet’s `--client-ca-file` flag or edit `/etc/kubernetes/kubelet-config.json`, because these are host-level settings managed on each worker node (systemd units and config files). To remediate this finding, make the changes directly on every worker node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Remediates CIS OKE 3.2.3:
        # Ensure kubelet is started with --client-ca-file=/etc/kubernetes/ca.crt
        #
        # Run on: every worker node (as root)
        # Safe to re-run (idempotent).

        set -euo pipefail

        KUBELET_DROPIN_DIR="/etc/systemd/system/kubelet.service.d"
        KUBELET_DROPIN_FILE="${KUBELET_DROPIN_DIR}/00-default.conf"
        CLIENT_CA_ARG="--client-ca-file=/etc/kubernetes/ca.crt"
        CA_FILE="/etc/kubernetes/ca.crt"

        echo "[INFO] Starting kubelet --client-ca-file remediation"

        if [[ "$(id -u)" -ne 0 ]]; then
          echo "[ERROR] This script must be run as root."
          exit 1
        fi

        if [[ ! -f "${KUBELET_DROPIN_FILE}" ]]; then
          echo "[ERROR] ${KUBELET_DROPIN_FILE} not found. Adjust path or create drop-in as per your distro."
          exit 1
        fi

        if [[ ! -f "${CA_FILE}" ]]; then
          echo "[ERROR] ${CA_FILE} not found. Create or place the correct client CA certificate before rerunning."
          exit 1
        fi

        echo "[INFO] Ensuring kubelet drop-in directory exists: ${KUBELET_DROPIN_DIR}"
        mkdir -p "${KUBELET_DROPIN_DIR}"

        echo "[INFO] Ensuring ${KUBELET_DROPIN_FILE} contains ${CLIENT_CA_ARG}"

        # Backup once
        if [[ ! -f "${KUBELET_DROPIN_FILE}.cis-3.2.3.bak" ]]; then
          cp "${KUBELET_DROPIN_FILE}" "${KUBELET_DROPIN_FILE}.cis-3.2.3.bak"
        fi

        # Normalize file and ensure Environment line with KUBELET_EXTRA_ARGS includes the arg
        tmpfile="$(mktemp)"
        trap 'rm -f "${tmpfile}"' EXIT

        # Read current content
        cat "${KUBELET_DROPIN_FILE}" > "${tmpfile}"

        # Remove any duplicate --client-ca-file arguments
        sed -i 's/--client-ca-file=[^ ]*//g' "${tmpfile}"

        # Ensure there is an Environment line for KUBELET_EXTRA_ARGS
        if ! grep -q 'Environment=.*KUBELET_EXTRA_ARGS' "${tmpfile}"; then
          # Add a basic Environment line; adapt if your distro uses a different pattern
          echo 'Environment="KUBELET_EXTRA_ARGS="' >> "${tmpfile}"
        fi

        # Append the CLIENT_CA_ARG to KUBELET_EXTRA_ARGS, preserving existing content
        # Works whether Environment= or EnvironmentContains double quotes
        perl -pi -e '
          if (/^Environment=.*KUBELET_EXTRA_ARGS/) {
            s/"$/ '"${CLIENT_CA_ARG}"'"/ if ! /'"${CLIENT_CA_ARG//\//\\/}"'/;
          }
        ' "${tmpfile}"

        # Install updated file if changed
        if ! cmp -s "${tmpfile}" "${KUBELET_DROPIN_FILE}"; then
          echo "[INFO] Updating ${KUBELET_DROPIN_FILE}"
          cp "${tmpfile}" "${KUBELET_DROPIN_FILE}"
        else
          echo "[INFO] ${KUBELET_DROPIN_FILE} already contains ${CLIENT_CA_ARG}"
        fi

        echo "[INFO] Reloading systemd and restarting kubelet (this will restart the kubelet on this node)"
        systemctl daemon-reload
        systemctl restart kubelet.service

        echo "[INFO] Checking kubelet status"
        systemctl status kubelet -l --no-pager || true

        echo "[INFO] Verifying kubelet is running with ${CLIENT_CA_ARG}"
        if /bin/ps -fC kubelet | grep -q -- "${CLIENT_CA_ARG}"; then
          echo "[SUCCESS] kubelet is running with ${CLIENT_CA_ARG}"
        else
          echo "[FAIL] kubelet is NOT running with ${CLIENT_CA_ARG}"
          echo "[INFO] Full kubelet command line:"
          /bin/ps -fC kubelet || true
          exit 2
        fi
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
