Pod Security #
Container yang berjalan tanpa konfigurasi keamanan yang tepat beroperasi dengan privilege yang jauh lebih besar dari yang dibutuhkan. Sebuah container yang berjalan sebagai root dengan akses penuh ke sistem file host adalah vektor serangan yang sangat besar — jika container tersebut di-compromise, penyerang berpotensi keluar dari container dan mengakses node atau cluster secara keseluruhan. SecurityContext adalah cara mendefinisikan aturan keamanan yang membatasi apa yang bisa dilakukan container.
SecurityContext: Pod vs Container Level #
SecurityContext bisa didefinisikan di dua level dengan scope yang berbeda:
spec:
# Pod-level: berlaku untuk semua container dalam Pod
securityContext:
runAsNonRoot: true # semua container harus bukan root
runAsUser: 1000 # jalankan sebagai UID 1000
runAsGroup: 3000 # GID untuk proses
fsGroup: 2000 # GID untuk volume yang di-mount
seccompProfile:
type: RuntimeDefault # aktifkan seccomp profile default
containers:
- name: api
# Container-level: override Pod-level untuk container ini
securityContext:
allowPrivilegeEscalation: false # WAJIB — cegah eskalasi privilege
readOnlyRootFilesystem: true # filesystem root read-only
capabilities:
drop:
- ALL # hapus semua Linux capabilities
add:
- NET_BIND_SERVICE # tambah kembali hanya yang dibutuhkan
Konfigurasi Paling Penting #
runAsNonRoot dan runAsUser #
securityContext:
runAsNonRoot: true # Kubernetes menolak container yang coba jalan sebagai root
runAsUser: 1000 # UID spesifik (bukan 0)
runAsGroup: 1000
Mengapa penting:
Container root (UID 0) = root di host jika container escape terjadi
Container non-root (UID 1000) = user biasa di host
→ Blast radius jauh lebih kecil jika terjadi container breakout
allowPrivilegeEscalation: false #
securityContext:
allowPrivilegeEscalation: false
Ini mencegah proses di dalam container mendapatkan privilege lebih tinggi dari proses induknya — misalnya via sudo, setuid, atau setcap. Satu konfigurasi ini secara signifikan mengurangi risiko eskalasi privilege.
readOnlyRootFilesystem #
securityContext:
readOnlyRootFilesystem: true
Dengan readOnlyRootFilesystem: true:
→ Penyerang tidak bisa tulis file ke container filesystem
→ Tidak bisa modifikasi binary yang ada
→ Tidak bisa install tools (wget, curl, nc) untuk lateral movement
Tapi: banyak aplikasi butuh tempat tulis sementara
Solusi: mount tmpfs untuk direktori yang butuh write access:
spec:
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache/app
volumes:
- name: tmp
emptyDir: {} # tmpfs untuk /tmp
- name: cache
emptyDir:
medium: Memory # eksplisit di memory
sizeLimit: 100Mi
Capabilities #
Linux capabilities memecah privilege root menjadi unit-unit yang lebih kecil. Container secara default mendapat subset capabilities. Best practice: drop semua, lalu add kembali hanya yang benar-benar dibutuhkan.
securityContext:
capabilities:
drop:
- ALL # hapus semua capabilities default
add:
- NET_BIND_SERVICE # boleh bind ke port < 1024 (misal: port 80)
Capabilities yang sering dibutuhkan:
NET_BIND_SERVICE — bind ke port < 1024 (80, 443)
NET_ADMIN — konfigurasi network interface (butuh ini? pertimbangkan ulang)
SYS_PTRACE — debug process (JANGAN di production)
CHOWN — ubah file ownership
Capabilities yang TIDAK boleh ada di production:
SYS_ADMIN — hampir setara dengan root, terlalu berbahaya
NET_RAW — bisa membuat raw packet (digunakan untuk serangan network)
DAC_OVERRIDE — bypass file permission checks
Pod Security Standards #
Kubernetes mendefinisikan tiga level standar keamanan Pod yang semakin ketat:
Privileged:
→ Tidak ada batasan — container bisa lakukan hampir apa saja
→ Hanya untuk workload infrastruktur kritikal (CNI plugin, node agent)
→ JANGAN gunakan untuk aplikasi biasa
Baseline:
→ Mencegah privilege escalation yang paling berbahaya
→ Memblokir hostNetwork, hostPID, hostIPC
→ Memblokir hostPath volume yang tidak aman
→ Cocok untuk sebagian besar workload production
Restricted:
→ Mengikuti semua best practice Pod hardening
→ runAsNonRoot: true wajib
→ readOnlyRootFilesystem: true wajib
→ capabilities drop ALL wajib
→ seccompProfile wajib
→ Cocok untuk workload yang butuh keamanan tinggi
Pod Security Admission (PSA) #
Kubernetes 1.25+ memiliki Pod Security Admission bawaan yang menerapkan Pod Security Standards di level namespace:
# Label namespace untuk menerapkan Pod Security Standard
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# Mode: enforce (tolak), audit (log), warn (peringatan)
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
# Tambahkan label ke namespace yang sudah ada
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted
# Test apakah Pod akan diterima
kubectl apply --dry-run=server -f pod.yaml -n production
Contoh SecurityContext Produksi yang Lengkap #
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: my-api:v2
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp-dir
mountPath: /tmp
- name: log-dir
mountPath: /var/log/app
volumes:
- name: tmp-dir
emptyDir: {}
- name: log-dir
emptyDir: {}
Ringkasan #
allowPrivilegeEscalation: falseselalu — satu setting ini mencegah proses mendapat privilege lebih tinggi dari parent; wajib di semua container production.runAsNonRoot: truedi Pod-level — container yang jalan sebagai root sama berbahayanya dengan root di host jika terjadi container escape; gunakan UID non-root.readOnlyRootFilesystem: true+ emptyDir untuk direktori yang butuh write — filesystem read-only sangat mempersulit penyerang; mount emptyDir ke/tmpdan direktori cache.capabilities drop ALLlaluaddyang perlu saja — jangan berikan capabilities yang tidak dibutuhkan; kebanyakan aplikasi web tidak butuh capabilities apapun.- Pod Security Standards via namespace label — Kubernetes 1.25+ mendukung PSA bawaan; label namespace dengan
pod-security.kubernetes.io/enforce=restricteduntuk enforcement.- seccompProfile: RuntimeDefault — aktifkan seccomp profile default yang memblokir ~300 syscall yang jarang digunakan dan sering dieksploitasi.