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 AKS
  • CIS Critical Security Controls v8
  • 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, back up the kubelet config and open it for editing:

    sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%F-%H%M%S)
    sudo vi /var/lib/kubelet/config.yaml
  2. In /var/lib/kubelet/config.yaml, add or update the field under the top-level keys so it reads exactly:

    protectKernelDefaults: true

    Save and exit the editor.

  3. If your kubelet is also configured via systemd flags, check for an override and edit if present:

    if [ -f /etc/systemd/system/kubelet.service.d/10-kubeadm.conf ]; then
    sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    fi

    Ensure any existing --protect-kernel-defaults flag is set to true, for example in an Environment= or argument line:

    --protect-kernel-defaults=true
  4. Reload systemd units and restart kubelet on the worker node (this will temporarily disrupt pods on that node):

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
  5. Verify the kubelet is running with --protect-kernel-defaults=true on the worker node:

    /bin/ps -fC kubelet

    Confirm the output shows --protect-kernel-defaults=true in the kubelet command line (or, if using only the config file, that no conflicting --protect-kernel-defaults=false flag appears).

Using kubectl

kubectl cannot modify kubelet host-level configuration such as /var/lib/kubelet/config.yaml or the kubelet systemd unit where --protect-kernel-defaults=true must be set. To fix this finding, make the changes directly on every worker node as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Enable protectKernelDefaults for kubelet on every worker node.
# Run on each worker node as root. Safe to re-run (idempotent).

set -euo pipefail

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

echo "[*] Ensuring protectKernelDefaults: true in ${KUBELET_CONFIG} (if present)..."
if [ -f "${KUBELET_CONFIG}" ]; then
if grep -qE '^[[:space:]]*protectKernelDefaults:' "${KUBELET_CONFIG}"; then
if ! grep -qE '^[[:space:]]*protectKernelDefaults:[[:space:]]*true[[:space:]]*$' "${KUBELET_CONFIG}"; then
# Replace existing value with true
sed -i -E 's/^([[:space:]]*protectKernelDefaults:).*/\1 true/' "${KUBELET_CONFIG}"
echo " - Updated existing protectKernelDefaults to true in ${KUBELET_CONFIG}"
RESTART_NEEDED=1
else
echo " - protectKernelDefaults already set to true in ${KUBELET_CONFIG}"
fi
else
# Append setting at the end
printf '\nprotectKernelDefaults: true\n' >> "${KUBELET_CONFIG}"
echo " - Added protectKernelDefaults: true to ${KUBELET_CONFIG}"
RESTART_NEEDED=1
fi
else
echo " - ${KUBELET_CONFIG} not found; assuming kubelet may be using only CLI flags."
fi

echo "[*] Ensuring --protect-kernel-defaults=true is present in ${SYSTEMD_DROPIN} (if kubelet uses CLI flags)..."
if [ -f "${SYSTEMD_DROPIN}" ]; then
# Ensure the Environment line with KUBELET_SYSTEM_PODS_ARGS exists and includes the flag
if grep -q 'KUBELET_SYSTEM_PODS_ARGS' "${SYSTEMD_DROPIN}"; then
if grep -q 'KUBELET_SYSTEM_PODS_ARGS' "${SYSTEMD_DROPIN}" | grep -q -- '--protect-kernel-defaults=true'; then
echo " - --protect-kernel-defaults=true already present in KUBELET_SYSTEM_PODS_ARGS"
else
# Append flag inside the existing Environment line
sed -i -E \
's/(Environment=.*KUBELET_SYSTEM_PODS_ARGS="[^"]*)"/\1 --protect-kernel-defaults=true"/' \
"${SYSTEMD_DROPIN}"
echo " - Added --protect-kernel-defaults=true to KUBELET_SYSTEM_PODS_ARGS"
RESTART_NEEDED=1
fi
else
# No KUBELET_SYSTEM_PODS_ARGS present; add one
cat <<'EOF' >> "${SYSTEMD_DROPIN}"

# Added to enforce kubelet kernel defaults protection
Environment="KUBELET_SYSTEM_PODS_ARGS=--protect-kernel-defaults=true"
EOF
echo " - Created KUBELET_SYSTEM_PODS_ARGS with --protect-kernel-defaults=true"
RESTART_NEEDED=1
fi
else
echo " - ${SYSTEMD_DROPIN} not found; kubelet may be managed differently on this node."
fi

if [ "${RESTART_NEEDED}" -eq 1 ]; then
echo "[*] Reloading systemd and restarting kubelet (this will restart the kubelet on this node)..."
systemctl daemon-reload
systemctl restart kubelet.service
else
echo "[*] No changes made; kubelet configuration already compliant. No restart needed."
fi

echo "[*] Verification: checking kubelet process flags and config..."

# Show kubelet process line
/bin/ps -fC kubelet || true

# Verify flag presence in process arguments
if /bin/ps -o args= -C kubelet 2>/dev/null | grep -q -- '--protect-kernel-defaults=true'; then
echo " - kubelet is running with --protect-kernel-defaults=true"
else
echo " - WARNING: kubelet process does not show --protect-kernel-defaults=true in CLI flags."
fi

# Verify config file, if present
if [ -f "${KUBELET_CONFIG}" ]; then
if grep -qE '^[[:space:]]*protectKernelDefaults:[[:space:]]*true[[:space:]]*$' "${KUBELET_CONFIG}"; then
echo " - ${KUBELET_CONFIG} has protectKernelDefaults: true"
else
echo " - WARNING: ${KUBELET_CONFIG} does not show protectKernelDefaults: true"
fi
fi

echo "[*] Completed on this node."

Additional Reading: