> ## 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 Anonymous Auth Argument Set To False

### More Info:

The kubelet --anonymous-auth argument must be set to false. Allowing anonymous authentication lets unauthenticated requests reach the kubelet API and gain access to the node.

### Risk Level

Critical

### 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, open the kubelet systemd drop‑in config for editing:
           ```bash theme={null}
           sudo vi /etc/systemd/system/kubelet.service.d/00-default.conf
           ```

        2. In the `ExecStart=` line, ensure the `--anonymous-auth` flag is present and set to false (add it if missing), for example:
           ```ini theme={null}
           ExecStart=... --anonymous-auth=false ...
           ```

        3. If the kubelet instead reads options from `/etc/kubernetes/kubelet-config.json`, open that file and set the `authentication.anonymous.enabled` field to `false` (create the hierarchy if needed):
           ```bash theme={null}
           sudo vi /etc/kubernetes/kubelet-config.json
           ```
           Example snippet:
           ```json theme={null}
           {
             "authentication": {
               "anonymous": {
                 "enabled": false
               }
             }
           }
           ```

        4. Reload systemd configuration on the same worker node:
           ```bash theme={null}
           sudo systemctl daemon-reload
           ```

        5. Restart the kubelet on the same worker node and ensure it is running:
           ```bash theme={null}
           sudo systemctl restart kubelet.service
           sudo systemctl status kubelet -l
           ```

        6. Verify on the same worker node that the kubelet process is running with `--anonymous-auth=false`:
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```
           Confirm the output contains `--anonymous-auth=false` and no conflicting `--anonymous-auth=true`.
      </Accordion>

      <Accordion title="Using kubectl">
        `kubectl` cannot modify kubelet process flags or host-level config files, so this setting cannot be fixed via the Kubernetes API. To remediate, you must change the kubelet configuration on every worker node (for example in `/etc/systemd/system/kubelet.service.d/00-default.conf` and `/etc/kubernetes/kubelet-config.json`), as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Harden kubelet anonymous authentication on all worker nodes
        # CIS OKE 3.2.1 – Ensure that the --anonymous-auth argument is set to false
        #
        # Usage:
        #   1) Put worker node hostnames/IPs into /root/worker-nodes.txt (one per line), or
        #      set WORKER_NODES env var as a space‑separated list.
        #   2) Run this script from an admin machine that has SSH access as root (or via sudo)
        #      to every worker node.
        #   3) Script is idempotent and safe to re‑run.
        #

        set -euo pipefail

        WORKER_NODES_FILE="/root/worker-nodes.txt"

        if [[ -z "${WORKER_NODES:-}" ]]; then
          if [[ -f "$WORKER_NODES_FILE" ]]; then
            # shellcheck disable=SC2002
            WORKER_NODES="$(cat "$WORKER_NODES_FILE" | awk 'NF')"
          else
            echo "ERROR: No worker nodes specified."
            echo "Set WORKER_NODES env var (space‑separated) or create $WORKER_NODES_FILE."
            exit 1
          fi
        fi

        if [[ -z "$WORKER_NODES" ]]; then
          echo "ERROR: Worker node list is empty."
          exit 1
        fi

        echo "Target worker nodes:"
        for n in $WORKER_NODES; do echo "  - $n"; done
        echo

        REMOTE_SCRIPT='
        set -euo pipefail

        CONFIG_FILE="/etc/kubernetes/kubelet-config.json"
        SYSTEMD_DIR="/etc/systemd/system/kubelet.service.d"
        SYSTEMD_DROPIN="$SYSTEMD_DIR/00-default.conf"

        echo "[INFO] Running on $(hostname)"

        if [[ ! -f "$SYSTEMD_DROPIN" ]]; then
          echo "[INFO] $SYSTEMD_DROPIN not found – creating drop‑in directory and file."
          mkdir -p "$SYSTEMD_DIR"
          cat > "$SYSTEMD_DROPIN" <<EOF
        [Service]
        ExecStart=
        ExecStart=/usr/bin/kubelet
        EOF
        fi

        if ! grep -q "ExecStart=" "$SYSTEMD_DROPIN"; then
          echo "[INFO] No ExecStart line in $SYSTEMD_DROPIN – appending a basic ExecStart."
          printf "\n[Service]\nExecStart=/usr/bin/kubelet\n" >> "$SYSTEMD_DROPIN"
        fi

        TMP_FILE="$(mktemp)"
        trap "rm -f \"$TMP_FILE\"" EXIT

        awk "
          /^ExecStart=/ {
            line=\$0
            # Remove any existing --anonymous-auth flags
            gsub(/--anonymous-auth(=([^ \\\\]+))?/, \"\", line)
            # Ensure a single space between args
            sub(/  +/, \" \", line)
            # Ensure we end with a space before appending
            if (line !~ / $/) { line=line\" \" }
            # Append the desired flag
            line=line\"--anonymous-auth=false\"
            print line
            next
          }
          { print }
        " "$SYSTEMD_DROPIN" > "$TMP_FILE"

        if ! cmp -s "$TMP_FILE" "$SYSTEMD_DROPIN"; then
          echo "[INFO] Updating $SYSTEMD_DROPIN with --anonymous-auth=false"
          cp "$SYSTEMD_DROPIN" "$SYSTEMD_DROPIN.bak.$(date +%s)"
          cp "$TMP_FILE" "$SYSTEMD_DROPIN"
        else
          echo "[INFO] $SYSTEMD_DROPIN already enforces --anonymous-auth=false"
        fi

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

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

        echo "[INFO] Verifying kubelet process flags for --anonymous-auth=false:"
        /bin/ps -fC kubelet || true
        if /bin/ps -fC kubelet | grep -q -- "--anonymous-auth=false"; then
          echo "[INFO] SUCCESS: kubelet is running with --anonymous-auth=false"
        else
          echo "[WARN] kubelet process does not show --anonymous-auth=false – manual review required."
        fi

        echo
        '

        for NODE in $WORKER_NODES; do
          echo "===== Processing worker node: $NODE ====="
          ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "root@$NODE" "$REMOTE_SCRIPT"
        done

        echo "All nodes processed."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
