> ## 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 That The --make-iptables-util-chains Argument Is Set To True

### More Info:

When makeIPTablesUtilChains is true, the kubelet manages the iptables utility chains needed for correct pod networking and traffic filtering on the node.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS EKS

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, open the kubelet config file and set `makeIPTablesUtilChains` to true:
           ```bash theme={null}
           sudo mkdir -p /etc/kubernetes/kubelet
           sudo sed -i '/makeIPTablesUtilChains/d' /var/lib/kubelet/config.yaml
           echo 'makeIPTablesUtilChains: true' | sudo tee -a /var/lib/kubelet/config.yaml
           ```
           If your environment instead uses `/etc/kubernetes/kubelet/kubelet-config.json`, edit that file:
           ```bash theme={null}
           sudo sed -i '/makeIPTablesUtilChains/d' /etc/kubernetes/kubelet/kubelet-config.json
           sudo sed -i 's/^{/{\n  "makeIPTablesUtilChains": true,/' /etc/kubernetes/kubelet/kubelet-config.json
           ```

        2. On every worker node, ensure the systemd drop-in does not override this setting:
           ```bash theme={null}
           if [ -f /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf ]; then
             sudo sed -i 's/--make-iptables-util-chains[=:][^[:space:]]*//g' /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
           fi
           ```

        3. On every worker node, reload systemd and restart kubelet (this restarts the kubelet and may briefly disrupt workloads on that node):
           ```bash theme={null}
           sudo systemctl daemon-reload
           sudo systemctl restart kubelet.service
           sudo systemctl status kubelet -l
           ```

        4. From any machine with `kubectl` access, optionally verify the live kubelet config via the configz endpoint for a given worker node:
           ```bash theme={null}
           kubectl proxy --port=8001 &
           export HOSTNAME_PORT=localhost:8001
           export NODE_NAME=<worker-node-name>
           curl -sSL "http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz" | grep -i makeIPTablesUtilChains
           ```

        5. On every worker node, confirm the running kubelet process is not passing a conflicting `--make-iptables-util-chains` flag:
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```
           Ensure the command line either omits `--make-iptables-util-chains` (so the config file value is used) or, if present, has it set to `true`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify the kubelet’s host-level configuration or process flags, including `makeIPTablesUtilChains`. This finding must be remediated directly on each worker node by editing the kubelet config and/or systemd unit files as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Fix CISEKS 3.2.6: Ensure that the --make-iptables-util-chains argument is set to true
        #
        # Run on: every worker node (with root privileges)
        # Safe to re-run: yes

        set -euo pipefail

        KUBELET_CONF_JSON="/etc/kubernetes/kubelet/kubelet-config.json"
        KUBELET_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubelet-args.conf"

        echo "[INFO] Ensuring kubelet manages iptables utility chains (makeIPTablesUtilChains: true)"

        #-------------------------------------------------------------------------------
        # Helper: ensure string is present and not contradicted in systemd drop-in
        #-------------------------------------------------------------------------------
        ensure_no_make_iptables_flag_in_dropin() {
          local f="$1"
          if [[ ! -f "$f" ]]; then
            echo "[INFO] Systemd drop-in $f not found; nothing to clean."
            return 0
          fi

          if grep -q -- "--make-iptables-util-chains" "$f"; then
            echo "[INFO] Removing --make-iptables-util-chains from $f to avoid overriding kubelet config."

            cp -a "$f" "${f}.bak.$(date +%Y%m%d%H%M%S)"

            # Remove any occurrences of the flag in the file
            # Handles both '--make-iptables-util-chains=true' and '--make-iptables-util-chains:false' variants
            sed -i 's/\s*--make-iptables-util-chains[=:]\(true\|false\)//g' "$f"

            echo "[INFO] Cleaned $f. Backup saved as ${f}.bak.*"
          else
            echo "[INFO] No --make-iptables-util-chains flag found in $f; leaving as-is."
          fi
        }

        #-------------------------------------------------------------------------------
        # Method 1: Kubelet config file (preferred, per remediation)
        #-------------------------------------------------------------------------------
        configure_kubelet_config_file() {
          local f="$1"

          if [[ ! -f "$f" ]]; then
            echo "[WARN] $f does not exist; skipping Method 1 remediation."
            return 1
          fi

          cp -a "$f" "${f}.bak.$(date +%Y%m%d%H%M%S)"

          if command -v jq >/dev/null 2>&1; then
            echo "[INFO] Using jq to set makeIPTablesUtilChains: true in $f"
            tmp="$(mktemp)"
            jq '.makeIPTablesUtilChains = true' "$f" > "$tmp"
            mv "$tmp" "$f"
          else
            echo "[INFO] jq not available; updating $f with sed/awk."

            # If key exists, set it to true; otherwise insert it near the top-level keys.
            if grep -q '"makeIPTablesUtilChains"' "$f"; then
              sed -i 's/"makeIPTablesUtilChains"[[:space:]]*:[[:space:]]*[^,]*/"makeIPTablesUtilChains": true/' "$f"
            else
              # Insert after first '{' (simple but safe for standard kubelet-config.json)
              tmp="$(mktemp)"
              awk '
                BEGIN{inserted=0}
                {
                  print $0
                  if (!inserted && $0 ~ /{/) {
                    print "  \"makeIPTablesUtilChains\": true,"
                    inserted=1
                  }
                }
              ' "$f" > "$tmp"
              mv "$tmp" "$f"
            fi
          fi

          echo "[INFO] Updated $f to ensure makeIPTablesUtilChains: true"
          return 0
        }

        #-------------------------------------------------------------------------------
        # Method 2 fallback: systemd executable argument if no kubelet-config.json
        #-------------------------------------------------------------------------------
        configure_kubelet_service_args() {
          local f="$1"

          if [[ ! -f "$f" ]]; then
            echo "[WARN] $f not found; cannot apply Method 2 remediation."
            return 1
          fi

          cp -a "$f" "${f}.bak.$(date +%Y%m%d%H%M%S)"

          # Ensure we have an Environment line defining KUBELET_ARGS or similar.
          if ! grep -q "KUBELET_ARGS" "$f"; then
            echo "[WARN] No KUBELET_ARGS variable found in $f; manual review needed."
            return 1
          fi

          # Remove any existing make-iptables flag and append correct one once.
          sed -i 's/\s*--make-iptables-util-chains[=:]\(true\|false\)//g' "$f"

          if grep -q -- "--make-iptables-util-chains" "$f"; then
            echo "[INFO] --make-iptables-util-chains already present in $f"
          else
            echo "[INFO] Adding --make-iptables-util-chains=true to KUBELET_ARGS in $f"
            sed -i 's/^\(Environment=.*KUBELET_ARGS="\)\(.*\)"/\1\2 --make-iptables-util-chains=true"/' "$f"
          fi

          return 0
        }

        #-------------------------------------------------------------------------------
        # Apply remediation
        #-------------------------------------------------------------------------------
        method_used="none"

        if configure_kubelet_config_file "$KUBELET_CONF_JSON"; then
          method_used="configfile"
          ensure_no_make_iptables_flag_in_dropin "$KUBELET_DROPIN"
        else
          echo "[INFO] Falling back to Method 2 (systemd executable args)."
          if configure_kubelet_service_args "$KUBELET_DROPIN"; then
            method_used="serviceargs"
          else
            echo "[ERROR] Could not apply remediation via config file or service args. Manual intervention required."
            exit 1
          fi
        fi

        #-------------------------------------------------------------------------------
        # Restart kubelet to apply changes
        #-------------------------------------------------------------------------------
        echo "[INFO] Reloading systemd and restarting kubelet (this will restart the kubelet on this node)."
        systemctl daemon-reload
        systemctl restart kubelet.service

        # Optional: brief wait to ensure process is up
        sleep 5

        echo "[INFO] Checking kubelet status:"
        systemctl status kubelet -l --no-pager || true

        #-------------------------------------------------------------------------------
        # Verification (adapted from audit command)
        #-------------------------------------------------------------------------------
        echo "[INFO] Verifying kubelet process flags for --make-iptables-util-chains=true"

        /bin/ps -fC kubelet || {
          echo "[ERROR] kubelet process not found after restart."
          exit 1
        }

        if /bin/ps -o args= -C kubelet | grep -q -- "--make-iptables-util-chains=true"; then
          echo "[PASS] kubelet is running with --make-iptables-util-chains=true"
        else
          echo "[WARN] kubelet is not showing --make-iptables-util-chains=true as an explicit flag."
          echo "       If Method 1 (config file) was used, this is expected; kubelet reads it from $KUBELET_CONF_JSON."
          echo "       Additional verification via configz endpoint is recommended:"
          echo "         kubectl proxy --port=8001 &"
          echo "         export HOSTNAME_PORT=localhost:8001"
          echo "         export NODE_NAME=<this-node-name-from-kubectl-get-nodes>"
          echo "         curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/\${NODE_NAME}/proxy/configz\" | grep -i makeIPTablesUtilChains"
        fi

        echo "[INFO] Remediation script completed on this node (method used: $method_used)"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
