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​

  • CIS Kubernetes

Triage and Remediation​

Remediation​

Manual Steps
  1. On every worker node, check whether kubelet uses a config file and locate it:

    ps -fC kubelet

    If 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).

  2. If using a kubelet config file, edit it to set protectKernelDefaults to true:

    sudo sed -i 's/^[[:space:]]*protectKernelDefaults:.*/protectKernelDefaults: true/' /var/lib/kubelet/config.yaml

    If there is no protectKernelDefaults line, add it under the main kubeletConfiguration block, for example:

    sudo sh -c 'printf "\nprotectKernelDefaults: true\n" >> /var/lib/kubelet/config.yaml'
  3. If instead kubelet is configured only via command-line flags (no --config= flag in ps output), edit the systemd drop-in on each worker node:

    sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    In the line that starts with KUBELET_SYSTEM_PODS_ARGS=, add or update:

    --protect-kernel-defaults=true

    Save and exit.

  4. 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-reload
    sudo systemctl restart kubelet.service
  5. Verify on each worker node that kubelet is now running with protect-kernel-defaults enabled:

    ps -fC kubelet

    If using flags, ensure the output contains --protect-kernel-defaults=true.
    If using a config file, confirm the file still has protectKernelDefaults: 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"

Additional Reading:​