Mart sonunda rutin bir sızma testi raporu masama geldi ve 14. sayfadaki tek satır, o çeyreğin önceliklerini değiştirdi: test ekibi, staging kümesinde ele geçirdikleri sıradan bir pod'dan, ödeme servisinin iç API'sine hiçbir kimlik doğrulama olmadan istek atabilmişti. Üretimde de durum farklı değildi: cluster'ın içi, güven duvarının içi sayılıyordu. Perimeter güvenliğimiz sağlamdı — WAF, API gateway, ağ politikaları — ama kabuğu geçen herkes için içerisi açık büfeydi. Kimlik doğrulama "kenarda" yapılıyor, 60 küsur mikroservis birbirine körlemesine güveniyordu. Raporun o satırının altına tek not düştüm: "Kabuk güvenliği, kabuklu deniz ürünü gibidir; kabuğu kırılınca her şey ortada." O hafta mTLS projesini başlattık.
Sıfır Güven Sloganını Pakete Çevirmek
"Zero trust" son yılların en çok eskitilen terimi; biz onu tek bir mühendislik cümlesine indirdik: her servis çağrısında, çağıran ve çağrılan taraf birbirinin kimliğini kriptografik olarak doğrular ve trafik şifrelenir — cluster içinde bile, "iç ağ" diye bir muafiyet olmadan. Bunun standart aracı mTLS: klasik TLS'in, istemcinin de sertifika sunduğu hali. Kulağa basit geliyor; 60 servis, üç dil (PHP, Node.js, Java) ve saniyede on binlerce iç çağrı söz konusu olunca üç büyük soruyla yüzleşiyorsunuz. Sertifikaları kim üretecek ve döndürecek? TLS sonlandırmayı kim yapacak — uygulama mı, altyapı mı? Ve bütün bunlar gecikmeye ne yapacak?
İlk soruda kestirme yol yok: elle sertifika dağıtımı, 60 serviste ölü doğmuş bir fikir. Kimlik, otomatik ve kısa ömürlü olmalı. İkinci soruda iki yol vardı. Uygulama içinde mTLS — her dilin kendi TLS yığınıyla — bizim poliglot gerçekliğimizde üç ayrı implementasyon, üç ayrı hata yüzeyi demekti; IoT günlerimden biliyordum ki sertifika yönetimini uygulama koduna gömmek, her sertifika olayını bir deployment olayına çevirir. Service mesh ise bu işi sidecar proxy'lere taşıyor: uygulama düz HTTP konuşur, pod içindeki proxy dışarıya mTLS konuşur, kimlikler SPIFFE formatında (spiffe://cluster/ns/payments/sa/payment-api) otomatik üretilir ve rotasyon saatlik yapılır. Mesh'i seçtik; adayları karşılaştırırken önceliğimiz özellik zenginliği değil, operasyonel yalınlık ve kaynak maliyetiydi. PHP monoliti gibi mesh'e hemen giremeyecek iş yükleri için de geçiş dönemi planı yaptık: onların trafiği, mesh sınırındaki gateway'de mTLS'e sarılıyor.
Yanlış Korku, Doğru Korku
Projeye başlarken ekibin en büyük korkusu gecikmeydi: "Her çağrıya TLS el sıkışması binerse p99 mahvolur." Bu korku büyük ölçüde yersiz çıktı — bağlantılar havuzlanıyor ve uzun ömürlü, el sıkışma her istekte değil bağlantı başına yaşanıyor. Ölçtük: sidecar'lı yolda istek başına eklenen medyan gecikme 0,7 milisaniye, p99'da 2,1 milisaniye. Saniyede 2 bin istek gören sipariş yolunda bile bütçemizin içindeydi. Asıl maliyet beklemediğimiz yerden geldi: bellek. Her pod'a binen sidecar, başına 60-90 MB RAM demekti; 1.400 pod'luk kümede toplamda 100 GB'ın üzerinde ek bellek ve node başına pod yoğunluğunda düşüş. Bu, bulut faturasında görünür bir kalemdi ve kimse sunumlarda bundan bahsetmiyor. Kısmen proxy konfigürasyon budamasıyla (kullanmadığımız filtreleri kapatarak) sidecar'ları 45 MB civarına indirdik; kalanını, sızma testi raporunun yanına koyup güvenlik bütçesi olarak kabullendik.
İkinci beklenmedik ders: mTLS'i açmak, kimlik doğrulamayı çözer ama yetkilendirmeyi kendiliğinden çözmez. İlk fazda "herkes herkesle mTLS konuşsun" modundaydık — şifreli ama hâlâ açık büfe, sadece büfeye girerken artık kimlik gösteriliyor. Gerçek kazanım ikinci fazda geldi: yetkilendirme politikaları. Ödeme servisinin iç API'sine yalnızca sipariş orkestrasyonu ve iade servisi erişebilir; fatura servisi veri ambarına yazabilir ama ödeme servisini çağıramaz. Bu politikaları yazmak, teknik işten çok arkeoloji oldu: kim kimi gerçekten çağırıyor? Cevabı tracing altyapımızdan çıkardık — dört haftalık trace verisinden servis çağrı matrisi üretip politikaları önce "izle ama engelleme" modunda yaydık. İyi ki öyle yaptık: ilk politika taslağı, ayda bir çalışan ve kimsenin hatırlamadığı üç batch işini açlıktan öldürecekti. Dört haftalık gözlem, aylık işleri yakalamaya yetmedi; iz penceresini 6 haftaya uzatıp iki istisna daha bulduk. Enforcement'ı servise servise, en riskli olandan (ödeme) başlayarak açtık; tam kapsama sekiz haftada ulaştık.
Sertifikalar Konusunda Paranoyanın Doğru Dozu
IoT tarafından taşıdığım bir refleks burada da hayat kurtardı: rotasyonun kendisini tatbikatla test etmek. Mesh, workload sertifikalarını saatlik döndürüyor — bu kısım otomatik ve dertsiz. Tehlike, zincirin üstünde: mesh'in kök CA'sı ve onun altındaki ara CA. Bunların rotasyonu "yılda bir" sınıfı bir olay ve tam da bu yüzden herkesin unuttuğu, dokümanın eskidiği, yapanın şirketten ayrıldığı türden bir işlem. Biz ara CA rotasyonunu staging'de üç kez tatbikat olarak koştuk ve ikinci tatbikatta güzel bir hata yakaladık: PHP gateway'inin güven deposu, yeni ara CA'yı almadan eski sertifika zinciri geçersiz kılınırsa, monolitten gelen bütün trafik 40 saniye boyunca reddediliyordu. Üretimde bu, öğlen pikinde tam kesinti demekti. Prosedürü "önce yeni köke güven ekle, sonra yeni kökle imzala, en son eskiyi kaldır" sırasına bağladık ve her adım arasına doğrulama koyduk. Sertifika süresi dolmasına dayalı kesintiler sektörde o kadar klasik ki, panomuzda en büyük punto şu metrikte: "en yakın CA son kullanma tarihi: X gün". X, 30'un altına inerse kritik alarm çalar.
Bir de gözlemlenebilirlik faslı var: mTLS açıldıktan sonra ağ seviyesinde tcpdump ile sorun ayıklamak fiilen bitti — her şey şifreli. Bunun telafisi, proxy'lerin ürettiği zengin telemetri: hangi kimlik hangi kimliği çağırdı, TLS versiyonu neydi, politika neyi reddetti. Reddedilen her çağrı artık Grafana'da kimlik bazında görünüyor ve ilk ayda bu panel, guardrail görevi gördü: iki yeni deployment, eksik ServiceAccount yüzünden yanlış kimlikle çıkmış ve politika duvarına çarpmıştı; ikisi de müşteri etkisi doğmadan, panelden yakalandı.
Kabuğun İçinde Yeni Bir Kabuk Yok Artık
Bugün üretim trafiğimizin yüzde 97'si mTLS ile akıyor (kalan yüzde 3, emekliliği planlanan iki legacy entegrasyon; onlar ayrı bir ağ segmentinde yaşıyor) ve sonraki sızma testinde aynı senaryo — ele geçirilmiş pod'dan ödeme API'sine erişim — politika katmanında, üç ayrı log iziyle reddedildi. Rapordaki cümleyi çerçeveletmedim ama içimden geçti. Sıfır güvenin mikroservislere inmesi ne bir ürün satın almakla ne de mesh kurmakla bitiyor; kimlik, politika, rotasyon ve gözlemlenebilirlik dörtlüsünün her birinin sahibi olduğunda bitiyor — daha doğrusu, hiç bitmiyor, işletilen bir sürece dönüşüyor. Kendi kümenizde "içerisi güvenli sayılır" varsayımıyla yaşıyorsanız ve nereden başlayacağınızı bilmiyorsanız bana ulaşın; çağrı matrisi çıkarma yöntemimizi ve fazlı geçiş planımızı paylaşırım. İlk adım mesh kurmak değil, kimin kimi çağırdığını öğrenmek — biz de dahil, kimse bunu ezberden bilmiyor.
Sızma testi ekibinin lideriyle kapanış toplantısında espri yaptık: "Artık pod ele geçirince ne yapıyorsunuz?" Cevabı, bütün projenin özeti gibiydi: "Oturup log üretiyoruz. Başka bir şey yapamıyoruz."