Skip to main content

Ensure Anonymous Auth Argument Is Disabled

More Info:

Disable anonymous requests to the Kubelet server.

Risk Level

High

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS OKE
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, open the kubelet systemd drop-in config for editing:

    sudo vi /etc/systemd/system/kubelet.service.d/00-default.conf
  2. In the ExecStart= line, ensure the kubelet is started with anonymous auth disabled. Add --anonymous-auth=false if it is missing, or set it to false if present with another value. For example:

    ExecStart=/usr/bin/kubelet \
    --config=/var/lib/kubelet/config.yaml \
    --anonymous-auth=false \
    ...
  3. If /var/lib/kubelet/config.yaml is used to configure authentication, also ensure it does not enable anonymous auth. Open it:

    sudo vi /var/lib/kubelet/config.yaml

    And either remove any authentication.anonymous section or explicitly set:

    authentication:
    anonymous:
    enabled: false
  4. Reload systemd configuration and restart kubelet on the same worker node:

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
  5. Confirm kubelet is running correctly:

    sudo systemctl status kubelet -l
  6. Verify that kubelet is now running with --anonymous-auth=false on this worker node:

    /bin/ps -fC kubelet

    Ensure the output shows the kubelet process arguments including --anonymous-auth=false and no conflicting --anonymous-auth=true.

Using kubectl

kubectl cannot modify Kubelet process flags or its host-level configuration file /var/lib/kubelet/config.yaml or the systemd drop-in at /etc/systemd/system/kubelet.service.d/00-default.conf. To remediate this finding, make the change directly on every worker node as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Remediation: Disable kubelet anonymous auth on every worker node
#
# Usage:
# 1) Put all worker node hostnames/IPs into a file, one per line, e.g. nodes.txt
# 2) Ensure SSH access and sudo privileges on each node (passwordless sudo recommended)
# 3) Run: ./fix-kubelet-anon-auth.sh nodes.txt
#
# This script is idempotent and safe to re-run.

set -euo pipefail

NODES_FILE="${1:-}"

if [[ -z "${NODES_FILE}" || ! -f "${NODES_FILE}" ]]; then
echo "Usage: $0 <nodes_file_with_hostnames_or_IPs>"
exit 1
fi

# Commands executed on: every worker node
remote_fix() {
local NODE="$1"

echo "=== [$NODE] Starting remediation ==="

ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$NODE" 'bash -s' << 'EOF'
set -euo pipefail

UNIT_DIR="/etc/systemd/system/kubelet.service.d"
UNIT_FILE="${UNIT_DIR}/00-default.conf"
BACKUP_SUFFIX="$(date +%Y%m%d%H%M%S)"

if [[ ! -d "${UNIT_DIR}" ]]; then
echo "Directory ${UNIT_DIR} does not exist; kubelet may be managed differently. Skipping."
exit 0
fi

if [[ ! -f "${UNIT_FILE}" ]]; then
echo "File ${UNIT_FILE} not found, creating it."
sudo install -o root -g root -m 0644 /dev/null "${UNIT_FILE}"
fi

echo "Backing up ${UNIT_FILE} to ${UNIT_FILE}.${BACKUP_SUFFIX}.bak"
sudo cp "${UNIT_FILE}" "${UNIT_FILE}.${BACKUP_SUFFIX}.bak"

# Ensure --anonymous-auth=false is present and not overridden
# 1) Remove any existing --anonymous-auth flags
sudo sed -i -r 's/--anonymous-auth(=|\s+)(true|false)//g' "${UNIT_FILE}"

# 2) Ensure KUBELET_EXTRA_ARGS or ExecStart has --anonymous-auth=false
if grep -q 'KUBELET_EXTRA_ARGS' "${UNIT_FILE}"; then
echo "Updating KUBELET_EXTRA_ARGS in ${UNIT_FILE}"
sudo sed -i -r 's/(KUBELET_EXTRA_ARGS=.*)/\1 --anonymous-auth=false/' "${UNIT_FILE}"
elif grep -q 'ExecStart=' "${UNIT_FILE}"; then
echo "Updating ExecStart in ${UNIT_FILE}"
sudo sed -i -r 's|(ExecStart=.*kubelet)|\1 --anonymous-auth=false|' "${UNIT_FILE}"
else
echo "No KUBELET_EXTRA_ARGS or ExecStart found; appending Environment line."
echo 'Environment="KUBELET_EXTRA_ARGS=--anonymous-auth=false"' | sudo tee -a "${UNIT_FILE}" >/dev/null
fi

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

echo "Checking kubelet status:"
sudo systemctl status kubelet -l --no-pager || true

echo "Verifying kubelet process flags:"
/bin/ps -fC kubelet || true

# Verification: ensure --anonymous-auth=false is visible in kubelet process
if /bin/ps -fC kubelet | grep -q -- '--anonymous-auth=false'; then
echo "Verification PASSED: --anonymous-auth=false is set on kubelet."
else
echo "Verification FAILED: --anonymous-auth=false not found on kubelet process."
exit 1
fi

EOF

echo "=== [$NODE] Remediation complete ==="
}

while IFS= read -r NODE; do
[[ -z "$NODE" || "$NODE" =~ ^# ]] && continue
remote_fix "$NODE"
done < "${NODES_FILE}"

Additional Reading: