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
- APRA CPS 234 (Australia)
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS Critical Security Controls v8
- CIS GKE
- 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
Remediation
Manual Steps
-
On every worker node, check whether kubelet uses a config file and locate it (you already know
/var/lib/kubelet/config.yaml, but confirm it exists):ls -l /var/lib/kubelet/config.yamlIf this file does not exist, skip to step 3 (flag-based configuration).
-
On every worker node using the kubelet config file, edit it and set
protectKernelDefaults: truein the top-level kubelet configuration:sudo sed -i 's/^\(\s*protectKernelDefaults:\).*/\1 true/' /var/lib/kubelet/config.yaml || \echo 'protectKernelDefaults: true' | sudo tee -a /var/lib/kubelet/config.yaml -
On every worker node, if kubelet is configured via systemd flags, edit the kubelet drop-in to add the flag:
sudo sed -i 's|\(KUBELET_SYSTEM_PODS_ARGS="[^"]*\)"|\1 --protect-kernel-defaults=true"|' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf || \echo 'Environment="KUBELET_SYSTEM_PODS_ARGS=--protect-kernel-defaults=true"' | \sudo tee -a /etc/systemd/system/kubelet.service.d/10-kubeadm.conf -
On every worker node, reload systemd and restart kubelet (note: this restarts the kubelet and may briefly disrupt workloads on that node):
sudo systemctl daemon-reloadsudo systemctl restart kubelet.service -
On every worker node, verify kubelet is running with
--protect-kernel-defaults=true:/bin/ps -fC kubeletConfirm in the output that either the kubelet command line includes
--protect-kernel-defaults=trueor that it is known to be loaded from/var/lib/kubelet/config.yamlwithprotectKernelDefaults: true.
Using kubectl
kubectl cannot configure kubelet process flags or its local config file, so it cannot be used to set protectKernelDefaults: true on worker nodes. To remediate this finding, make the change directly on each node’s /var/lib/kubelet/config.yaml or kubelet systemd unit as described in the Manual Steps section.
Automation
#!/usr/bin/env bash
#
# Automation: Ensure kubelet has protectKernelDefaults enabled on every worker node
# Usage: Run on each worker node as root (or with sudo).
# Safe to re-run; makes changes only when needed.
set -euo pipefail
KUBELET_CONFIG="/var/lib/kubelet/config.yaml"
SYSTEMD_OVERRIDE_DIR="/etc/systemd/system/kubelet.service.d"
SYSTEMD_OVERRIDE_FILE="${SYSTEMD_OVERRIDE_DIR}/10-kubeadm.conf"
changed=0
need_restart=0
echo "=== Ensuring protectKernelDefaults: true in kubelet configuration ==="
# 1) Prefer kubelet config file if present
if [ -f "$KUBELET_CONFIG" ]; then
echo "Detected kubelet config file at ${KUBELET_CONFIG}"
# Make a backup once
if [ ! -f "${KUBELET_CONFIG}.bak" ]; then
cp "$KUBELET_CONFIG" "${KUBELET_CONFIG}.bak"
fi
# If key exists but not true, set to true
if grep -q '^[[:space:]]*protectKernelDefaults:' "$KUBELET_CONFIG"; then
if ! grep -q '^[[:space:]]*protectKernelDefaults:[[:space:]]*true[[:space:]]*$' "$KUBELET_CONFIG"; then
# Replace any existing value with true (preserve indentation)
perl -pi -e 's/^(\s*protectKernelDefaults:\s*).*/${1}true/' "$KUBELET_CONFIG"
echo "Updated existing protectKernelDefaults entry to true in ${KUBELET_CONFIG}"
changed=1
need_restart=1
else
echo "protectKernelDefaults already set to true in ${KUBELET_CONFIG}"
fi
else
# Add key under top-level; append at end if no better place is known
printf '\nprotectKernelDefaults: true\n' >> "$KUBELET_CONFIG"
echo "Added protectKernelDefaults: true to ${KUBELET_CONFIG}"
changed=1
need_restart=1
fi
# 2) Fallback to systemd flags if no config file
else
echo "No kubelet config file found at ${KUBELET_CONFIG}, using systemd flags"
mkdir -p "$SYSTEMD_OVERRIDE_DIR"
if [ ! -f "$SYSTEMD_OVERRIDE_FILE" ]; then
cat > "$SYSTEMD_OVERRIDE_FILE" <<'EOF'
[Service]
Environment="KUBELET_SYSTEM_PODS_ARGS=--protect-kernel-defaults=true"
EOF
echo "Created ${SYSTEMD_OVERRIDE_FILE} with protect-kernel-defaults flag"
changed=1
need_restart=1
else
# Make a backup once
if [ ! -f "${SYSTEMD_OVERRIDE_FILE}.bak" ]; then
cp "$SYSTEMD_OVERRIDE_FILE" "${SYSTEMD_OVERRIDE_FILE}.bak"
fi
# Check if flag already present
if grep -q -- '--protect-kernel-defaults=true' "$SYSTEMD_OVERRIDE_FILE"; then
echo "--protect-kernel-defaults=true already present in ${SYSTEMD_OVERRIDE_FILE}"
else
# Ensure KUBELET_SYSTEM_PODS_ARGS exists and append flag
if grep -q '^Environment="KUBELET_SYSTEM_PODS_ARGS=' "$SYSTEMD_OVERRIDE_FILE"; then
perl -pi -e 's/^(Environment="KUBELET_SYSTEM_PODS_ARGS=.*)"/${1} --protect-kernel-defaults=true"/' "$SYSTEMD_OVERRIDE_FILE"
else
echo 'Environment="KUBELET_SYSTEM_PODS_ARGS=--protect-kernel-defaults=true"' >> "$SYSTEMD_OVERRIDE_FILE"
fi
echo "Appended --protect-kernel-defaults=true to ${SYSTEMD_OVERRIDE_FILE}"
changed=1
need_restart=1
fi
fi
fi
# 3) Restart kubelet if needed
if [ "$need_restart" -eq 1 ]; then
echo "Reloading systemd and restarting kubelet (this restarts kubelet on this worker node)..."
systemctl daemon-reload
systemctl restart kubelet.service
echo "kubelet restarted."
fi
# 4) Verification: ensure kubelet is running with protect-kernel-defaults enabled
echo "=== Verification: checking kubelet process flags ==="
/bin/ps -fC kubelet || { echo "kubelet process not found"; exit 1; }
if /bin/ps -fC kubelet | grep -q -- '--protect-kernel-defaults=true'; then
echo "Verification PASSED: kubelet is running with --protect-kernel-defaults=true"
exit 0
fi
# If using config file, the flag may not appear on the command line; do a config-level check
if [ -f "$KUBELET_CONFIG" ] && grep -q '^[[:space:]]*protectKernelDefaults:[[:space:]]*true[[:space:]]*$' "$KUBELET_CONFIG"; then
echo "Verification PASSED: protectKernelDefaults: true is set in ${KUBELET_CONFIG}"
exit 0
fi
echo "Verification FAILED: kubelet does not appear to have protect-kernel-defaults enabled."
exit 1