> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, check whether kubelet uses a config file and locate it:
           ```bash theme={null}
           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`:
           ```bash theme={null}
           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:
           ```bash theme={null}
           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:
           ```bash theme={null}
           sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
           ```
           In the line that starts with `KUBELET_SYSTEM_PODS_ARGS=`, add or update:
           ```text theme={null}
           --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):
           ```bash theme={null}
           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:
           ```bash theme={null}
           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`:
           ```bash theme={null}
           grep -n 'protectKernelDefaults' /var/lib/kubelet/config.yaml
           ```
      </Accordion>

      <Accordion title="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.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/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"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/admin/kubelet/](https://kubernetes.io/docs/admin/kubelet/)
