Ensure Protect Kernel Defaults Argument Is Enabled
More Info:
Protect tuned kernel parameters from overriding kubelet default kernel parameter values.
Risk Level
High
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every worker node, check whether kubelet uses a config file and locate it:
ps -fC kubeletIf you see a flag like
--config=/var/lib/kubelet/config.yaml, you are using a config file (path may differ; below assumes/var/lib/kubelet/config.yaml). -
If using a kubelet config file, edit it to set
protectKernelDefaultstotrue:sudo sed -i 's/^[[:space:]]*protectKernelDefaults:.*/protectKernelDefaults: true/' /var/lib/kubelet/config.yamlIf there is no
protectKernelDefaultsline, add it under the mainkubeletConfigurationblock, for example:sudo sh -c 'printf "\nprotectKernelDefaults: true\n" >> /var/lib/kubelet/config.yaml' -
If instead kubelet is configured only via command-line flags (no
--config=flag inpsoutput), edit the systemd drop-in on each worker node:sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.confIn the line that starts with
KUBELET_SYSTEM_PODS_ARGS=, add or update:--protect-kernel-defaults=trueSave and exit.
-
Reload systemd and restart kubelet on each worker node (this restarts the kubelet process and may briefly impact scheduling on that node):
sudo systemctl daemon-reloadsudo systemctl restart kubelet.service -
Verify on each worker node that kubelet is now running with
protect-kernel-defaultsenabled:ps -fC kubeletIf using flags, ensure the output contains
--protect-kernel-defaults=true.
If using a config file, confirm the file still hasprotectKernelDefaults: true:grep -n 'protectKernelDefaults' /var/lib/kubelet/config.yaml
Using kubectl
kubectl cannot modify kubelet host-level configuration or process flags, so this finding cannot be fixed via the Kubernetes API. The correction must be made directly on each worker node by editing /var/lib/kubelet/config.yaml or the kubelet systemd unit as described in the Manual Steps section.
Automation
#!/usr/bin/env bash
#
# Remediate CIS 4.2.6: Ensure --protect-kernel-defaults / protectKernelDefaults is enabled
# Target: every worker node (run this on each worker node as root)
#
# Behavior:
# - If /var/lib/kubelet/config.yaml exists, ensure protectKernelDefaults: true
# - Also ensure kubelet systemd drop-in does NOT override with --protect-kernel-defaults=false
# - Reload systemd and restart kubelet if a change is made
# - Safe to re-run (idempotent)
#
set -euo pipefail
KUBELET_CFG="/var/lib/kubelet/config.yaml"
SYSTEMD_DIR="/etc/systemd/system/kubelet.service.d"
DROPIN_CONF="${SYSTEMD_DIR}/10-kubeadm.conf"
RESTART_NEEDED=0
echo "[INFO] Starting CIS 4.2.6 remediation for kubelet protect-kernel-defaults"
# 1. Ensure protectKernelDefaults: true in kubelet config file (if present)
if [[ -f "${KUBELET_CFG}" ]]; then
echo "[INFO] Found kubelet config file at ${KUBELET_CFG}"
# Create a backup only once
if [[ ! -f "${KUBELET_CFG}.cis-4.2.6.bak" ]]; then
cp -p "${KUBELET_CFG}" "${KUBELET_CFG}.cis-4.2.6.bak"
echo "[INFO] Backed up kubelet config to ${KUBELET_CFG}.cis-4.2.6.bak"
fi
if grep -qE '^[[:space:]]*protectKernelDefaults:' "${KUBELET_CFG}"; then
if grep -qE '^[[:space:]]*protectKernelDefaults:[[:space:]]*true[[:space:]]*$' "${KUBELET_CFG}"; then
echo "[INFO] protectKernelDefaults already set to true in ${KUBELET_CFG}"
else
echo "[INFO] Updating existing protectKernelDefaults entry to true in ${KUBELET_CFG}"
sed -i -E 's/^[[:space:]]*protectKernelDefaults:[[:space:]]*.*/protectKernelDefaults: true/' "${KUBELET_CFG}"
RESTART_NEEDED=1
fi
else
echo "[INFO] Adding protectKernelDefaults: true to ${KUBELET_CFG}"
# Append at end; kubelet config is YAML, top-level key is acceptable
printf '\nprotectKernelDefaults: true\n' >> "${KUBELET_CFG}"
RESTART_NEEDED=1
fi
else
echo "[WARN] ${KUBELET_CFG} not found. This script expects kubelet to use a config file."
echo "[WARN] If kubelet is configured only with flags, edit ${DROPIN_CONF} manually per benchmark remediation."
fi
# 2. Ensure no conflicting --protect-kernel-defaults flag in systemd drop-in
if [[ -f "${DROPIN_CONF}" ]]; then
echo "[INFO] Inspecting ${DROPIN_CONF} for --protect-kernel-defaults flags"
# Backup only once
if [[ ! -f "${DROPIN_CONF}.cis-4.2.6.bak" ]]; then
cp -p "${DROPIN_CONF}" "${DROPIN_CONF}.cis-4.2.6.bak"
echo "[INFO] Backed up systemd drop-in to ${DROPIN_CONF}.cis-4.2.6.bak"
fi
# Remove any explicit false flag; if you need flags-only configuration,
# set --protect-kernel-defaults=true here manually as per remediation.
if grep -q -- '--protect-kernel-defaults=false' "${DROPIN_CONF}"; then
echo "[INFO] Removing --protect-kernel-defaults=false from ${DROPIN_CONF}"
sed -i 's/--protect-kernel-defaults=false//g' "${DROPIN_CONF}"
RESTART_NEEDED=1
fi
else
echo "[INFO] ${DROPIN_CONF} not found; skipping systemd drop-in checks"
fi
# 3. Restart kubelet if necessary
if [[ "${RESTART_NEEDED}" -eq 1 ]]; then
echo "[INFO] Changes detected; reloading systemd and restarting kubelet"
systemctl daemon-reload
systemctl restart kubelet.service
else
echo "[INFO] No changes needed; kubelet restart not required"
fi
# 4. Verification (adapted from audit): ensure kubelet is running with protect-kernel-defaults true
echo "[INFO] Verifying kubelet protect-kernel-defaults setting"
if ! /bin/ps -fC kubelet >/dev/null 2>&1; then
echo "[ERROR] kubelet process not found after remediation"
exit 1
fi
/bin/ps -fC kubelet || true
# Check via running arguments (best-effort; kubelet may primarily use config file)
if /bin/ps -o args= -C kubelet | grep -q -- '--protect-kernel-defaults=false'; then
echo "[ERROR] kubelet still has --protect-kernel-defaults=false in its arguments"
exit 1
fi
if /bin/ps -o args= -C kubelet | grep -q -- '--protect-kernel-defaults=true'; then
echo "[INFO] kubelet is running with --protect-kernel-defaults=true flag"
else
echo "[INFO] kubelet may be using config file; checking ${KUBELET_CFG}"
if [[ -f "${KUBELET_CFG}" ]] && grep -qE '^[[:space:]]*protectKernelDefaults:[[:space:]]*true[[:space:]]*$' "${KUBELET_CFG}"; then
echo "[INFO] Verified protectKernelDefaults: true in ${KUBELET_CFG}"
else
echo "[WARN] Could not conclusively verify protectKernelDefaults=true; review kubelet configuration manually."
exit 1
fi
fi
echo "[INFO] CIS 4.2.6 remediation complete on this worker node"