Jaringan datar adalah hadiah bagi penyerang yang sudah masuk; di episode ini kalian menerapkan segmentasi menyeluruh — network policy default-deny per namespace, egress control untuk membatasi koneksi keluar, dan mTLS service mesh dengan Istio/Linkerd agar setiap percakapan antar-service terautentikasi dan terenkripsi

Setelah Fase 3 ditutup dengan shift-right, kita masuk Fase 4: jaringan. Episode 8 sudah memperkenalkan default-deny dasar; episode ini mendalamkannya menjadi strategi segmentasi utuh. Mengapa penting? Karena model ancaman modern mengasumsikan breach sudah terjadi — pertanyaannya bukan "bagaimana mencegah masuk", melainkan "seberapa jauh attacker bisa bergerak setelah masuk". Itulah konsep lateral movement, dan jaringan datar adalah teman terbaiknya.
Insiden nyata berulang kali menunjukkan pola yang sama: satu container dicompromise lewat RCE web app → karena semua pod saling bisa diakses → database, Redis tanpa auth, dan service internal lain ikut tewas dalam hitungan menit. Segmentasi memutus rantai ini.
Model lama: perimeter — aman di dalam, curiga di luar. Model modern (zero trust): tidak ada lokasi yang dipercaya; setiap koneksi diverifikasi. Untuk platform Kubernetes, prinsipnya diterjemahkan jadi tiga aturan:
Episode 8 membuat deny-all; sekarang kita bangun allowlist bertingkat. Contoh arsitektur three-tier:
Aturan segmentasinya ketat dan satu arah:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-ingress
namespace: prod
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- namespaceSelector:
matchLabels:
env: prod
podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
policyTypes:
- IngressPerhatikan baris yang disorot: kombinasi namespaceSelector + podSelector artinya traffic harus lolos dua syarat sekaligus (dari namespace env=prod DAN pod berlabel app=frontend). Kesalahan umum pemula menaruhnya sebagai dua item array terpisah — yang artinya atau, bukan dan, dan membuka celah besar.
Uji kebijakan kalian secara aktif (jangan asumsikan CNI menerapkannya):
kubectl run nettest --rm -it --image=nicolaka/netshoot -- \
curl --max-time 3 api.prod.svc.cluster.local:8080
# harus TIMEOUT dari pod tanpa label frontendIngress saja belum lengkap — attacker yang masuk akan mencoba keluar: download payload, exfiltrate data, beacon ke C2 server. Default-deny egress memaksa semua koneksi keluar dideklarasikan:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-egress
namespace: prod
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Egress
egress:
- to: # DNS tetap wajib dibuka
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
- to: # hanya boleh ke database internal
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432Hasilnya: pod api tidak bisa membuka koneksi ke internet sama sekali — bahkan kalau RCE berhasil, payload tidak bisa didownload dan data tidak bisa dikirim keluar. Untuk kasus yang butuh akses external API, gunakan egress gateway atau proxy dengan FQDN allowlist (Cilium mendukung policy berbasis DNS name).
Warning
Jangan lupakan DNS saat menulis egress policy — ini penyebab outage nomor satu saat adopsi default-deny egress. Pod yang tak bisa resolve hostname akan gagal semua koneksi, termasuk ke service internal yang diizinkan.
NetworkPolicy bekerja di L3/L4 (IP/port). Dua kelemahannya:
Service mesh (Istio, Linkerd) menyelesaikan keduanya: sidecar/eBPF proxy menyuntikkan identitas kriptografis (SPIFFE/SVID) ke setiap workload, dan semua traffic antar-service otomatis mutual TLS.
Dengan Linkerd, cukup anotasi namespace; dengan Istio, konfigurasi peer authentication:
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: prod
spec:
mtls:
mode: STRICT # tolak semua traffic non-mTLSSTRICT artinya: hanya workload dengan sertifikat mesh yang bisa bicara — plaintext ditolak. Authorization layer mesh-nya juga lebih halus dari label:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: api-from-frontend
namespace: prod
spec:
selector:
matchLabels:
app: api
action: ALLOW
rules:
- from:
- source:
principals: ["prod/frontend"]
to:
- operation:
methods: ["GET", "POST"]Ini L7 authorization: method-level, principal-level — sesuatu yang mustahil dilakukan NetworkPolicy murni.
| Kebutuhan | Solusi | Biaya |
|---|---|---|
| Isolasi namespace dasar | NetworkPolicy default-deny | Rendah |
| Kontrol L7 & identitas kuat | Service mesh mTLS | Sedang (operational overhead) |
| Multi-cluster / VM hybrid | Mesh + SPIRE federation | Tinggi |
Saran pragmatis: mulai NetworkPolicy menyeluruh (dampak terbesar, biaya terkecil), lalu mesh untuk stack yang benar-benar butuh L7/multi-cluster. Jangan pasang Istio hanya untuk default-deny.
Inti yang harus dibawa pulang:
Di episode 19 selanjutnya kita beralih ke identitas: Identity & Access for Pipelines — bagaimana pipeline dan workload membuktikan siapa mereka tanpa password statis: OIDC federation, SPIFFE/SPIRE in-cluster, dan desain service account least privilege sampai level permission boundary. Sampai jumpa!