Skip to main content

Ensure Make Iptables Util Chains Argument Is Set True

More Info:

Allow Kubelet to manage iptables.

Risk Level

High

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS GKE
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • 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, check how kubelet is configured (config file vs. flags):

    ps -fC kubelet
    ls -l /etc/kubernetes/kubelet /etc/systemd/system/kubelet.service.d /var/lib/kubelet
  2. If kubelet uses a config file at /var/lib/kubelet/config.yaml, edit it and set makeIPTablesUtilChains: true:

    sudo sed -i '/^makeIPTablesUtilChains:/d' /var/lib/kubelet/config.yaml
    echo 'makeIPTablesUtilChains: true' | sudo tee -a /var/lib/kubelet/config.yaml

    If the file is in JSON format instead (e.g. /etc/kubernetes/kubelet/kubelet-config.json), ensure it contains:

    "makeIPTablesUtilChains": true
  3. Ensure no systemd drop-in overrides this setting on the worker node:

    sudo grep -R --no-color --line-number 'make-iptables-util-chains' /etc/systemd/system/kubelet.service.d || true

    If found in /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf, remove that flag:

    sudo sed -i 's/--make-iptables-util-chains[=:][^[:space:]]*//g' /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
  4. If your environment configures kubelet only via executable arguments, ensure the flag is present and set to true in /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on the worker node:

    sudo sed -i 's/--make-iptables-util-chains[=:][^[:space:]]*//g' /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
    sudo sed -i 's#\(KUBELET_ARGS=".*\)"#\1 --make-iptables-util-chains=true"#' /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
  5. Restart kubelet on the worker node to apply changes:

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
    sudo systemctl status kubelet -l
  6. Verify on the worker node that kubelet is running and (if needed) inspect live config:

    ps -fC kubelet
    # Optional, from any machine with kubectl access:
    kubectl proxy --port=8001 &
    export HOSTNAME_PORT=localhost:8001
    export NODE_NAME="$(kubectl get nodes -o name | sed 's#node/##' | head -n1)"
    curl -sSL "http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz" | grep -i makeIPTablesUtilChains
Using kubectl

kubectl cannot modify kubelet host-level configuration or process flags, so this finding cannot be fixed via the Kubernetes API. The required change must be made directly on every worker node (editing /var/lib/kubelet/config.yaml or the systemd drop-in under /etc/systemd/system/kubelet.service.d/); follow the Manual Steps section to implement and verify the fix.

Automation
#!/usr/bin/env bash
#
# Fix CIS GKE 3.2.7: Ensure Kubelet --make-iptables-util-chains is true
#
# Run this on every worker node as root.
# Idempotent: safe to re-run.

set -euo pipefail

KUBELET_CONF_FILE="/var/lib/kubelet/config.yaml"
SYSTEMD_DROPIN_DIR="/etc/systemd/system/kubelet.service.d"
SYSTEMD_DROPIN_FILE="${SYSTEMD_DROPIN_DIR}/10-kubelet-args.conf"

echo "[INFO] Starting remediation for kubelet makeIPTablesUtilChains on node: $(hostname)"

# 1. Ensure systemd drop-in does NOT override make-iptables-util-chains
if [[ -f "${SYSTEMD_DROPIN_FILE}" ]]; then
echo "[INFO] Adjusting ${SYSTEMD_DROPIN_FILE} to remove any --make-iptables-util-chains overrides"
cp "${SYSTEMD_DROPIN_FILE}" "${SYSTEMD_DROPIN_FILE}.bak.$(date +%s)"

# Remove any existing occurrences of --make-iptables-util-chains from KUBELET_ARGS or ExecStart
tmpfile="$(mktemp)"
sed -E 's/--make-iptables-util-chains(=|:)?(true|false)?[[:space:]]*//g' \
"${SYSTEMD_DROPIN_FILE}" > "${tmpfile}"
mv "${tmpfile}" "${SYSTEMD_DROPIN_FILE}"
fi

# 2. Ensure kubelet config file has makeIPTablesUtilChains: true
if [[ ! -f "${KUBELET_CONF_FILE}" ]]; then
echo "[WARN] ${KUBELET_CONF_FILE} not found; creating minimal config with makeIPTablesUtilChains: true"
mkdir -p "$(dirname "${KUBELET_CONF_FILE}")"
cat > "${KUBELET_CONF_FILE}" <<'EOF'
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
makeIPTablesUtilChains: true
EOF
else
echo "[INFO] Ensuring makeIPTablesUtilChains: true is set in ${KUBELET_CONF_FILE}"
cp "${KUBELET_CONF_FILE}" "${KUBELET_CONF_FILE}.bak.$(date +%s)"

if grep -qE '^[[:space:]]*makeIPTablesUtilChains:' "${KUBELET_CONF_FILE}"; then
# Replace existing value with true
sed -i -E 's/^[[:space:]]*makeIPTablesUtilChains:.*/makeIPTablesUtilChains: true/' \
"${KUBELET_CONF_FILE}"
else
# Append setting near the end to avoid breaking YAML structure
printf '\nmakeIPTablesUtilChains: true\n' >> "${KUBELET_CONF_FILE}"
fi
fi

# 3. Reload systemd and restart kubelet
echo "[INFO] Restarting kubelet to apply configuration"
systemctl daemon-reload
systemctl restart kubelet.service

# 4. Verify kubelet is running
echo "[INFO] Verifying kubelet service status"
systemctl status kubelet -l --no-pager || {
echo "[ERROR] kubelet service is not healthy after restart"
exit 1
}

# 5. Verification aligned with audit: inspect kubelet process and active config
echo "[INFO] Current kubelet process:"
/bin/ps -fC kubelet || {
echo "[ERROR] kubelet process not found"
exit 1
}

echo "[INFO] Verifying makeIPTablesUtilChains is set to true in ${KUBELET_CONF_FILE}"
if grep -qE '^[[:space:]]*makeIPTablesUtilChains:[[:space:]]*true[[:space:]]*$' "${KUBELET_CONF_FILE}"; then
echo "[SUCCESS] makeIPTablesUtilChains is correctly set to true in ${KUBELET_CONF_FILE}"
else
echo "[ERROR] makeIPTablesUtilChains is not correctly set in ${KUBELET_CONF_FILE}"
exit 1
fi

echo "[INFO] Remediation for this node completed successfully."

Additional Reading: