Güvenlik

Zero-Trust ve Mikro Segmentasyon: Kubernetes Ağını Kapatmak

Cluster içinde her pod her podla konuşabiliyorsa, tek bir zafiyet tüm sisteme açılan kapıdır. Bunu kapatmanın yolu ve sık yapılan hatalar.

Güvenlik mimarisinde uzun yıllar geçerli olan varsayım şuydu: dışarısı tehlikeli, içerisi güvenli. Bu varsayım, saldırganın içeri girdiği ilk andan itibaren geçersiz hale geliyor. Zero-trust yaklaşımı da tam olarak bu varsayımı kaldırmak üzerine kurulu. Aşağıda bunun Kubernetes tarafındaki somut karşılığını, yani mikro segmentasyonu ele alıyoruz.

Çevre güvenliği neden tek başına yetmiyor

Klasik model kaleye benzer: dışarıda güçlü bir duvar, içeride serbest dolaşım. Bu modelde tüm yatırım giriş noktasına yapılır. Sorun şu ki saldırılar genelde duvarı yıkarak değil, bir kapıdan geçerek başlıyor. Ele geçirilmiş bir kimlik bilgisi, güncellenmemiş bir kütüphane ya da dışarıya açık tek bir servis yeterli oluyor.

İçeri girildikten sonra olan şeye lateral movement, yani yanal hareket deniyor. Saldırgan ilk eriştiği yerde durmaz; oradan ulaşabildiği diğer sistemlere geçer, yetki yükseltir ve asıl hedefine doğru ilerler. Bir ihlalin zararını belirleyen şey de çoğu zaman ilk giriş değil, bu hareketin ne kadar serbest olduğudur. Çevre güvenliği bu hareketi hiç görmez, çünkü tüm bu trafik onun için içeride kalan trafiktir.

Zero-trust gerçekte ne söylüyor

Zero-trust bir ürün değil, bir mimari yaklaşım. NIST'in bu konudaki yayımladığı çerçeve, yaklaşımı bir dizi ilke üzerinden tanımlıyor. Özü şu üç maddeye indirgenebilir:

  • Konum güven üretmez. Bir isteğin ağın içinden gelmesi, onu güvenilir yapmaz. Her istek kendi başına değerlendirilir.
  • En az yetki uygulanır. Her bileşen yalnızca işini yapmak için gereken kaynağa, gereken süre boyunca erişir.
  • İhlal varsayılır. Sistem, saldırganın zaten içeride olduğu varsayımıyla tasarlanır. Bu varsayım doğrudan segmentasyona ve sürekli izlemeye götürür.

Üçüncü madde en çok atlanandır ve en pahalıya patlayandır. Çünkü ilk iki maddeyi uygulayıp üçüncüsünü atlayan bir kurulum, ihlal gerçekleştiğinde hasarın nereye kadar yayıldığını söyleyemez.

Kubernetes ağı varsayılan olarak düzdür

Kubernetes'in ağ modeli sadeliği hedefler: cluster içindeki her pod, her pod ile doğrudan haberleşebilir. Namespace'ler bir yönetim sınırıdır, bir ağ sınırı değildir. Yani hiçbir politika tanımlanmamışsa, üretim namespace'indeki bir veritabanına test namespace'indeki bir pod ağ seviyesinde erişebilir.

Bunun saldırgan açısından anlamı açıktır. Dışarıya açık tek bir web konteynerinin ele geçirilmesi, cluster içindeki tüm servislere ağ erişimi kazandırır. Veritabanı yalnızca uygulama parolasıyla korunuyorsa, o parolayı bulmak yeterli hale gelir. Segmentasyon olmadan tek savunma katmanı uygulama kimlik doğrulamasıdır ve bu ince bir katmandır.

Bu düzlüğü kapatmanın Kubernetes içindeki aracı NetworkPolicy nesnesidir. Kendi işlettiğimiz Kubernetes cluster kurulumlarında bu nesneyi baştan devreye almak, sonradan eklemekten çok daha ucuza gelir; çünkü çalışan bir sistemde trafiği kısıtlamak, kurarken kısıtlamaktan zordur.

NetworkPolicy ve sessizce uygulanmayan kurallar

NetworkPolicy'nin en tehlikeli özelliği şudur: uygulanmadığında hata vermez. Kubernetes API'si nesneyi kabul eder, kaydeder, kubectl get networkpolicy ile listelendiğinde görünür. Ama trafiği fiilen kısıtlayan şey Kubernetes değil, kullandığınız CNI ağ eklentisidir. Eklenti NetworkPolicy desteklemiyorsa kurallar sessizce yok sayılır ve siz segmentasyon yaptığınızı sanırsınız.

Bu yüzden ilk adım politikayı yazmak değil, ağ eklentisinin bu nesneyi gerçekten uyguladığını doğrulamaktır. Doğrulamanın tek güvenilir yolu test etmektir: bir politika ile engellenmesi gereken bir bağlantıyı deneyip gerçekten reddedildiğini görmek.

Uygulandığından emin olduktan sonra bilinmesi gereken davranış kuralları şunlar:

  • Politikalar toplanarak çalışır, yani birleşimleri alınır. Reddetme kuralı yazamazsınız; yalnızca izin verirsiniz. Reddetme, bir pod herhangi bir politika tarafından seçildiği anda otomatik olarak devreye girer.
  • Bir pod ingress kuralı içeren herhangi bir politika tarafından seçilirse, o pod için izin verilmeyen tüm gelen trafik kapanır. Yani varsayılan reddet davranışı, politika yazmakla değil, podu politikaya dahil etmekle başlar.
  • Politikalar namespace kapsamlıdır. Her namespace kendi kurallarını taşır, bir namespace'te yazılan politika diğerini korumaz.
  • hostNetwork kullanan podlar bu kuralların dışında kalır, çünkü doğrudan node'un ağ isim alanında çalışırlar.

