Skip to main content

Ensure Rotate Certificates Argument Is Enabled

More Info:

Enable kubelet client certificate rotation.

Risk Level

Low

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, open the kubelet config file and ensure rotateCertificates is not set to false (set it to true or remove the key). For example, using vi:

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

    In the kubeletConfiguration section, either remove any existing rotateCertificates line or set it explicitly:

    rotateCertificates: true
  2. Still on every worker node, check if kubelet is started with an explicit --rotate-certificates=false flag in its systemd drop-in:

    sudo grep -R --no-color -n "rotate-certificates" /etc/systemd/system/kubelet.service.d /etc/systemd/system/kubelet.service 2>/dev/null || echo "no rotate-certificates flag found"
  3. If the flag is present and set to false, edit the systemd configuration and remove the --rotate-certificates=false argument completely:

    sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    In the Environment= or KUBELET_CERTIFICATE_ARGS line, delete --rotate-certificates=false (do not replace it with true; absence uses the default secure behavior).

  4. On every worker node, reload systemd configuration and restart the kubelet for changes to take effect (this will temporarily disrupt workloads on that node):

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
  5. Verify on every worker node that kubelet is no longer running with --rotate-certificates=false:

    /bin/ps -fC kubelet

    Inspect the command line in the output and confirm there is no --rotate-certificates=false flag.

Using kubectl

kubectl cannot modify kubelet host-level configuration such as /var/lib/kubelet/config.yaml or the systemd unit files on worker nodes. To remediate this finding, edit the kubelet config and/or systemd service directly on each worker node as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Enable kubelet client certificate rotation on all worker nodes.
# Usage: run on each worker node with root privileges.

set -euo pipefail

KUBELET_CONFIG="/var/lib/kubelet/config.yaml"
SYSTEMD_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"

echo "[INFO] Ensuring kubelet client certificate rotation is enabled"

########################################
# 1. Update kubelet config file
########################################
if [ -f "${KUBELET_CONFIG}" ]; then
echo "[INFO] Found kubelet config: ${KUBELET_CONFIG}"

# Backup once
if [ ! -f "${KUBELET_CONFIG}.pre-rotate-cert-backup" ]; then
cp -p "${KUBELET_CONFIG}" "${KUBELET_CONFIG}.pre-rotate-cert-backup"
echo "[INFO] Backup created at ${KUBELET_CONFIG}.pre-rotate-cert-backup"
fi

# If rotateCertificates is explicitly set to false, change to true.
# If set to true already, leave as-is.
# If not present, leave file untouched (default is true).
if grep -qE '^[[:space:]]*rotateCertificates:[[:space:]]*false[[:space:]]*$' "${KUBELET_CONFIG}"; then
echo "[INFO] Updating rotateCertificates: false -> true in ${KUBELET_CONFIG}"
sed -i -E 's/^([[:space:]]*rotateCertificates:[[:space:]]*)false([[:space:]]*)$/\1true\2/' "${KUBELET_CONFIG}"
elif grep -qE '^[[:space:]]*rotateCertificates:[[:space:]]*true[[:space:]]*$' "${KUBELET_CONFIG}"; then
echo "[INFO] rotateCertificates is already set to true in ${KUBELET_CONFIG}"
else
echo "[INFO] rotateCertificates not explicitly set in ${KUBELET_CONFIG}; leaving default (true) in place"
fi
else
echo "[WARN] Kubelet config file ${KUBELET_CONFIG} not found; skipping file-based config"
fi

########################################
# 2. Clean up kubelet systemd arguments
########################################
if [ -f "${SYSTEMD_DROPIN}" ]; then
echo "[INFO] Found kubelet systemd drop-in: ${SYSTEMD_DROPIN}"

# Backup once
if [ ! -f "${SYSTEMD_DROPIN}.pre-rotate-cert-backup" ]; then
cp -p "${SYSTEMD_DROPIN}" "${SYSTEMD_DROPIN}.pre-rotate-cert-backup"
echo "[INFO] Backup created at ${SYSTEMD_DROPIN}.pre-rotate-cert-backup"
fi

# Remove any explicit --rotate-certificates=false from the file
if grep -q -- "--rotate-certificates=false" "${SYSTEMD_DROPIN}"; then
echo "[INFO] Removing --rotate-certificates=false from ${SYSTEMD_DROPIN}"
# Remove the argument whether standalone or followed by space or backslash
sed -i -E 's/[[:space:]]*--rotate-certificates=false(\\)?//g' "${SYSTEMD_DROPIN}"
else
echo "[INFO] No --rotate-certificates=false flag present in ${SYSTEMD_DROPIN}"
fi
else
echo "[WARN] Systemd drop-in ${SYSTEMD_DROPIN} not found; skipping argument cleanup"
fi

########################################
# 3. Reload systemd and restart kubelet
########################################
echo "[INFO] Reloading systemd and restarting kubelet (this will restart the kubelet process)"
systemctl daemon-reload
systemctl restart kubelet.service

########################################
# 4. Verification
########################################
echo "[INFO] Verifying kubelet process arguments"
/bin/ps -fC kubelet || {
echo "[ERROR] kubelet process not found after restart"
exit 1
}

if /bin/ps -fC kubelet | grep -q -- "--rotate-certificates=false"; then
echo "[ERROR] kubelet is still running with --rotate-certificates=false"
exit 1
fi

echo "[INFO] kubelet is not using --rotate-certificates=false"

# If config file exists, double-check the setting
if [ -f "${KUBELET_CONFIG}" ]; then
if grep -qE '^[[:space:]]*rotateCertificates:[[:space:]]*false[[:space:]]*$' "${KUBELET_CONFIG}"; then
echo "[ERROR] rotateCertificates is still set to false in ${KUBELET_CONFIG}"
exit 1
fi
echo "[INFO] Verified rotateCertificates is not set to false in ${KUBELET_CONFIG}"
fi

echo "[INFO] Certificate rotation setting remediated successfully on this node"

Additional Reading: