Skip to main content

Ensure Rotate Certificates Argument Is Not Set Disabled

More Info:

Enable kubelet client 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 EKS
  • 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, back up the current kubelet configuration and systemd drop-in:
sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%F-%H%M%S)
sudo cp -a /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf.bak.$(date +%F-%H%M%S)
  1. On every worker node, edit the kubelet config file to enable certificate rotation:
sudo vi /var/lib/kubelet/config.yaml

Ensure there is a line setting rotateCertificates: true (add or update as needed), for example:

rotateCertificates: true
  1. On every worker node, ensure no systemd argument disables rotation:
sudo vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
  • Remove any occurrence of --rotate-certificates=false.
  • If you must use flags instead of config, make sure KUBELET_ARGS (or the ExecStart line) includes --rotate-certificates=true and not false.
  1. On every worker node, reload systemd and restart kubelet (this will briefly disrupt pods scheduled on that node):
sudo systemctl daemon-reload
sudo systemctl restart kubelet
  1. On every worker node, verify the kubelet process is running with certificate rotation enabled and not disabled:
/bin/ps -fC kubelet

Confirm the output does not contain --rotate-certificates=false; if the flag appears, it should be --rotate-certificates=true, or the flag can be absent while rotateCertificates: true is set in /var/lib/kubelet/config.yaml.

Using kubectl

kubectl cannot modify kubelet process flags or its on-node configuration file /var/lib/kubelet/config.yaml, so this finding cannot be fixed via the Kubernetes API. Make the changes directly on every worker node’s host configuration and systemd unit as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Enable kubelet client certificate rotation on every worker node.
# Run this script on EACH WORKER NODE as root (or with sudo).
#
# Idempotent: safe to re-run; only enforces rotateCertificates=true and
# removes/overrides any conflicting --rotate-certificates flags.
#
set -euo pipefail

SERVICE_DROPIN_DIR="/etc/systemd/system/kubelet.service.d"
SERVICE_DROPIN_FILE="${SERVICE_DROPIN_DIR}/10-kubelet-args.conf"
KUBELET_CONFIG_FILE="/var/lib/kubelet/config.yaml"

echo "[INFO] Enabling kubelet client certificate rotation on this node"

###############################################################################
# 1. Ensure kubelet config file sets rotateCertificates: true
###############################################################################
if [[ -f "${KUBELET_CONFIG_FILE}" ]]; then
echo "[INFO] Updating ${KUBELET_CONFIG_FILE} to set rotateCertificates: true"

# Create a backup once per run
cp -p "${KUBELET_CONFIG_FILE}" "${KUBELET_CONFIG_FILE}.bak.$(date +%s)"

# If rotateCertificates key exists, set it to true; otherwise append it.
if grep -qE '^[[:space:]]*rotateCertificates:' "${KUBELET_CONFIG_FILE}"; then
# Replace existing line to ensure it is set to true
sed -i 's/^[[:space:]]*rotateCertificates:.*/rotateCertificates: true/' \
"${KUBELET_CONFIG_FILE}"
else
# Append at end of file
printf '\nrotateCertificates: true\n' >> "${KUBELET_CONFIG_FILE}"
fi
else
echo "[WARN] ${KUBELET_CONFIG_FILE} not found; skipping config.yaml update"
fi

###############################################################################
# 2. Ensure systemd drop-in does not disable rotation and sets it to true
###############################################################################
echo "[INFO] Ensuring systemd drop-in does not disable --rotate-certificates"

mkdir -p "${SERVICE_DROPIN_DIR}"

if [[ -f "${SERVICE_DROPIN_FILE}" ]]; then
cp -p "${SERVICE_DROPIN_FILE}" "${SERVICE_DROPIN_FILE}.bak.$(date +%s)"
else
# Create a minimal drop-in if it doesn't exist
cat > "${SERVICE_DROPIN_FILE}" <<'EOF'
[Service]
Environment="KUBELET_ARGS="
EOF
fi

# Remove any existing --rotate-certificates arguments (true or false)
if grep -q -- "--rotate-certificates" "${SERVICE_DROPIN_FILE}"; then
sed -i 's/--rotate-certificates=[^" ]*//g' "${SERVICE_DROPIN_FILE}"
fi

# Ensure KUBELET_ARGS line exists
if ! grep -q '^Environment="KUBELET_ARGS=' "${SERVICE_DROPIN_FILE}"; then
echo 'Environment="KUBELET_ARGS="' >> "${SERVICE_DROPIN_FILE}"
fi

# Append --rotate-certificates=true if not already present
if ! grep -q -- "--rotate-certificates=true" "${SERVICE_DROPIN_FILE}"; then
sed -i 's/^Environment="KUBELET_ARGS=\(.*\)"/Environment="KUBELET_ARGS=\1 --rotate-certificates=true"/' \
"${SERVICE_DROPIN_FILE}"
fi

###############################################################################
# 3. Reload systemd and restart kubelet (OPERATIONAL IMPACT)
###############################################################################
echo "[INFO] Reloading systemd daemon and restarting kubelet"
systemctl daemon-reload
systemctl restart kubelet

###############################################################################
# 4. Verification (adapted from audit)
/bin/ps -fC kubelet
###############################################################################
echo "[INFO] Verification: checking kubelet process arguments and config"

# Show kubelet process line with rotate-certificates flag (if present)
ps -fC kubelet || true

# Check for rotateCertificates: true in config file
if [[ -f "${KUBELET_CONFIG_FILE}" ]]; then
echo "[INFO] Checking ${KUBELET_CONFIG_FILE} for rotateCertificates: true"
grep -n 'rotateCertificates' "${KUBELET_CONFIG_FILE}" || true
fi

echo "[INFO] Manual check expectations:"
echo " - kubelet should NOT be started with --rotate-certificates=false"
echo " - Either:"
echo " * kubelet has --rotate-certificates=true in its args, and/or"
echo " * ${KUBELET_CONFIG_FILE} contains: rotateCertificates: true"

Additional Reading: