
Hari 54: OPA Mati, Pod Nakal Lolos, Falco Masih Menangkap
Simulasi chaos: admission control (OPA) dimatikan, pod nakal lolos masuk. Tapi Falco tetap menangkap pod privileged. Ada script drift-check untuk menutup gap-nya.
Hari ke-54 dari challenge 60 Days DevSecOps. Topiknya: chaos security engineering. Intinya satu pertanyaan: kalau salah satu lapis keamanan dimatikan, apakah lapis lain masih menjaga?
Di hari-hari sebelumnya, saya mengandalkan OPA Gatekeeper untuk memblokir pod yang tidak patuh — misalnya pod tanpa resource limits atau pod privileged. Hari ini saya sengaja mematikannya dan lihat apa yang terjadi. Hasilnya menarik sekaligus sedikit menakutkan.
Apa itu Admission Control?
Sebelum masuk ke chaos, mari pahami dulu satu konsep: admission control.
Di Kubernetes, setiap kali Anda minta pod dibuat, permintaan itu melewati "pintu masuk" bernama admission webhook. OPA Gatekeeper menaruh kebijakan di sini: kalau pod tidak punya resource limits, tolak. Kalau pod memakai privileged: true, tolak.
Coba test dulu — deploy pod tanpa limits:
kubectl apply -f test-no-limits.yaml
Hasilnya ditolak mentah-mentah:
Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied:
[require-resource-limits] Container 'no-limits' has no CPU limit
Bagus. Pintunya bekerja. Sekarang, mari kita matikan pintunya.
Chaos: Pintu Dibuka Paksa
kubectl scale deployment gatekeeper-controller-manager -n gatekeeper-system --replicas=0
Controller yang melayani admission webhook saya matikan total. Sekarang, apa yang terjadi kalau pod nakal datang lagi?
kubectl apply -f test-no-limits.yaml # pod/test-no-limits created
kubectl apply -f test-privileged.yaml # pod/test-privileged created
Diterima. Pod yang barusan ditolak, sekarang masuk begitu saja. Ini yang disebut fail-open: kalau gerbang penjaga mati, semua orang lewat tanpa dicek.
Ini bukan bug — ini desain. Webhook Gatekeeper memakai failurePolicy: Ignore, artinya kalau controller-nya error, klaster memilih "biarkan masuk" daripada "blokir semuanya" (yang bisa bikin aplikasi lain ikut gagal deploy). Tapi konsekuensinya jelas: selama OPA mati, policy tidak ditegakkan.
Lapis Kedua: Falco (Runtime Security)
Sekarang pertanyaannya: apakah yang mengawasi di lapisan bawah — Falco, yang memantau syscall di runtime — ikut buta?
Hasilnya tidak sepenuhnya:
| Pod nakal | Reaksi Falco |
|---|---|
test-no-limits (cuma tanpa limits, diam saja) |
Diam total |
test-privileged (privileged) |
ALERT CRITICAL |
Pod privileged langsung memicu alert:
Critical ALERT: Privileged container launched
(container=priv image=alpine pod=test-privileged namespace=securebank)
Alert ini mengalir: Falco → falcosidekick → webhook → Slack #security-alerts. Terkirim, HTTP 200.
Inilah inti defense in depth: admission control boleh mati, tapi runtime masih menangkap pod yang melakukan hal berbahaya. Satu lapis gagal, lapis lain tetap siaga.
Tapi Ada Gap-nya
Di sisi lain, pod test-no-limits — yang sama sekali tidak punya resource limits — tidak memicu apapun di Falco. Kenapa?
Karena Falco melihat syscall, bukan konfigurasi pod. Pod yang diam-diam saja tidak melakukan syscall mencurigakan. Secara runtime, dia "biasa saja". Tapi secara kebijakan, dia melanggar.
Ini gap nyata: ada pod yang melanggar policy, tapi tidak ada yang mendeteksinya di runtime. Kalau tidak ada yang ngecek, selamanya dia dianggap baik-baik saja.
Menutup Gap: Dua Detector Drift
1. OPA Audit. Ternyata Gatekeeper punya deployment terpisah bernama audit yang tidak ikut dimatikan. Dia mengecek klaster secara berkala dan mencatat pelanggaran di status constraint:
kubectl get k8srequiredlimits.constraints.gatekeeper.sh -o jsonpath='{.items[0].status.totalViolations}'
# 8
Delapan pelanggaran tercatat — dua pod nakal itu terlihat oleh audit. Audit bukan penjaga pintu, tapi dia mencatat siapa yang menyelinap masuk.
2. Script drift-check.sh. Saya buat script sederhana pakai kubectl + jq untuk list semua container yang tidak punya resource limits:
DRIFT: pod=test-no-limits container=no-limits req.cpu=MISSING ...
DRIFT: pod=test-privileged container=priv req.cpu=MISSING ...
RESULT: 2 container drift terdeteksi. ⚠️
Script ini bisa dijalankan manual, masuk cron, atau jadi job di CI — detector drift yang murah tapi efektif.
Kembalikan Sistem
Semua chaos harus dibersihkan:
kubectl scale deployment gatekeeper-controller-manager -n gatekeeper-system --replicas=1
kubectl delete pod -n securebank test-no-limits test-privileged --grace-period=0 --force
Verifikasi: deploy ulang pod tanpa limits → Forbidden lagi. Pintu kembali dijaga. drift-check.sh → 0 drift.
Lessons Learned
- Admission control bukan segalanya. OPA hebat mencegah, tapi kalau mati, semua lolos. Jangan pernah taruh seluruh keamanan di satu gerbang.
- Fail-open itu keputusan desain. Konsekuensinya harus dikompensasi dengan detector lain (audit, drift-check, atau cron).
- Runtime tidak paham kebijakan bisnis. Falco melihat syscall, bukan "pod ini kurang limits". Gap ini harus ditutup detector konfigurasi.
- OPA audit itu safety net gratis. Meski admission mati, audit tetap mencatat pelanggaran. Cek
status.totalViolationsberkala. - Chaos test itu jujur. Latihan mematikan control mengungkap asumsi yang tidak pernah muncul di dokumen.
Kesimpulan
Hari ini menjawab pertanyaan kunci arsitektur keamanan: satu lapis mati, sisanya tetap jalan — tapi ada celah yang perlu ditutup. Kombinasi admission (OPA), runtime (Falco), dan audit (OPA audit + drift-check) membuat pertahanan tidak bergantung pada satu titik kegagalan.
Semua script ada di repo: chalange-devsecops — lihat folder securebank-api/k8s/chaos/ untuk manifest pod nakal dan securebank-api/security/chaos/drift-check.sh untuk detector drift.
Besok: mulai menyusun laporan audit dari semua temuan 54 hari.
Diskusi & Komentar
Artikel Terkait
Hari 20: Terraform + Checkov, 15 Celah IaC Ketahuan
Bikin infrastructure as code pakai Terraform, lalu scan dengan Checkov. Hasilnya 15 celah keamanan ketahuan — S3 tanpa enkripsi, security group terbuka ke dunia.
Hari 22: Pipeline IaC, Dua Scanner Barengan Gagal
Bikin workflow GitHub Actions khusus infrastructure security. Checkov dan Trivy IaC scan Terraform barengan. Hasilnya pipeline MERAH — security gate bekerja!
Hari 22 Bonus: Perbaikan Pipeline Gitleaks yang Merah Diam-diam
Pipeline Gitleaks merah sejak Day 14 karena flag --no-gitignore tidak pernah ada. Gitleaks detect scan git history, bukan working directory. Fix: hapus flag.