| name | performing-kubernetes-etcd-security-assessment |
| description | Assess the security posture of Kubernetes etcd clusters by evaluating encryption at rest, TLS configuration, access controls, backup encryption, and network isolation. |
| domain | cybersecurity |
| subdomain | container-security |
| tags | ["kubernetes","etcd","encryption","tls","security-assessment","backup","secrets","control-plane"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
| nist_csf | ["PR.PS-01","PR.IR-01","ID.AM-08","DE.CM-01"] |
| mitre_attack | ["T1610","T1611","T1609","T1525","T1573"] |
Performing Kubernetes etcd Security Assessment
Overview
etcd is the distributed key-value store that serves as Kubernetes' backing store for all cluster data, including Secrets, RBAC policies, ConfigMaps, and workload configurations. Without proper hardening, etcd exposes all cluster secrets in plaintext, making it the highest-value target for attackers who gain control plane access. A comprehensive security assessment covers encryption at rest, TLS for transport, access control, backup security, and network isolation.
When to Use
- When conducting security assessments that involve performing kubernetes etcd security assessment
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
Prerequisites
- Access to Kubernetes control plane nodes
- SSH access to etcd cluster nodes (or etcdctl configured)
- CIS Kubernetes Benchmark reference document
- Understanding of TLS certificate management and EncryptionConfiguration
Assessment Areas
1. Encryption at Rest
Verify that Kubernetes encrypts Secret data stored in etcd:
ps aux | grep kube-apiserver | grep encryption-provider-config
cat /etc/kubernetes/enc/encryption-config.yaml
Expected secure configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}
Verify secrets are actually encrypted in etcd:
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
get /registry/secrets/default/my-secret | hexdump -C | head -20
2. TLS Transport Security
ETCDCTL_API=3 etcdctl endpoint health \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
ps aux | grep etcd | tr ' ' '\n' | grep -E "peer-cert|peer-key|peer-trusted-ca"
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -enddate
openssl x509 -in /etc/kubernetes/pki/etcd/peer.crt -noout -enddate
Expected flags:
| Flag | Required Value | Purpose |
|---|
--cert-file | Path to server cert | Client-to-server TLS |
--key-file | Path to server key | Client-to-server TLS |
--trusted-ca-file | Path to CA cert | Client certificate validation |
--peer-cert-file | Path to peer cert | Peer-to-peer TLS |
--peer-key-file | Path to peer key | Peer-to-peer TLS |
--peer-trusted-ca-file | Path to peer CA | Peer certificate validation |
--client-cert-auth | true | Require client certificates |
--peer-client-cert-auth | true | Require peer certificates |
3. Access Control
ps aux | grep etcd | tr ' ' '\n' | grep listen-client-urls
ls -la /etc/kubernetes/pki/etcd/
ss -tlnp | grep 2379
4. Backup Security
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
gpg --symmetric --cipher-algo AES256 /backup/etcd-snapshot.db
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot.db --write-out=table
5. Network Isolation
iptables -L -n | grep -E "2379|2380"
curl -k https://<control-plane-ip>:2379/health
CIS Benchmark Checks
| CIS Control | Check | Expected Result |
|---|
| 2.1 | etcd cert-file set | TLS certificate configured |
| 2.2 | etcd client-cert-auth | Client certificate authentication enabled |
| 2.3 | etcd auto-tls disabled | auto-tls=false |
| 2.4 | etcd peer cert-file set | Peer TLS configured |
| 2.5 | etcd peer client-cert-auth | Peer authentication enabled |
| 2.6 | etcd peer auto-tls disabled | peer-auto-tls=false |
| 2.7 | etcd unique CA | Separate CA for etcd (not shared with cluster) |
Key Rotation Procedure
NEW_KEY=$(head -c 32 /dev/urandom | base64)
cat > /etc/kubernetes/enc/encryption-config.yaml <<EOF
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key2
secret: ${NEW_KEY}
- name: key1
secret: <old-key>
- identity: {}
EOF
kubectl get secrets --all-namespaces -o json | \
kubectl replace -f -
References