Yaygın ve doğru başlangıç, her namespace için gelen trafiği kapatan bir temel politika koymak, sonra ihtiyaç duyulan yolları tek tek açmaktır. Ama bunu doğrudan üretimde yapmak sistemi durdurur; önce mevcut trafiğin haritasının çıkarılması gerekir.

Egress kapatınca ne kırılır

Gelen trafiği kısıtlamak görece güvenlidir. Asıl sorunlar giden trafik kısıtlanınca başlar ve büyük çoğunluğu tek bir sebepten çıkar: DNS.

Bir pod için egress kısıtlandığında, cluster içindeki DNS servisine giden trafiğe açıkça izin verilmezse ad çözümleme durur. Uygulama artık hiçbir servis adını çözemez ve her bağlantı denemesi başarısız olur. Hata mesajı genelde ağ politikasını değil, bağlanamama durumunu gösterdiği için ekipler saatlerce yanlış yerde arar. Egress politikası yazarken kube-dns ya da CoreDNS servisine giden 53 numaralı porta izin vermek, neredeyse her zaman gereken ilk kuraldır.

İkinci sık kırılma noktası cluster dışına giden meşru trafiktir: paket depoları, imaj çekme, ödeme sağlayıcısı, e-posta servisi, lisans sunucusu. Bunların hepsi haritalanmadan egress kapatılırsa sistem çalışmaz hale gelir. Bu haritayı çıkarmanın en pratik yolu, politikayı önce yalnızca kayıt alan modda çalıştırıp gerçek trafiği izlemektir.

Kimlik katmanı: mTLS ve service mesh

NetworkPolicy üçüncü ve dördüncü katmanda çalışır: hangi pod, hangi pod ile, hangi porttan konuşabilir. Cevaplayamadığı soru şudur: karşı taraf gerçekten iddia ettiği servis mi. IP adresleri Kubernetes'te sürekli değişir ve bir IP'ye güvenmek kimlik doğrulaması değildir.

Bu boşluğu karşılıklı TLS doldurur. Karşılıklı TLS'te yalnızca istemci sunucuyu değil, sunucu da istemciyi doğrular; her iki taraf da sertifika sunar. Böylece kimlik ağ konumundan değil, kriptografik bir kimlikten gelir. Service mesh çözümleri bunu her podun yanına yerleştirdikleri bir vekil üzerinden, uygulama kodunu değiştirmeden sağlar ve sertifika dağıtımı ile yenilenmesini kendileri üstlenir.

Service mesh, NetworkPolicy'nin yerine geçmez. İkisi farklı katmanlarda çalışır: ağ katmanı kimin kiminle konuşabileceğini daraltır, kimlik katmanı konuşan tarafın gerçekten kim olduğunu doğrular. Bu birlikte kurgu zero-trust security yaklaşımının Kubernetes üzerindeki pratik karşılığıdır. Her podun yanına konan vekil kaynak tüketir; bu maliyet cluster maliyet hesabına doğrudan yansır.

Sık sorulan sorular

NetworkPolicy yazdım ama hiçbir şey değişmedi, neden?

Büyük ihtimalle kullandığınız CNI eklentisi NetworkPolicy uygulamıyor. Kubernetes bu nesneyi kabul eder ve saklar, ama trafiği fiilen kısıtlayan şey ağ eklentisidir. Politikayı uygulamayan bir eklentide kurallar sessizce yok sayılır, hata da verilmez.

Kubernetes ağı varsayılan olarak ne kadar açık?

Tamamen açıktır. Hiçbir politika tanımlanmamışsa cluster içindeki her pod, hangi namespace'te olursa olsun diğer her pod ile haberleşebilir. Yani tek bir konteynerin ele geçirilmesi, saldırgana cluster içindeki her servise erişim sağlar.

Egress politikası yazınca uygulamalar neden bozulur?

En sık sebep DNS'tir. Egress kısıtlandığında kube-dns ya da CoreDNS servisine giden 53 numaralı porta izin verilmezse ad çözümlemesi durur ve uygulama her adresi çözümleyemez hale gelir. Hata mesajı da ağ politikasını değil, bağlanamama sorununu işaret ettiği için kaynağı bulmak zaman alır.

NetworkPolicy ile service mesh arasındaki fark ne?

NetworkPolicy üçüncü ve dördüncü katmanda çalışır, yani hangi podun hangi pod ile hangi porttan konuşabileceğini belirler. Service mesh ise yedinci katmana çıkar ve karşılıklı TLS ile her iki tarafın kimliğini doğrular. Biri diğerinin yerine geçmez, katmanlı olarak birlikte kullanılırlar.

Mikro segmentasyona nereden başlamak gerekir?

Mevcut trafiği önce gözlemleyerek. Hangi servisin hangi servisle konuştuğu haritalanmadan yazılan varsayılan reddet politikası üretimi durdurur. Doğru sıra şudur: trafiği kaydet, haritayı çıkar, en kritik namespace'te kapatmaya başla, sonra genişlet.

Segmentasyonu birlikte kuralım

Mevcut trafiği haritalayıp cluster içindeki yanal hareketi kapatan politikaları devreye alıyoruz.

Zero-trust security Uzmanla görüşün

İlgili yazılar

Kubernetes

Kubernetes Sürüm Yükseltme

CNI değiştiğinde politika davranışının nasıl sessizce değiştiği.

Güvenlik

KVKK ve Veri Egemenliği

Erişim kaydı tutmanın uyum tarafındaki karşılığı ve yetmiş iki saat kuralı.