Skip to main content

Ensure Rotate Server Certificates Argument Is Enabled

More Info:

Enable kubelet server certificate rotation.

Risk Level

Low

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)
  • 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 KUBELET_KUBECONFIG_ARGS / KUBELET_EXTRA_ARGS (or equivalent) line, ensure the --rotate-server-certificates flag is present and set to true, for example:

    Environment="KUBELET_EXTRA_ARGS=--rotate-server-certificates=true"

    If the flag already exists with false, change it to true. Save and exit.

  3. If /var/lib/kubelet/config.yaml is used and you manage flags there instead of systemd, also ensure the following is set (if present) or add it under the top-level serverTLSBootstrap key:

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

    Add or set:

    serverTLSBootstrap: true

    Save and exit.

  4. Reload systemd configuration and restart kubelet on the worker node:

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

    sudo systemctl status kubelet -l
  6. Verify the kubelet process is now running with server certificate rotation enabled on the worker node:

    /bin/ps -fC kubelet

    Ensure the output includes --rotate-server-certificates=true (or confirm that kubelet is using the updated config.yaml with serverTLSBootstrap: true).

Using kubectl

kubectl cannot modify kubelet process flags or host-level files, so it cannot enable --rotate-server-certificates=true. This must be fixed on every worker node by editing the kubelet systemd drop-in and/or /var/lib/kubelet/config.yaml; follow the Manual Steps section on each node.

Automation
#!/usr/bin/env bash
#
# Enable kubelet --rotate-server-certificates on all worker nodes
# Usage: run on each worker node as root (or with sudo)
# Idempotent: safe to run multiple times.

set -euo pipefail

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

echo "[INFO] Ensuring kubelet systemd drop-in exists: ${UNIT_DROPIN_FILE}"

if [[ ! -d "${UNIT_DROPIN_DIR}" ]]; then
echo "[INFO] Creating directory ${UNIT_DROPIN_DIR}"
mkdir -p "${UNIT_DROPIN_DIR}"
fi

if [[ ! -f "${UNIT_DROPIN_FILE}" ]]; then
echo "[INFO] Creating new ${UNIT_DROPIN_FILE}"
cat > "${UNIT_DROPIN_FILE}" <<'EOF'
[Service]
ExecStart=
ExecStart=/usr/bin/kubelet --rotate-server-certificates=true
EOF
else
echo "[INFO] Backing up existing ${UNIT_DROPIN_FILE} to ${UNIT_DROPIN_FILE}${BACKUP_SUFFIX}"
cp "${UNIT_DROPIN_FILE}" "${UNIT_DROPIN_FILE}${BACKUP_SUFFIX}"

echo "[INFO] Updating ${UNIT_DROPIN_FILE} to ensure --rotate-server-certificates=true"

# Extract existing ExecStart (if any), strip the key, and ensure flag is present
current_execstart=$(grep -E '^ExecStart=' "${UNIT_DROPIN_FILE}" || true)

{
echo '[Service]'
echo 'ExecStart='

if [[ -z "${current_execstart}" ]]; then
# No existing ExecStart; construct a minimal one
echo 'ExecStart=/usr/bin/kubelet --rotate-server-certificates=true'
else
# Remove leading key and possible quotes
cmd="${current_execstart#ExecStart=}"
# Remove any existing rotate-server-certificates flag
cmd="${cmd//--rotate-server-certificates=true/}"
cmd="${cmd//--rotate-server-certificates=false/}"
# Normalize whitespace
cmd="$(echo "${cmd}" | xargs)"
# Append desired flag
echo "ExecStart=${cmd} --rotate-server-certificates=true"
fi
} > "${UNIT_DROPIN_FILE}.tmp"

mv "${UNIT_DROPIN_FILE}.tmp" "${UNIT_DROPIN_FILE}"
fi

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

echo "[INFO] Verifying kubelet status"
systemctl status kubelet -l --no-pager || {
echo "[ERROR] kubelet service is not healthy after restart"
exit 1
}

echo "[INFO] Verifying kubelet process has --rotate-server-certificates=true"
if /bin/ps -fC kubelet | grep -q -- '--rotate-server-certificates=true'; then
echo "[SUCCESS] kubelet is running with --rotate-server-certificates=true"
/bin/ps -fC kubelet
exit 0
else
echo "[ERROR] kubelet is NOT running with --rotate-server-certificates=true"
echo "[INFO] Current kubelet process:"
/bin/ps -fC kubelet || true
exit 1
fi

Additional Reading: