Skip to main content

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

Manual Steps
  1. 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.yaml

    If this file does not exist, skip to step 3 (flag-based configuration).

  2. On every worker node using the kubelet config file, edit it and set protectKernelDefaults: true in 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
  3. 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
  4. 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-reload
    sudo systemctl restart kubelet.service
  5. On every worker node, verify kubelet is running with --protect-kernel-defaults=true:

    /bin/ps -fC kubelet

    Confirm in the output that either the kubelet command line includes --protect-kernel-defaults=true or that it is known to be loaded from /var/lib/kubelet/config.yaml with protectKernelDefaults: 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

Additional Reading: