> ## 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:

Anonymous authentication allows unauthenticated requests to reach the kubelet API. Setting --anonymous-auth to false ensures every request must be authenticated.

### Risk Level

Critical

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every control plane node, confirm the current kube-apiserver arguments:
           ```bash theme={null}
           ps -ef | grep kube-apiserver | grep -v grep
           ```

        2. On every control plane node, back up the existing manifest:
           ```bash theme={null}
           sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
           ```

        3. Edit the kube-apiserver static pod manifest to set anonymous auth to false:
           ```bash theme={null}
           sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
           ```
           In the `containers:` → `- name: kube-apiserver` → `command:` list, ensure there is a line exactly like:
           ```yaml theme={null}
           - --anonymous-auth=false
           ```
           If a `--anonymous-auth=` flag already exists with a different value, change it to `false`. Save and exit.\
           Note: updating this file will cause the kube-apiserver static pod to restart automatically.

        4. (If flags are passed via `args:` instead of `command:`) ensure the flag is present or corrected under `args:`:
           ```yaml theme={null}
           args:
             - kube-apiserver
             - --anonymous-auth=false
           ```

        5. Wait for the kube-apiserver pod to restart and become Ready (from any machine with kubectl access):
           ```bash theme={null}
           kubectl get pods -n kube-system -l component=kube-apiserver -w
           ```

        6. Verify on every control plane node that the process now includes `--anonymous-auth=false`:
           ```bash theme={null}
           ps -ef | grep kube-apiserver | grep -v grep | grep -- '--anonymous-auth=false'
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify kube-apiserver process flags or static pod manifests, so it cannot be used to set `--anonymous-auth=false` for this control-plane component. To address this finding, you must edit `/etc/kubernetes/manifests/kube-apiserver.yaml` directly on every control plane node; follow the steps in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Purpose: Ensure kube-apiserver is started with --anonymous-auth=false
        # Scope:   Run on every control plane node (with root privileges)
        #
        # Idempotent: safe to re-run; only updates when needed.

        set -euo pipefail

        APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
        BACKUP_DIR="/etc/kubernetes/manifests/backup-$(date +%Y%m%d)"
        FLAG="--anonymous-auth="
        DESIRED_VALUE="false"

        echo "[INFO] Ensuring ${FLAG}${DESIRED_VALUE} on this control plane node"

        if [[ $EUID -ne 0 ]]; then
          echo "[ERROR] This script must be run as root." >&2
          exit 1
        fi

        if [[ ! -f "${APISERVER_MANIFEST}" ]]; then
          echo "[ERROR] kube-apiserver manifest not found at ${APISERVER_MANIFEST}" >&2
          exit 1
        fi

        mkdir -p "${BACKUP_DIR}"

        # Backup manifest once per day (idempotent by path+date)
        BACKUP_FILE="${BACKUP_DIR}/kube-apiserver.yaml"
        if [[ ! -f "${BACKUP_FILE}" ]]; then
          cp "${APISERVER_MANIFEST}" "${BACKUP_FILE}"
          echo "[INFO] Backup created at ${BACKUP_FILE}"
        else
          echo "[INFO] Backup already exists at ${BACKUP_FILE}"
        fi

        TMP_FILE="$(mktemp)"

        # Normalize file with a trailing newline to make sed safer
        # 1. If --anonymous-auth is present, force it to false.
        # 2. If not present, add it as a separate arg line under 'command:' for kube-apiserver.
        if grep -qE '\s--anonymous-auth=' "${APISERVER_MANIFEST}"; then
          echo "[INFO] Existing --anonymous-auth flag found; updating to ${DESIRED_VALUE} if needed"
          sed -E "s/(^(\s*-\s*|\s*)--anonymous-auth=)(true|false)/\1${DESIRED_VALUE}/" \
            "${APISERVER_MANIFEST}" > "${TMP_FILE}"
        else
          echo "[INFO] No --anonymous-auth flag found; adding --anonymous-auth=${DESIRED_VALUE}"

          # Add to the first 'kube-apiserver' container command list
          # This assumes the standard static pod manifest structure.
          # - name: kube-apiserver
          #   command:
          #   - kube-apiserver
          #   - ...
          awk -v flag="--anonymous-auth=${DESIRED_VALUE}" '
            /- name: kube-apiserver/ { in_apiserver=1 }
            in_apiserver && /command:/ { in_command=1 }
            in_command && /^\s*-/ && !added && !/- kube-apiserver/ {
              print "    - " flag
              added=1
            }
            { print }
          ' "${APISERVER_MANIFEST}" > "${TMP_FILE}"

          # Fallback: if the above logic failed to insert the flag (e.g. nonstandard layout),
          # append it at the end of the kube-apiserver command list.
          if ! grep -q "${FLAG}${DESIRED_VALUE}" "${TMP_FILE}"; then
            echo "[INFO] Fallback: appending flag near existing kube-apiserver args"
            sed -E '
              /- kube-apiserver/ {
                p=1
              }
              p && /^\s*-/ && !seen && !/- kube-apiserver/ {
                print "    - --anonymous-auth='${DESIRED_VALUE}'"
                seen=1
              }
              { print }
            ' "${APISERVER_MANIFEST}" > "${TMP_FILE}.2" || true

            if grep -q "${FLAG}${DESIRED_VALUE}" "${TMP_FILE}.2" 2>/dev/null; then
              mv "${TMP_FILE}.2" "${TMP_FILE}"
            else
              rm -f "${TMP_FILE}.2" 2>/dev/null || true
            fi
          fi
        fi

        # If no change, exit cleanly
        if cmp -s "${APISERVER_MANIFEST}" "${TMP_FILE}"; then
          echo "[INFO] No changes required; manifest already enforces ${FLAG}${DESIRED_VALUE}"
          rm -f "${TMP_FILE}"
        else
          echo "[INFO] Updating ${APISERVER_MANIFEST} (this will restart kube-apiserver static pod)"
          mv "${TMP_FILE}" "${APISERVER_MANIFEST}"
        fi

        # Wait for kube-apiserver to restart and stabilize
        echo "[INFO] Waiting for kube-apiserver process with ${FLAG}${DESIRED_VALUE} ..."
        RETRIES=30
        SLEEP_SECONDS=5
        SUCCESS=0

        for i in $(seq 1 "${RETRIES}"); do
          if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q "${FLAG}${DESIRED_VALUE}"; then
            SUCCESS=1
            break
          fi
          echo "[INFO] Attempt ${i}/${RETRIES}: kube-apiserver not yet running with ${FLAG}${DESIRED_VALUE}, retrying in ${SLEEP_SECONDS}s..."
          sleep "${SLEEP_SECONDS}"
        done

        echo "[INFO] Verification (matches audit command):"
        /bin/ps -ef | grep kube-apiserver | grep -v grep || true

        if [[ "${SUCCESS}" -ne 1 ]]; then
          echo "[ERROR] kube-apiserver did not come up with ${FLAG}${DESIRED_VALUE} within timeout." >&2
          exit 2
        fi

        echo "[INFO] kube-apiserver is running with ${FLAG}${DESIRED_VALUE} on this control plane node."
        echo "[INFO] Repeat this script on each remaining control plane node."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
