> ## 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.

# Kubelet Seccomp Default Parameter Set To True

### More Info:

Enabling seccompDefault applies the RuntimeDefault seccomp profile to all workloads that do not specify one. This reduces the syscall attack surface available to containers by default.

### Risk Level

Medium

### 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, back up the current kubelet configuration file:
           ```bash theme={null}
           sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%F-%H%M%S)
           ```

        2. On every worker node, edit `/var/lib/kubelet/config.yaml` to enable the default seccomp profile. If the `seccompDefault` field exists, set it to `true`; if not, add it under `apiVersion`/`kind`/`...` at the top level of the KubeletConfiguration:
           ```bash theme={null}
           sudo sed -i 's/^seccompDefault:.*/seccompDefault: true/' /var/lib/kubelet/config.yaml || \
           echo "seccompDefault: true" | sudo tee -a /var/lib/kubelet/config.yaml
           ```
           Then open the file and confirm indentation and YAML validity:
           ```bash theme={null}
           sudo vi /var/lib/kubelet/config.yaml
           ```
           Ensure there is a line like:
           ```yaml theme={null}
           seccompDefault: true
           ```

        3. On every worker node, ensure the kubelet is using the config file (adjust if your systemd unit differs). Inspect the kubelet systemd unit:
           ```bash theme={null}
           systemctl cat kubelet | sed -n '1,120p'
           ```
           Confirm either `--config=/var/lib/kubelet/config.yaml` is present in `ExecStart`, or add it by editing the drop-in or unit file per your distribution’s guidance.

        4. On every worker node, restart the kubelet to apply the change (this will disrupt pods on that node while they are rescheduled):
           ```bash theme={null}
           sudo systemctl daemon-reload
           sudo systemctl restart kubelet
           sudo systemctl status kubelet --no-pager
           ```

        5. On every worker node, verify the kubelet process is running and pick out the node’s kubelet PID:
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```

        6. On every worker node, confirm that `seccompDefault` is now set to `true` in the active configuration by checking the live config file and ensuring the kubelet process is healthy:
           ```bash theme={null}
           grep -n 'seccompDefault' /var/lib/kubelet/config.yaml
           /bin/ps -fC kubelet
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot be used to enable `seccompDefault` for the kubelet because this setting is controlled entirely by host-level kubelet configuration and flags on every worker node (for example in `/var/lib/kubelet/config.yaml` or the kubelet systemd unit). To remediate this finding, follow the guidance in the **Manual Steps** section on each worker node.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Automation: Enable seccompDefault in /var/lib/kubelet/config.yaml on every worker node
        #
        # Usage (from an admin machine with SSH access to worker nodes as root or via sudo):
        #   1) Put all worker node hostnames/IPs into /root/worker-nodes.txt (one per line)
        #   2) Run:
        #        bash enable-kubelet-seccomp-default.sh
        #
        # This script is idempotent and safe to re-run.

        set -euo pipefail

        WORKER_LIST_FILE="/root/worker-nodes.txt"
        SSH_USER="root"           # change to your SSH user if needed
        SSH_OPTS="-o BatchMode=yes -o StrictHostKeyChecking=accept-new"

        if [[ ! -f "${WORKER_LIST_FILE}" ]]; then
          echo "Worker node list file not found: ${WORKER_LIST_FILE}" >&2
          exit 1
        fi

        echo "Reading worker nodes from ${WORKER_LIST_FILE}"
        mapfile -t NODES < "${WORKER_LIST_FILE}"

        if [[ "${#NODES[@]}" -eq 0 ]]; then
          echo "No nodes listed in ${WORKER_LIST_FILE}" >&2
          exit 1
        fi

        # Remote script to run on each worker node
        read -r -d '' REMOTE_SCRIPT <<'EOF'
        set -euo pipefail

        KUBELET_CONFIG="/var/lib/kubelet/config.yaml"
        SYSTEMD_UNIT="kubelet.service"

        echo "=== $(hostname): processing kubelet config ==="

        if [[ ! -f "${KUBELET_CONFIG}" ]]; then
          echo "ERROR: ${KUBELET_CONFIG} not found; kubelet may be configured differently on this node." >&2
          exit 1
        fi

        # Ensure the YAML has a top-level apiVersion to place seccompDefault under;
        # do not alter structure otherwise.
        # We'll append seccompDefault: true only if not already true.

        CURRENT_SETTING="$(grep -E '^[[:space:]]*seccompDefault:' "${KUBELET_CONFIG}" 2>/dev/null || true)"

        if [[ -n "${CURRENT_SETTING}" ]]; then
          # Normalize any existing line to 'seccompDefault: true'
          if echo "${CURRENT_SETTING}" | grep -q 'seccompDefault:[[:space:]]*true'; then
            echo "seccompDefault already set to true; no change needed."
          else
            echo "seccompDefault found but not true; updating to true."
            cp "${KUBELET_CONFIG}" "${KUBELET_CONFIG}.bak.$(date +%s)"
            # Replace any existing seccompDefault line with 'seccompDefault: true'
            # (preserves indentation)
            perl -pi -e 's/^(\s*seccompDefault:\s*).*/${1}true/' "${KUBELET_CONFIG}"
          fi
        else
          echo "seccompDefault not present; adding seccompDefault: true at end of file."
          cp "${KUBELET_CONFIG}" "${KUBELET_CONFIG}.bak.$(date +%s)"
          printf "\nseccompDefault: true\n" >> "${KUBELET_CONFIG}"
        fi

        # Reload kubelet so the new config takes effect.
        # Operational impact: this restarts kubelet, which can briefly impact node status.
        if systemctl is-enabled --quiet "${SYSTEMD_UNIT}"; then
          echo "Restarting kubelet via systemd..."
          systemctl daemon-reload
          systemctl restart "${SYSTEMD_UNIT}"
        else
          echo "WARNING: ${SYSTEMD_UNIT} not enabled under systemd; restart kubelet manually." >&2
        fi

        # Verification: confirm kubelet is running and seccompDefault is true in config
        echo "Verifying kubelet process and seccompDefault setting..."

        if ! /bin/ps -fC kubelet >/dev/null 2>&1; then
          echo "ERROR: kubelet process not found after restart." >&2
          exit 1
        fi

        if ! grep -Eq '^[[:space:]]*seccompDefault:[[:space:]]*true[[:space:]]*$' "${KUBELET_CONFIG}"; then
          echo "ERROR: seccompDefault: true not found in ${KUBELET_CONFIG} after modification." >&2
          exit 1
        fi

        echo "SUCCESS: kubelet running and seccompDefault: true configured."
        EOF

        for NODE in "${NODES[@]}"; do
          [[ -z "${NODE}" ]] && continue
          echo "===== Connecting to worker node: ${NODE} ====="
          ssh ${SSH_OPTS} "${SSH_USER}@${NODE}" "${REMOTE_SCRIPT}" || {
            echo "ERROR: remediation failed on node ${NODE}" >&2
          }
        done

        echo "=== Cluster-wide verification ==="
        for NODE in "${NODES[@]}"; do
          [[ -z "${NODE}" ]] && continue
          echo "--- ${NODE} ---"
          ssh ${SSH_OPTS} "${SSH_USER}@${NODE}" "\
            echo 'ps output:' && /bin/ps -fC kubelet || echo 'kubelet not found'; \
            echo 'seccompDefault line:' && grep -E '^[[:space:]]*seccompDefault:' /var/lib/kubelet/config.yaml || echo 'seccompDefault not set'"
        done

        echo "Done."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
