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
Remediation
Manual Steps
-
On every worker node, check how kubelet is configured (config file vs. flags):
ps -fC kubeletls -l /etc/kubernetes/kubelet /etc/systemd/system/kubelet.service.d /var/lib/kubelet -
If kubelet uses a config file at
/var/lib/kubelet/config.yaml, edit it and setmakeIPTablesUtilChains: true:sudo sed -i '/^makeIPTablesUtilChains:/d' /var/lib/kubelet/config.yamlecho 'makeIPTablesUtilChains: true' | sudo tee -a /var/lib/kubelet/config.yamlIf the file is in JSON format instead (e.g.
/etc/kubernetes/kubelet/kubelet-config.json), ensure it contains:"makeIPTablesUtilChains": true -
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 || trueIf 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 -
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.confon the worker node:sudo sed -i 's/--make-iptables-util-chains[=:][^[:space:]]*//g' /etc/systemd/system/kubelet.service.d/10-kubelet-args.confsudo sed -i 's#\(KUBELET_ARGS=".*\)"#\1 --make-iptables-util-chains=true"#' /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf -
Restart kubelet on the worker node to apply changes:
sudo systemctl daemon-reloadsudo systemctl restart kubelet.servicesudo systemctl status kubelet -l -
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:8001export 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."