Cloud Native Security: Pod Security, Network Policies
Kubernetes'te güvenlik, tek bir katmanda çözülecek bir sorun değildir. Bir pod'un çalışma zamanında ne yapabileceğini kısıtlamak (Pod Security) ve kiminle konuşabileceğini sınırlamak (Network Policies), birbirini tamamlayan iki savunma hattıdır. Bu iki mekanizma olmadan, tek bir pod'un ele geçirilmesi, küme içinde yatay hareket (lateral movement) için açık bir kapı bırakır.
1. Pod Security: Pod'ların Yetkilerini Sınırlamak
Pod Security, bir pod'un hangi ayrıcalıklarla çalışabileceğini tanımlar. Kubernetes 1.25'ten itibaren PodSecurityPolicy (PSP) kaldırılmış ve yerine yerleşik Pod Security Admission (PSA) denetleyicisi gelmiştir . PSA, namespace etiketleri aracılığıyla üç standart profil uygular:
| Profil | Amaç | Kısıtlar |
|---|---|---|
| Privileged | Sistem ve altyapı namespace'leri | Kısıtlama yok; uygulama iş yüklerinde kullanılmamalı |
| Baseline | Bilinen ayrıcalık yükseltmelerini engellemek | Ayrıcalıklı container, hostPID, hostIPC, hostNetwork ve çoğu hostPath engellenir |
| Restricted | Üretim uygulamaları için en sıkı seviye | Baseline'a ek olarak: root olmayan kullanıcı, ayrıcalık yükseltme yasağı, seccompProfile zorunluluğu ve sınırlı volume tipleri |
Uygulama Modları:
-
enforce: İhlal eden pod'lar admission aşamasında reddedilir.
-
warn: İhlal eden pod'lara izin verilir ancak kullanıcı uyarı alır.
-
audit: İhlal, audit log'una kaydedilir .
Önerilen Geçiş Stratejisi: Üretimde doğrudan enforce moduna geçmek yerine, önce staging ortamında warn ve audit modlarını etkinleştirin. Bu, mevcut iş yüklerinin restricted profiline uyup uymadığını gösterir ve kesinti riskini azaltır .
Örnek Namespace Etiketlemesi:
bash
kubectl label namespace retail-app \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/audit=restricted
Pod Spec'inde Güvenlik Bağlamı (Security Context):
PSA namespace seviyesinde koruma sağlarken, container seviyesinde açık güvenlik ayarları tanımlamak denetimi kolaylaştırır ve taşınabilirliği artırır . Üretim için kritik ayarlar:
yaml
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: api
securityContext:
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
Bu ayarlar sırasıyla: root olmayan kullanıcı, varsayılan seccomp profili, kök dosya sisteminin salt okunur olması, ayrıcalık yükseltmenin engellenmesi ve tüm Linux yeteneklerinin kaldırılması anlamına gelir .
2. Network Policies: Pod'lar Arası Trafiği Kısıtlamak
Kubernetes'in varsayılan ağ modeli düz ve tamamen açıktır: her pod, her namespace'teki her pod'a her porttan bağlanabilir . Bu, demo ortamları için uygun olsa da üretimde tek bir pod'un ele geçirilmesinin veritabanına, iç API'lere ve cloud metadata servisine erişmesi anlamına gelir.
NetworkPolicy, Layer 4 (TCP, UDP, SCTP) seviyesinde trafiği beyaz liste (allowlist) mantığıyla kısıtlar . Kritik nokta: NetworkPolicy yalnızca onu destekleyen bir CNI plugin'i ile uygulanır. Calico, Cilium ve Antrea destekler; temel flannel desteklemez .
Temel Mantık: Additive ve Default-Allow
Bir pod'a herhangi bir NetworkPolicy uygulanmadığı sürece trafik serbesttir. Bir policy pod'u seçtiği anda o yön (Ingress veya Egress) için default-deny devreye girer ve yalnızca açıkça izin verilen trafik geçer . Policy'ler toplanır (additive); çakışma yaratmaz, izinler birleşir .
Adım 1: Default-Deny ile Başlayın
Her namespace'te tüm giriş ve çıkışı kapatan bir politika oluşturun:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: payments
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Bu politika, namespace'teki tüm pod'ları izole eder; hiçbir trafik geçmez .
Adım 2: Yalnızca Gereken Trafiği İzin Verin
Örneğin, api pod'larının yalnızca frontend pod'larından 8080 portuna trafik almasına izin verin:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: payments
spec:
podSelector:
matchLabels:
app: api
policyTypes: ["Ingress"]
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Adım 3: DNS'i Unutmayın (En Sık Yapılan Hata)
Egress için default-deny uyguladığınızda, pod'lar CoreDNS'e erişemez ve tüm hostname çözümlemeleri başarısız olur. Uygulama "rastgele bozulmuş" gibi görünür . DNS için açık izin ekleyin:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: payments
spec:
podSelector: {}
policyTypes: ["Egress"]
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
kubernetes.io/metadata.name etiketi, tüm namespace'lerde otomatik olarak bulunur ve namespace'i adıyla hedeflemeyi sağlar .
3. İki Katmanı Birlikte Düşünmek
Pod Security ve Network Policies birbirini tamamlar:
-
Pod Security, bir pod'un ne yapabileceğini kısıtlar. Örneğin,
restrictedprofil sayesinde ele geçirilen bir pod, root yetkisiyle host'a erişemez veya ayrıcalık yükseltemez. -
Network Policies, bir pod'un nereye gidebileceğini kısıtlar. Örneğin, ele geçirilen bir pod, yalnızca izin verilen servislere bağlanabilir; veritabanına veya metadata servisine ulaşamaz.
Birlikte uygulandıklarında, bir pod'un ele geçirilmesi durumunda saldırganın etki alanı (blast radius) önemli ölçüde daralır.
4. En İyi Pratikler
| Pratik | Açıklama |
|---|---|
| Önce audit/warn, sonra enforce | Üretimde doğrudan enforce yerine staging'de warn/audit ile başlayın |
| Her namespace'e default-deny uygulayın | Unutulan namespace'ler, kümedeki en büyük güvenlik açığıdır |
| DNS egress'ini açıkça izin verin | default-deny sonrası DNS'i unutmak, uygulamayı çalışmaz hale getirir |
| CNI plugin'inin NetworkPolicy desteklediğini doğrulayın | Desteklemeyen bir plugin ile politika yazmak yanlış güvenlik hissi yaratır |
| Security Context'i açıkça tanımlayın | PSA namespace seviyesinde korur; container seviyesinde runAsNonRoot, readOnlyRootFilesystem gibi ayarları belirtmek denetimi kolaylaştırır |
Sonuç
Cloud native güvenlik, tek bir kontrolle sağlanmaz. Pod Security Admission, pod'ların ayrıcalıklarını restricted profiliyle en aza indirir; Network Policies ise varsayılan olarak açık olan ağı, default-deny ve seçici izinlerle en az ayrıcalık modeline dönüştürür. İkisi birlikte uygulandığında, bir ihlalin etkisi izole edilir ve yatay hareket engellenir. Unutmayın: Güvenlik, "kur ve unut" değil, sürekli izleme, audit ve iyileştirme gerektiren bir süreçtir.