Skip to main content

Ensure Make Iptables Util Chains Argument Is Enabled

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 OKE
  • 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, open the kubelet systemd drop-in file for editing:

    sudo vi /etc/systemd/system/kubelet.service.d/00-default.conf
  2. In the ExecStart= line, ensure the kubelet is started with --make-iptables-util-chains=true. For example, add it if missing:

    ExecStart=/usr/bin/kubelet \
    --make-iptables-util-chains=true \
    $KUBELET_EXTRA_ARGS

    Save and exit.

  3. If /var/lib/kubelet/config.yaml exists and you manage kubelet via the config file, ensure the setting is also present there (still on every worker node):

    sudo vi /var/lib/kubelet/config.yaml

    Add or update this YAML field under the top-level config (if supported in your version):

    makeIPTablesUtilChains: true

    Save and exit.

  4. Reload systemd and restart kubelet to apply the changes (every worker node):

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
  5. Confirm kubelet is running correctly (every worker node):

    sudo systemctl status kubelet -l
  6. Verify the kubelet process now includes --make-iptables-util-chains=true (every worker node):

    /bin/ps -fC kubelet

    Ensure the output shows --make-iptables-util-chains=true in the kubelet command line.

Using kubectl

kubectl cannot modify kubelet startup flags or host-level configuration files such as /etc/systemd/system/kubelet.service.d/00-default.conf or /var/lib/kubelet/config.yaml. To enable --make-iptables-util-chains=true, changes must be made directly on every worker node’s host configuration; refer to the Manual Steps section for the exact procedure.

Automation
#!/usr/bin/env bash
# Remediation for CIS OKE 3.2.6: Ensure --make-iptables-util-chains=true for kubelet
# Target: run on every worker node (as root)
set -euo pipefail

UNIT_DIR="/etc/systemd/system/kubelet.service.d"
UNIT_FILE="${UNIT_DIR}/00-default.conf"
ARG="--make-iptables-util-chains=true"

echo "[INFO] Ensuring kubelet systemd drop-in exists at ${UNIT_FILE}"
if [[ ! -d "${UNIT_DIR}" ]]; then
mkdir -p "${UNIT_DIR}"
fi

if [[ ! -f "${UNIT_FILE}" ]]; then
cat > "${UNIT_FILE}" <<'EOF'
[Service]
Environment="KUBELET_EXTRA_ARGS=
"
EOF
echo "[INFO] Created new ${UNIT_FILE} with KUBELET_EXTRA_ARGS stub"
fi

echo "[INFO] Ensuring ${ARG} is present in KUBELET_EXTRA_ARGS in ${UNIT_FILE}"

# Ensure KUBELET_EXTRA_ARGS line exists
if ! grep -q '^Environment="KUBELET_EXTRA_ARGS=' "${UNIT_FILE}"; then
# Append a new line if not present
printf '\n[Service]\nEnvironment="KUBELET_EXTRA_ARGS="\n' >> "${UNIT_FILE}"
fi

# Normalize KUBELET_EXTRA_ARGS line into a temp file
TMP_FILE="$(mktemp)"
trap 'rm -f "${TMP_FILE}"' EXIT

awk -v arg="${ARG}" '
BEGIN { updated=0 }
/^Environment="KUBELET_EXTRA_ARGS=/ {
line=$0
# Strip prefix and trailing quote
sub(/^Environment="KUBELET_EXTRA_ARGS=/, "", line)
sub(/"$/, "", line)

# If arg is missing, append it
found=0
n=split(line, a, " ")
for (i=1; i<=n; i++) {
if (a[i] == arg) {
found=1
break
}
}
if (!found) {
if (length(line) == 0) {
line=arg
} else {
line=line" "arg
}
updated=1
}
print "Environment=\"KUBELET_EXTRA_ARGS=" line "\""
next
}
{ print }
END {
if (updated==1) {
# nothing extra to print; message handled outside awk
}
}
' "${UNIT_FILE}" > "${TMP_FILE}"

if ! cmp -s "${UNIT_FILE}" "${TMP_FILE}"; then
echo "[INFO] Updating ${UNIT_FILE} with ${ARG}"
cp "${TMP_FILE}" "${UNIT_FILE}"
else
echo "[INFO] ${ARG} already present; no change to ${UNIT_FILE}"
fi

echo "[INFO] Reloading systemd and restarting kubelet (this will restart kubelet on this node)"
systemctl daemon-reload
systemctl restart kubelet.service

echo "[INFO] Verifying kubelet is running with ${ARG}"
/bin/ps -fC kubelet || {
echo "[ERROR] kubelet process not found after restart"
exit 1
}

if /bin/ps -fC kubelet | grep -q -- "${ARG}"; then
echo "[SUCCESS] kubelet is running with ${ARG}"
exit 0
else
echo "[ERROR] kubelet is NOT running with ${ARG}. Current kubelet command line:"
/bin/ps -fC kubelet || true
exit 1
fi

Additional Reading: