Skip to main content

Streaming Connection Idle Timeout Argument Is Not Set 0

More Info:​

Do not disable timeouts on streaming connections.

Risk Level​

Medium

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)
  • Essential 8
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • 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 whether kubelet is using a config file and/or args file:

    ps -fC kubelet
    ls -l /var/lib/kubelet/config.yaml /etc/kubernetes/kubelet-config.yaml /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
  2. If /var/lib/kubelet/config.yaml (or /etc/kubernetes/kubelet-config.yaml if that’s what your node uses) exists and contains streamingConnectionIdleTimeout, edit it so it is set to a non-zero value:

    sudo sed -i 's/^\(\s*streamingConnectionIdleTimeout:\s*\).*/\1"4h0m0s"/' /var/lib/kubelet/config.yaml

    If the key is missing, add it under the top-level kubelet config section, for example:

    sudo sh -c 'printf "\nstreamingConnectionIdleTimeout: \"4h0m0s\"\n" >> /var/lib/kubelet/config.yaml'
  3. Ensure no command-line flag overrides the config: edit the kubelet systemd drop-in on every worker node and remove any --streaming-connection-idle-timeout entry:

    sudo vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf

    Delete --streaming-connection-idle-timeout=0 (or any value) from the KUBELET_ARGS line, or update it to --streaming-connection-idle-timeout=4h0m0s if you are managing this setting only via args.

  4. Reload systemd and restart kubelet on every worker node (this will briefly disrupt kubelet on the node):

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
    sudo systemctl status kubelet -l
  5. (Optional, if configz is enabled) From any machine with kubectl access, verify the live kubelet config includes a non-zero timeout:

    kubectl proxy --port=8001 &
    export HOSTNAME_PORT=localhost:8001
    export NODE_NAME="<node-name-from-kubectl-get-nodes>"
    curl -sSL "http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz" | grep -i streamingConnectionIdleTimeout
  6. Verification (on every worker node): confirm kubelet is running and no --streaming-connection-idle-timeout=0 is present in its arguments:

    /bin/ps -fC kubelet
Using kubectl

kubectl cannot modify kubelet’s host-level configuration, including /var/lib/kubelet/config.yaml or the systemd unit files on worker nodes where --streaming-connection-idle-timeout is set. To remediate this finding, make the changes directly on each worker node’s filesystem and systemd configuration as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Remediate CIS GKE 3.2.5 on every worker node:
# Ensure streamingConnectionIdleTimeout is non-zero for kubelet.
#
# RUN ON: each worker node (over SSH, or via your automation system).
# SAFE TO RE-RUN.

set -euo pipefail

KUBELET_CONFIG_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"
BACKUP_SUFFIX="$(date +%Y%m%d%H%M%S)"
DESIRED_TIMEOUT="4h0m0s"

echo "[$(hostname)] Starting remediation for kubelet streamingConnectionIdleTimeout..."

#--- Helper: backup file once per run -----------------------------------------
backup_file() {
local f="$1"
if [ -f "$f" ]; then
local b="${f}.${BACKUP_SUFFIX}.bak"
cp -p "$f" "$b"
echo "[$(hostname)] Backed up ${f} to ${b}"
fi
}

#--- Step 1: Remove any CLI override for --streaming-connection-idle-timeout ---
if [ -f "$SYSTEMD_DROPIN_FILE" ]; then
if grep -q -- '--streaming-connection-idle-timeout' "$SYSTEMD_DROPIN_FILE"; then
echo "[$(hostname)] Found --streaming-connection-idle-timeout in ${SYSTEMD_DROPIN_FILE}, removing..."
backup_file "$SYSTEMD_DROPIN_FILE"
# Remove only the argument, keep other args intact
# Handles spaces and optional quotes around KUBELET_ARGS
sed -i 's/\(^.*KUBELET_ARGS=.*\)--streaming-connection-idle-timeout=[^" ]*\(.*$\)/\1\2/' "$SYSTEMD_DROPIN_FILE"
# Clean up any double spaces left behind
sed -i 's/ / /g' "$SYSTEMD_DROPIN_FILE"
else
echo "[$(hostname)] No --streaming-connection-idle-timeout flag in ${SYSTEMD_DROPIN_FILE}."
fi
else
echo "[$(hostname)] ${SYSTEMD_DROPIN_FILE} not present; skipping CLI flag cleanup."
fi

#--- Step 2: Ensure config file sets streamingConnectionIdleTimeout -----------
if [ -f "$KUBELET_CONFIG_FILE" ]; then
echo "[$(hostname)] Ensuring streamingConnectionIdleTimeout is set in ${KUBELET_CONFIG_FILE}..."
backup_file "$KUBELET_CONFIG_FILE"

# If key exists, replace its value; otherwise, append in a simple YAML-safe way.
if grep -qE '^\s*streamingConnectionIdleTimeout\s*:' "$KUBELET_CONFIG_FILE"; then
# Replace existing value with desired timeout
sed -i "s/^\(\s*streamingConnectionIdleTimeout\s*:\s*\).*/\1\"${DESIRED_TIMEOUT}\"/" "$KUBELET_CONFIG_FILE"
else
# Append at the end of the file
printf "\nstreamingConnectionIdleTimeout: \"%s\"\n" "${DESIRED_TIMEOUT}" >> "$KUBELET_CONFIG_FILE"
fi
else
echo "[$(hostname)] WARNING: ${KUBELET_CONFIG_FILE} not found; cannot apply Method 1 remediation."
fi

#--- Step 3: Reload and restart kubelet --------------------------------------
echo "[$(hostname)] Reloading systemd and restarting kubelet..."
systemctl daemon-reload
systemctl restart kubelet.service

echo "[$(hostname)] Checking kubelet status..."
systemctl status kubelet -l --no-pager || {
echo "[$(hostname)] ERROR: kubelet did not start cleanly; investigate logs."
exit 1
}

#--- Step 4: Verification (adapted from audit) --------------------------------
echo "[$(hostname)] Verifying remediation with ps and config file..."

# Check process args to confirm no --streaming-connection-idle-timeout=0
if /bin/ps -fC kubelet | grep -q -- '--streaming-connection-idle-timeout=0'; then
echo "[$(hostname)] ERROR: kubelet still running with --streaming-connection-idle-timeout=0"
/bin/ps -fC kubelet
exit 1
fi

# If process flag exists but non-zero, this is acceptable per remediation method 2;
# however, primary goal is to avoid value 0.
if /bin/ps -fC kubelet | grep -q -- '--streaming-connection-idle-timeout'; then
echo "[$(hostname)] kubelet is using a non-zero --streaming-connection-idle-timeout flag (Method 2 in effect)."
else
# Otherwise rely on config file (Method 1)
if [ -f "$KUBELET_CONFIG_FILE" ]; then
if grep -qE "^\s*streamingConnectionIdleTimeout\s*:\s*\"${DESIRED_TIMEOUT}\"" "$KUBELET_CONFIG_FILE"; then
echo "[$(hostname)] kubelet configuration file sets streamingConnectionIdleTimeout=${DESIRED_TIMEOUT}."
else
echo "[$(hostname)] WARNING: streamingConnectionIdleTimeout not confirmed in ${KUBELET_CONFIG_FILE}."
grep -n 'streamingConnectionIdleTimeout' "$KUBELET_CONFIG_FILE" || true
exit 1
fi
fi
fi

echo "[$(hostname)] Remediation complete and verified."

Additional Reading:​