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
Remediation
Manual Steps
-
On every worker node, open the kubelet config file and ensure
rotateCertificatesis not set tofalse(set it totrueor remove the key). For example, usingvi:sudo vi /var/lib/kubelet/config.yamlIn the
kubeletConfigurationsection, either remove any existingrotateCertificatesline or set it explicitly:rotateCertificates: true -
Still on every worker node, check if kubelet is started with an explicit
--rotate-certificates=falseflag 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" -
If the flag is present and set to
false, edit the systemd configuration and remove the--rotate-certificates=falseargument completely:sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.confIn the
Environment=orKUBELET_CERTIFICATE_ARGSline, delete--rotate-certificates=false(do not replace it withtrue; absence uses the default secure behavior). -
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-reloadsudo systemctl restart kubelet.service -
Verify on every worker node that kubelet is no longer running with
--rotate-certificates=false:/bin/ps -fC kubeletInspect the command line in the output and confirm there is no
--rotate-certificates=falseflag.
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"