Cluster Hardening #
Keamanan aplikasi yang berjalan di Kubernetes bergantung juga pada keamanan cluster itu sendiri. API Server yang tidak terlindungi, etcd yang bisa diakses sembarangan, atau kubelet yang mengizinkan akses anonymous adalah celah yang bisa dieksploitasi untuk mengakses seluruh cluster. Artikel ini membahas langkah-langkah hardening di level cluster — di luar aplikasi dan Pod.
Mengamankan API Server #
API Server adalah komponen yang paling banyak terekspos. Konfigurasi yang salah di sini adalah kegagalan keamanan yang fundamental.
Konfigurasi API Server yang harus diverifikasi:
1. Anonymous auth dinonaktifkan
--anonymous-auth=false
→ Semua request harus autentikasi; tidak ada akses tanpa identitas
2. RBAC sebagai authorization mode
--authorization-mode=Node,RBAC
→ Jangan gunakan AlwaysAllow atau ABAC
3. Admission controllers yang diaktifkan
--enable-admission-plugins=NodeRestriction,PodSecurity,...
4. Audit logging aktif
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--audit-log-path=/var/log/kubernetes/audit.log
5. TLS untuk semua komunikasi
--tls-cert-file, --tls-private-key-file (sudah default di cluster modern)
--client-ca-file (untuk client certificate auth)
6. Etcd connection menggunakan TLS
--etcd-certfile, --etcd-keyfile, --etcd-cafile
# Verifikasi konfigurasi API Server (self-managed cluster)
kubectl get pod kube-apiserver-<node> -n kube-system -o yaml | \
grep -A 50 "command:"
Mengamankan Etcd #
Etcd menyimpan seluruh state cluster termasuk Secret (meski hanya base64). Akses langsung ke etcd melewati semua RBAC dan audit logging.
Proteksi etcd:
1. Akses hanya dari API Server
Etcd harus listen hanya di loopback atau interface internal
Port 2379 (client) dan 2380 (peer) tidak boleh accessible dari luar
2. TLS mutual authentication
Hanya API Server dengan certificate yang tepat bisa connect ke etcd
3. Enkripsi at-rest
Aktifkan enkripsi Secret di etcd via EncryptionConfiguration
(dibahas di artikel Secret Management)
4. Backup terenkripsi
Backup etcd secara regular dan simpan di tempat yang aman
Backup mengandung semua Secret cluster — perlakukan seperti data kritikal
# Verifikasi etcd hanya listen di interface yang tepat
# Di node control plane:
ss -tlnp | grep 2379
# Harus: 127.0.0.1:2379 atau IP internal, BUKAN 0.0.0.0:2379
# Cek apakah etcd menggunakan TLS
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 \
endpoint health
Hardening Kubelet #
Kubelet berjalan di setiap node dan punya akses langsung ke container runtime. Konfigurasi default bisa terlalu permisif.
# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
anonymous:
enabled: false # nonaktifkan anonymous auth
webhook:
enabled: true # autentikasi via API Server
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook # otorisasi via API Server (bukan AlwaysAllow)
readOnlyPort: 0 # nonaktifkan readonly port (port 10255)
protectKernelDefaults: true # protect kernel defaults dari modifikasi
eventRecordQPS: 5
rotateCertificates: true # rotasi sertifikat otomatis
# Verifikasi kubelet config
ssh worker-node-1
cat /var/lib/kubelet/config.yaml
# Verifikasi readonly port tidak aktif
curl http://worker-node-1:10255/pods # harus gagal/tidak accessible
Admission Controllers #
Admission controllers memproses request ke API Server setelah autentikasi dan otorisasi tapi sebelum objek disimpan ke etcd. Mereka bisa memvalidasi atau memodifikasi request.
Admission controllers yang direkomendasikan:
NodeRestriction:
→ Batasi kubelet agar hanya bisa modify node dan Pod yang ada di node-nya
→ Mencegah node yang dikompromis memodifikasi resource node lain
PodSecurity:
→ Enforce Pod Security Standards (Privileged/Baseline/Restricted)
→ Menggantikan PodSecurityPolicy yang sudah deprecated
ResourceQuota:
→ Pastikan Pod memiliki resource requests/limits
→ Cegah denial-of-service dari resource yang tidak terbatas
LimitRanger:
→ Set default resource limits untuk Pod yang tidak mendefinisikannya
MutatingAdmissionWebhook + ValidatingAdmissionWebhook:
→ Untuk custom policy enforcement (Kyverno, OPA/Gatekeeper)
# Cek admission plugins yang aktif
kubectl get pod kube-apiserver-<node> -n kube-system -o yaml | \
grep "enable-admission-plugins"
Node Security #
# Minimal node hardening:
# 1. OS tetap up-to-date
apt update && apt upgrade -y # atau yum update -y
# 2. Matikan service yang tidak dibutuhkan
systemctl disable bluetooth cups avahi-daemon
# 3. Konfigurasi firewall (hanya izinkan port Kubernetes yang dibutuhkan)
ufw allow 6443/tcp # API Server
ufw allow 2379/tcp # etcd client (hanya dari API Server)
ufw allow 10250/tcp # kubelet API (hanya dari API Server)
ufw allow 30000:32767/tcp # NodePort range
# 4. Nonaktifkan SSH password auth, gunakan key-based
# /etc/ssh/sshd_config:
# PasswordAuthentication no
# PermitRootLogin no
# 5. Audit tool untuk cek security posture node
lynis audit system # atau CIS-CAT
CIS Kubernetes Benchmark #
CIS (Center for Internet Security) menerbitkan benchmark untuk Kubernetes dengan ratusan check. Gunakan kube-bench untuk automated verification:
# Jalankan kube-bench di control plane node
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl logs job.batch/kube-bench
# Output:
# [PASS] 1.1.1 Ensure that the API server pod specification file permissions are set to 600 or more restrictive
# [FAIL] 1.1.2 Ensure that the API server pod specification file ownership is set to root:root
# [WARN] 1.2.1 Ensure that the --anonymous-auth argument is set to false
# ...
# == Summary master ==
# 42 checks PASS
# 8 checks FAIL
# 12 checks WARN
Update dan Patch Management #
Kebijakan update yang direkomendasikan:
Kubernetes version:
→ Upgrade setidaknya setiap 3-4 bulan
→ Kubernetes mendukung 3 versi minor terbaru
→ Setelah itu: security fix tidak backport
Node OS:
→ Security patch dalam 48-72 jam setelah release
→ Automated dengan unattended-upgrades atau Ansible
Container images:
→ Rebuild image secara berkala meski tidak ada perubahan kode
→ Base image update otomatis via Dependabot atau Renovate
→ Scan CVE setelah setiap build
etcd:
→ Upgrade bersamaan dengan Kubernetes (kurang lebih)
→ Selalu backup sebelum upgrade
Ringkasan #
- API Server: nonaktifkan anonymous auth, gunakan RBAC — dua konfigurasi ini menutup celah paling fundamental;
--anonymous-auth=falsedan--authorization-mode=Node,RBAC.- Etcd tidak boleh accessible dari luar cluster — port 2379/2380 hanya untuk loopback atau interface internal; backup etcd harus diperlakukan seperti data Secret.
- Kubelet: nonaktifkan anonymous auth dan readonly port —
authentication.anonymous.enabled: falsedanreadOnlyPort: 0di kubelet config.- Admission controllers untuk policy enforcement — NodeRestriction, PodSecurity, dan ResourceQuota adalah minimum; tambahkan Kyverno atau OPA untuk custom policy.
- kube-bench untuk audit CIS compliance — automated check terhadap ratusan benchmark item; jalankan setelah setup dan secara berkala.
- Update kubernetes dan node OS secara regular — security patch harus diterapkan dalam 48-72 jam; Kubernetes versi lebih dari 3 minor release ke belakang tidak mendapat security fix.
← Sebelumnya: Audit Logging Berikutnya: Anti-Pattern Security →