> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OCI OKE Kubelet streamingConnectionIdleTimeout Should Not Be 0

### 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        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 Services** → **Kubernetes 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 Options** → **Kubelet 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 Options** → **Kubelet 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:
           ```bash theme={null}
           kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
           ```
        3. After the new node joins:
           ```bash theme={null}
           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:
           ```bash theme={null}
           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.:
           ```bash theme={null}
           ps aux | grep kubelet | grep streaming-connection-idle-timeout
           ```
           You should see something like:
           ```text theme={null}
           --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.
      </Accordion>

      <Accordion title="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.
      </Accordion>

      <Accordion title="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:
          ```bash theme={null}
          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.

        ```python theme={null}
        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.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # 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.
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
