Skip to main content
cd ../config-traps
risk/register/kubernetes-etcd-on-2379-no-client-cert-no-cluster.html
Kubernetes Cluster Securitycritical severityKubernetes etcd

Kubernetes etcd on 2379: No Client Cert, No Cluster

Severity
critical
Reviewed
12 Jul 2026
Remediation
~20 minutes
Overview

etcd's client port 2379 accepts unauthenticated connections when -client-cert-auth is false or unset, leaving only transport encryption in place. Anyone reaching the port dumps every Secret, ServiceAccount token, and RBAC object, then writes forged ClusterRoleBindings directly into the Raft log, bypassing the API server and audit trail entirely.

Operational summary

At a glance

Symptom
Broad security group or flat pod network reaches port 2379, allowing unauthenticated etcdctl calls against the datastore
Likely cause
etcd client listener without --client-cert-auth=true, bound to 0.0.0.0 instead of a scoped private interface
Impact
Full Secret and RBAC exfiltration plus forged ClusterRoleBindings written straight into Raft, invisible to API server audit logs.
Verification signal
Re-run the detection test and a controlled negative-path test.
Safe correction
Enable --client-cert-auth and --peer-client-cert-auth, bind listeners to private interfaces, restrict CIDR, and enable EncryptionConfiguration for Secrets.
Rollback or recovery
Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.

The Trap

etcd exposed on port 2379 without –client-cert-auth enabled, meaning transport is TLS-encrypted but not mutually authenticated, so any TCP connection reaching the listener can issue raw etcd API calls against the cluster’s backing store.

The Default State

kubeadm-bootstrapped clusters generate etcd certificates automatically, but self-managed installs using bare binaries, kops, kubespray templates, or bring-your-own-etcd Helm charts frequently leave –client-cert-auth=false or omit the flag, relying only on –cert-file and –key-file for encryption without mutual auth. Because –listen-client-urls defaults to binding all interfaces rather than the node’s private address, and cloud security groups are often opened for a broad “control plane” CIDR rather than scoped to the three API server IPs, the client port ends up reachable from the pod network, and sometimes from the VPC at large.

The Blast Radius

An attacker with reach to 2379 runs etcdctl –insecure-skip-tls-verify get / –prefix –keys-only and enumerates every key in the cluster: Secrets in base64 (unencrypted by default without an EncryptionConfiguration resource), ServiceAccount tokens, TLS private keys stored as Secrets, and the full RBAC graph. From there they mint a kubeconfig from a captured cluster-admin-bound token, or write directly into etcd with etcdctl put to fabricate a ClusterRoleBinding, bypassing the API server’s admission chain and audit log entirely. Writes land straight in the Raft log, and kube-apiserver picks up the forged object on its next watch cycle with no webhook check, no PodSecurity evaluation, and no entry beyond etcd’s own logs, which most SOC pipelines never ingest.

The Lead Mechanic Fix

Enforce mutual TLS on every etcd member: set –client-cert-auth=true, –trusted-ca-file, –cert-file, –key-file for the client listener, and –peer-client-cert-auth=true with matching peer flags for inter-member traffic. Bind –listen-client-urls to the node’s private interface only, never 0.0.0.0, and restrict the security group or NetworkPolicy to the exact API server IPs on 2379 and 2380. Apply an EncryptionConfiguration using aescbc or a KMS provider so Secrets are encrypted at the API server layer as a second control, and rotate the etcd CA if any exposure window existed. Confirm with etcdctl –insecure-skip-tls-verify endpoint health run from outside the allowed CIDR; it must fail closed with connection refused, not a TLS handshake.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Control to implement

Enable --client-cert-auth and --peer-client-cert-auth, bind listeners to private interfaces, restrict CIDR, and enable EncryptionConfiguration for Secrets.

Validate the vendor-specific syntax in official documentation before applying it.

04

Verify, roll back or escalate

Verify

Re-run the detection test and a controlled negative-path test. Confirm the unsafe behaviour is blocked while approved traffic still succeeds.

Rollback

Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources