Skip to main content

OCI OKE Kubelet streamingConnectionIdleTimeout Should Not

More Info:

Setting streamingConnectionIdleTimeout to 0 disables idle connection timeout for kubectl exec, attach and port-forward sessions, which can be abused for long-lived covert channels. A non-zero value (default 4h) limits exposure.

Risk Level

Medium

Address

Compliance, Security

Compliance Standards

  • CIS OKE

Triage and Remediation

Remediation

Using Console

Below are the console-based steps to remediate this in Oracle Container Engine for Kubernetes (OKE) by setting a non‑zero streamingConnectionIdleTimeout on the kubelet.

Goal: Ensure kubelet’s streaming-connection-idle-timeout is not 0 on worker nodes by updating node pool kubelet configuration and then rolling nodes.


1. Confirm which node pool(s) are affected

  1. Sign in to the OCI Console.
  2. Open the navigation menu → Developer ServicesKubernetes Clusters (OKE).
  3. Select your Compartment.
  4. Click the Cluster you’re auditing.
  5. Go to the Node Pools tab and identify the node pool(s) that correspond to the failing nodes.

2. Check if kubelet config is editable for the node pool

  1. Click on the Node Pool name.
  2. Click Edit (top-right).
  3. Scroll to Advanced OptionsKubelet configuration (or similar “Kubelet config / Worker node configuration” area).
    • If you see fields for kubelet parameters, proceed.
    • If not editable (e.g., older pool type), you must create a new node pool with the correct settings (see step 3B).

3A. Edit kubelet config on an existing node pool (if allowed)

  1. In the Edit Node Pool page, under kubelet settings, locate:
    • Streaming Connection Idle Timeout or a similar field (may be expressed as 4h, 1h, etc.).
  2. Set a non-zero value (example: 4h is commonly used):
    • Example value: 4h
    • Any non-zero duration that meets your org’s security baseline is acceptable.
  3. Save the changes (Update Node Pool).

OKE will apply this config to new nodes in the node pool. Existing nodes need to be rotated.


3B. If kubelet config is not editable → create a new node pool

  1. In the cluster’s Node Pools tab, click Create node pool.
  2. Configure:
    • Kubernetes version, shape, subnets, etc., matching the existing node pool as appropriate.
  3. Under Advanced OptionsKubelet configuration:
    • Set Streaming Connection Idle Timeout to a non-zero duration (e.g., 4h).
  4. Click Create.
  5. Wait for the new node pool status to become Active.

4. Rotate/replace nodes so they inherit the new kubelet config

If you edited the existing node pool:

  1. From the Node Pool details page:
    • Either Scale down and back up the node pool, or
    • Terminate nodes one-by-one; new nodes will launch with the updated kubelet settings.
  2. Use kubectl drain (from your workstation) before terminating nodes to avoid workload disruption:
    kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
  3. After the new node joins:
    kubectl uncordon <new-node-name>

If you created a new node pool:

  1. Add the new node pool to the cluster and ensure auto-scaling / replicas are correct.
  2. Cordon and drain nodes in the old node pool and then terminate them.
  3. When workloads are stable on the new pool, you can delete the old node pool.

5. Validate the change

  1. Once new nodes are up, list nodes and pick one:
    kubectl get nodes -o wide
  2. SSH to the node (if allowed) or use logs/agent, then confirm kubelet arguments include a non-zero timeout, e.g.:
    ps aux | grep kubelet | grep streaming-connection-idle-timeout
    You should see something like:
    --streaming-connection-idle-timeout=4h0m0s
  3. Re-run your compliance scan to ensure the check “Kubelet streamingConnectionIdleTimeout Should Not Be 0” now passes.

If you share your OKE version and whether the node pools are managed/virtual nodes, I can give you the exact field names as they appear in your console screen.

Using CLI

For Oracle Container Engine for Kubernetes (OKE), this specific kubelet setting:

--streaming-connection-idle-timeout

is not exposed as a configurable parameter via OKE APIs, Terraform, or the OCI CLI on managed node pools as of my latest knowledge (mid‑2024). OKE manages kubelet flags internally, and there is no supported knob in:

  • oci ce cluster ...
  • oci ce node-pool ...
  • Node pool kubeletConfigDetails (which only covers a limited set of kubelet options like maxPodsPerNode, podsPerCore, etc.)

So:

  • You cannot remediate “Kubelet streamingConnectionIdleTimeout should not be 0” via OCI CLI on standard OKE managed node pools.
  • Any workaround would require unsupported modifications inside the node (e.g., editing the kubelet systemd unit or bootstrap scripts via cloud-init/user data), which can be overwritten on upgrade/repair and may be out of support with Oracle.

If you must satisfy this check:

  1. Confirm with OCI/OKE documentation or an Oracle SR whether support for this kubelet flag has been added.
  2. If not supported:
    • Mark this finding as not remediable / accepted risk for OKE managed nodes in your compliance tooling, or
    • Use self-managed Kubernetes on OCI Compute (where you control kubelet flags) instead of OKE for workloads that require strict control over this setting.

There is currently no valid OCI CLI sequence I can provide that will change streamingConnectionIdleTimeout for OKE-managed kubelets.

Using Python

To remediate this in OCI OKE, you must update your node pool(s) so the kubelet streamingConnectionIdleTimeout is set to a non-zero value (e.g., "4h"). In OKE this is done via the node pool’s kubelet configuration.

Below is a concise step‑by‑step guide using the OCI Python SDK.


1. Prerequisites

  • OCI Python SDK installed:
    pip install oci
  • OCI config file (~/.oci/config) with a profile that has permissions to manage OKE node pools.
  • Your:
    • compartment_id
    • cluster_id
    • OCI profile name (e.g., DEFAULT)

2. Decide on a non-zero timeout

Pick a valid Kubernetes duration string, e.g.:

  • "1h"
  • "2h"
  • "4h" (commonly used)
  • "30m"

OCI expects it as a string in that format.


3. Python script to update all node pools in a cluster

This script:

  1. Lists all node pools in a cluster.
  2. Updates each node pool’s kubelet config so streaming_connection_idle_timeout is non-zero.
import oci
from oci.container_engine import ContainerEngineClient
from oci.container_engine.models import (
UpdateNodePoolDetails,
UpdateNodePoolNodeConfigDetails,
KubeletConfig
)

# ==== CONFIGURE THESE VALUES ====
OCI_PROFILE = "DEFAULT"
CLUSTER_ID = "<your_cluster_ocid_here>"
NEW_TIMEOUT = "4h" # Set desired non-zero timeout
# ================================

def main():
# Load OCI config
config = oci.config.from_file("~/.oci/config", OCI_PROFILE)
ce_client = ContainerEngineClient(config)

# List node pools in the cluster
response = ce_client.list_node_pools(
compartment_id=config["tenancy"],
cluster_id=CLUSTER_ID
)

node_pools = response.data
if not node_pools:
print("No node pools found for cluster:", CLUSTER_ID)
return

for np in node_pools:
print(f"Processing node pool: {np.name} ({np.id})")

# Get current node pool details
np_details = ce_client.get_node_pool(np.id).data

# Read existing kubelet config if present
existing_node_config = np_details.node_config_details
existing_kubelet_config = getattr(existing_node_config, "kubelet_config", None) if existing_node_config else None

# Build new kubelet config, preserving other fields if they exist
if existing_kubelet_config:
kubelet_config = KubeletConfig(
cpu_manager_policy=existing_kubelet_config.cpu_manager_policy,
cpu_cfs_quota=existing_kubelet_config.cpu_cfs_quota,
cpu_cfs_quota_period=existing_kubelet_config.cpu_cfs_quota_period,
image_gc_high_threshold=existing_kubelet_config.image_gc_high_threshold,
image_gc_low_threshold=existing_kubelet_config.image_gc_low_threshold,
topology_manager_policy=existing_kubelet_config.topology_manager_policy,
allowed_unsafe_sysctls=existing_kubelet_config.allowed_unsafe_sysctls,
max_pods=existing_kubelet_config.max_pods,
pod_pids_limit=existing_kubelet_config.pod_pids_limit,
# Set the required field:
streaming_connection_idle_timeout=NEW_TIMEOUT
)
else:
kubelet_config = KubeletConfig(
streaming_connection_idle_timeout=NEW_TIMEOUT
)

# Build new node config details, preserving other fields
update_node_config = UpdateNodePoolNodeConfigDetails(
placement_configs=existing_node_config.placement_configs if existing_node_config else None,
size=existing_node_config.size if existing_node_config else None,
nsg_ids=existing_node_config.nsg_ids if existing_node_config else None,
kms_key_id=getattr(existing_node_config, "kms_key_id", None) if existing_node_config else None,
is_pv_encryption_in_transit_enabled=getattr(
existing_node_config,
"is_pv_encryption_in_transit_enabled",
None
) if existing_node_config else None,
boot_volume_size_in_gbs=getattr(existing_node_config, "boot_volume_size_in_gbs", None)
if existing_node_config else None,
kubelet_config=kubelet_config
)

update_details = UpdateNodePoolDetails(
node_config_details=update_node_config
)

# Call update_node_pool
update_response = ce_client.update_node_pool(
node_pool_id=np.id,
update_node_pool_details=update_details
)

work_request_id = update_response.headers.get("opc-work-request-id")
print(f"Update initiated for node pool {np.name} ({np.id}). Work request: {work_request_id}")

print("Update calls submitted. Monitor work requests in OCI Console or via SDK.")

if __name__ == "__main__":
main()

4. Notes

  • After updating, OKE will roll the node pool according to its upgrade/rolling rules; pods may be rescheduled.
  • If you only want to update specific node pools, filter by np.name or np.id instead of iterating over all.
Using Terraform
# As of the current Oracle/oci Terraform provider, the OKE node pool
# resource does not expose kubelet flags such as streamingConnectionIdleTimeout.
# There is no argument on oci_containerengine_node_pool (or related resources)
# that maps to this kubelet setting, so it cannot be remediated directly
# with Terraform on the oci-containers-oke-nodepool surface.

# You must currently remediate this via non‑Terraform means, for example:
# - In the OCI Console: edit the OKE node pool or underlying node bootstrap
# configuration so that kubelet is started with a non‑zero
# --streaming-connection-idle-timeout (e.g. 4h).
# - Or via custom cloud-init/bootstrapping scripts attached to the node
# pool, which modify the kubelet systemd unit or config file to set
# streamingConnectionIdleTimeout to a non-zero value.

# Since there is no Terraform argument, `terraform plan` will show no
# changes related to streamingConnectionIdleTimeout.