Skip to main content

More Info:

Kubelet HTTP endpoints transmit credentials and pod data in cleartext and bypass authentication. Force HTTPS-only listeners so all kubelet traffic is encrypted and authenticated.

Risk Level

Critical

Address

Compliance, Security

Compliance Standards

  • CIS OKE

Triage and Remediation

Remediation

Using Console

To ensure OKE kubelets only serve HTTPS (and disable the insecure/read‑only HTTP port), you must configure the kubelet options on the node pool. This is done from the OCI Console at the node pool level.A. Check current node pool kubelet settings
  1. Sign in to the OCI Console.
  2. Go to Developer Services → Kubernetes Clusters (OKE).
  3. Select your compartment and then your cluster.
  4. In the cluster details page, open the Node Pools tab.
  5. Click the node pool you want to harden.
  6. Look for Kubelet configuration or Kubelet security settings (the exact label depends on OKE version).
    • If you see options like “Enable Kubelet read-only port” or “Enable anonymous access”, and they are enabled, the kubelet can serve HTTP traffic on the insecure/read‑only port (typically 10255).
If these settings are already disabled, the kubelet is serving only HTTPS, and you’re done.
B. Update the node pool so kubelet uses HTTPS onlyIn most OKE versions, kubelet insecure/read‑only port settings are immutable for existing nodes. The secure practice is to create a new node pool with hardened kubelet settings, then drain and delete the old one.

1. Create a new hardened node pool

  1. From the same cluster details page, go to Node Pools → Create node pool.
  2. Configure:
    • Compartment, Name, Kubernetes version, Subnet(s), Shape, etc., to match your existing worker configuration (or your desired new config).
  3. Scroll to Kubelet configuration / Kubelet security settings:
    • Uncheck / Disable:
      • Enable Kubelet read-only port (or similar wording).
        • This disables the HTTP read-only port (typically 10255).
      • Any anonymous access setting (e.g., --anonymous-auth=false is desired).
    • Ensure:
      • Only the secure kubelet port (10250) is enabled.
      • TLS remains enabled (default in OKE).
  4. Complete the rest of the wizard and click Create.
  5. Wait until the new node pool status is Active and nodes are Ready in the Kubernetes cluster (kubectl get nodes).

2. Move workloads to the new node pool

  1. Cordon and drain old nodes (from your workstation with kubeconfig):
  2. Make sure your deployments / node selectors / taints allow scheduling onto the new node pool.
    • If you use nodePoolId / oci.oraclecloud.com/metadata or other labels, update them or add labels to the new nodes and adjust selectors.
  3. Confirm pods are running on the new nodes:

3. Delete the old node pool

  1. In the OCI Console, return to the Node Pools list for the cluster.
  2. Confirm that workloads are running on the new node pool only.
  3. Select the old node pool → Delete.
  4. Wait for the deletion to complete.

C. (Optional) Network-level enforcementTo further ensure no HTTP access to kubelet:
  1. Identify the security lists/NSGs attached to the worker subnets.
  2. In Networking → Virtual Cloud Networks → [Your VCN] → Subnets / NSGs:
    • Confirm there are no ingress rules allowing traffic to:
      • Port 10255 (kubelet read‑only, HTTP).
    • Allow only:
      • Port 10250 from control plane CIDRs (as required by OKE), not from the public internet.

After the new node pool is in place with kubelet read‑only port disabled and network rules tightened, all kubelet traffic will be restricted to HTTPS (TLS on 10250) only.
In OKE, kubelets already serve HTTPS on port 10250. The usual “HTTP only” risk comes from the legacy read-only HTTP port (10255). The practical remediation is to ensure kubelet’s readOnlyPort is disabled (set to 0) across all worker nodes. With managed nodes you do this via the node pool (so new/replaced nodes come up correctly), using the OCI CLI.Below is a concise, CLI‑only way to do that.

1. Prepare a cloud‑init script to harden kubelet

Create a file kubelet-hardening.yaml:
Base64‑encode it for use as user_data:
On macOS:

2. Identify your node pool

Copy the id of the node pool you want to harden:

3. Merge user_data into node pool metadata via OCI CLI

  1. Fetch current node pool JSON:
  1. Extract existing node metadata (if any):
  1. Create a new metadata JSON that includes/overrides user_data:
  1. Save it:
  1. Update the node pool:
This ensures all new or replaced nodes in this pool run the hardening script on boot, disabling the HTTP port.

4. Recycle nodes so the change takes effect

For existing nodes, the new user_data only runs on (re)provisioning. Use oci ce node-pool or oci compute instance to rotate nodes:List nodes in the node pool:
Then, one by one (to avoid downtime):
Repeat for all nodes, or use your usual rolling‑update procedure.

5. Verify kubelet only serves HTTPS

SSH to a node and verify:
Optionally check /var/lib/kubelet/config.yaml:
At that point, kubelet will only be serving over HTTPS (port 10250), and the insecure HTTP port is disabled.
To ensure kubelet only serves HTTPS in OCI OKE, the practical remediation you can do yourself is to block/disable HTTP (read-only kubelet port 10255) at the network level using OCI Security Lists or NSGs via the OCI Python SDK.Below is a step‑by‑step outline and a Python example.

1. Understand what needs to be blocked

Kubelet typically uses:
  • Port 10250 (HTTPS) – secure kubelet API (keep this, but restrict who can access it).
  • Port 10255 (HTTP, read-only) – insecure kubelet API (must be blocked).
On OKE managed worker nodes, you usually cannot directly edit kubelet flags, so the standard hardening approach is to block 10255 via network rules.

2. Identify the subnet / NSG / security list used by worker nodes

  1. Go to your OKE cluster in OCI Console.
  2. Check each Node Pool → Subnets used for worker nodes.
  3. For each subnet, note:
    • Its OCID.
    • Whether it uses:
      • NSGs (preferred), or
      • Security Lists.
You will modify whichever is in use.

3. Python SDK setup

Install SDK if needed:
Ensure ~/.oci/config is set up (with tenancy, user, fingerprint, private_key, region, and profile).

4. Example: Block kubelet HTTP (10255) on a Security List via Python

This example:
  • Reads an existing security list.
  • Removes any ingress on TCP/10255 (and optionally any unrestricted 10250).
  • Updates the security list.

5. Example: Block kubelet HTTP (10255) on an NSG via Python

If your worker nodes use NSGs:

6. Verify

  1. From a pod or external host, try:
    • curl http://<worker-node-ip>:10255/healthz → should fail.
    • curl https://<worker-node-ip>:10250/healthz (with proper auth/cert) → should work but only from allowed sources.
  2. Optionally run your security scanner again to confirm remediation.

If you share whether your worker nodes are using Security Lists or NSGs (and how 10255 is currently allowed), I can tailor the Python snippet exactly to your setup.