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

# Ensure Anonymous Auth Argument Is Disabled

### More Info:

Disable anonymous requests to the Kubelet server.

### Risk Level

High

### 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, back up the API server manifest before editing:
           ```bash theme={null}
           sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak.$(date +%F-%H%M%S)
           ```

        2. On every control plane node, open the API server static pod manifest for editing:
           ```bash theme={null}
           sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
           ```

        3. In the `kube-apiserver` container `command` or `args` section, ensure the flag is present and set to false (add it if missing), for example:
           ```yaml theme={null}
           - kube-apiserver
           - --anonymous-auth=false
           ```
           Save and exit. Editing this file will cause the kubelet to restart the API server pod automatically.

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

        5. On every control plane node, verify the running kube-apiserver process now includes `--anonymous-auth=false`:
           ```bash theme={null}
           /bin/ps -ef | grep kube-apiserver | grep -v grep
           ```
      </Accordion>

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

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Automation: Disable anonymous auth on kube-apiserver (--anonymous-auth=false)
        #
        # Run on: every control plane node (as root)
        # Effect: Editing /etc/kubernetes/manifests/kube-apiserver.yaml will restart the kube-apiserver
        #         because it is a static Pod managed by kubelet.

        set -euo pipefail

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

        echo "==> Ensuring kube-apiserver anonymous-auth is disabled"

        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_file="${BACKUP_DIR}/kube-apiserver.yaml.$(date +%H%M%S)"
        cp -a "${APISERVER_MANIFEST}" "${backup_file}"
        echo "Backup created at ${backup_file}"

        # Idempotently ensure --anonymous-auth=false is present and not overridden

        # 1) Remove any existing --anonymous-auth=... occurrences to avoid conflicts
        tmpfile="$(mktemp)"
        trap 'rm -f "${tmpfile}"' EXIT

        sed -E 's/--anonymous-auth=[^[:space:]]+//g' "${APISERVER_MANIFEST}" > "${tmpfile}"

        # 2) Ensure there is exactly one --anonymous-auth=false in the container args.
        #    We will append it in the args: list if not already present.
        if ! grep -q -- "${PARAM}" "${tmpfile}"; then
          # Insert into the first occurrence of " - --" style arg list under kube-apiserver container.
          # This is conservative and keeps indentation.
          if grep -qE '^\s*- --' "${tmpfile}"; then
            # Append a new arg line right after the first existing arg line.
            awk -v param="${PARAM}" '
              BEGIN {added=0}
              {
                print $0
                if (!added && $0 ~ /^[[:space:]]*- --/) {
                  sub(/^- /,"",$0)  # no-op; just to show we found it
                  print gensub(/^([[:space:]]*)- .*/, "\\1- " param, 1)
                  added=1
                }
              }
              END {
                if (!added) {
                  # Fallback: print at end as a top-level arg (unlikely path)
                  print "- " param
                }
              }
            ' "${tmpfile}" > "${tmpfile}.new"
            mv "${tmpfile}.new" "${tmpfile}"
          else
            # No recognizable args list; append at end of file as a last resort.
            echo "- ${PARAM}" >> "${tmpfile}"
          fi
        fi

        # 3) Move the updated manifest into place atomically
        cp -a "${tmpfile}" "${APISERVER_MANIFEST}"
        chmod 600 "${APISERVER_MANIFEST}" || true

        echo "Updated ${APISERVER_MANIFEST} with ${PARAM}"

        # 4) Wait for kube-apiserver to restart and run with the new flag.
        #    We poll the process command line until it shows --anonymous-auth=false.
        echo "Waiting for kube-apiserver to run with ${PARAM} ..."

        RETRIES=30
        SLEEP_SECONDS=10
        success=0

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

        if [[ "${success}" -ne 1 ]]; then
          echo "WARNING: kube-apiserver process did not show ${PARAM} after ${RETRIES} attempts." >&2
          echo "Please check kubelet and kube-apiserver status manually."
          exit 1
        fi

        echo "Verification: kube-apiserver is running with ${PARAM}"
        /bin/ps -ef | grep kube-apiserver | grep -v grep

        echo "==> Completed: anonymous auth disabled on this control plane node."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/admin/kubelet-authentication-authorization/#kubelet-authentication](https://kubernetes.io/docs/admin/kubelet-authentication-authorization/#kubelet-authentication)
