labs

Bu lab modernize edildi ama ucтan uca dogrulanmadi. Takilirsaniz bize bildirin.

Container Güvenlik Kontrolleri

50 dkdockerkubernetesGitHub'da gor
Bu sayfada

Container Güvenliği

Uygulamalarınızı Kubernetes'te modelleyip çalıştırmak oldukça kolay, ama üretime geçmeden önce yapılacak daha çok iş var — ve güvenlik bunların başında geliyor.

Kubernetes'te uygulama güvenliği çoğunlukla container'ları güvenceye almakla ilgilidir; o da çoğunlukla Linux güvenlik önlemlerini uygulamakla ilgilidir. Uygulayabileceğiniz çok sayıda kontrol var, ama her uygulama hepsini desteklemiyor.

Uygulamalarınızın hangi işletim sistemi özelliklerine ihtiyaç duyduğunu anlamanız gerekiyor, çünkü kontrol uygulamak onları bozabilir — Go uygulamaları salt okunur bir dosya sisteminde sorunsuz çalışabilirken Java uygulamaları hata verecektir.

Kaynaklar

Kubernetes API sunucusuna erişimi kaldırmak

Varsayılan Kubernetes güvenlik kontrolleri cesaret verici değil.

Pi web uygulamasını çalıştırarak başlayalım; güvenlik sorunlarını kontrol etmek için onu kullanacağız:

kubectl apply -f labs/container-security/specs/pi

Pi uygulaması tek bir Pod'da çalışıyor ve siteyi Service üzerinden http://localhost:30020 adresinde kontrol edebilirsiniz.

Deployment belirtiminde güvenlikle ilgili özel bir şey yok.

Kubernetes varsayılan olarak her Pod'a, içinde bir kimlik doğrulama token'ı bulunan bir volume bağlıyor; böylece Pod içindeki uygulamalar Kubernetes API sunucusunu kullanabiliyor. Prometheus ve Fluentd gibi uygulamalar Pod'ları ve diğer nesneleri bulabilmek için API erişimine ihtiyaç duyuyor — ama neredeyse hiçbir iş uygulamasının buna ihtiyacı yok.

Token Pi uygulamasında da duruyor:

kubectl exec deploy/pi-web -- cat /var/run/secrets/kubernetes.io/serviceaccount/token

Kubernetes kümesiyle kimlik doğrulaması yapmak için gereken tek şey bu (bu tür token'ları Kubectl ile kullanabilirsiniz) ve ardından Pod ile tamamen aynı izinlere sahip olurdunuz.

Kubernetes 1.21'den beri bunlar bound (bağlı) token'lar — kısa ömürlü ve bu Pod ile hedef kitleye bağlı, dolayısıyla çalınan bir token'ın süresi doluyor. Bu, etki alanını küçültüyor; ortadan kaldırmıyor — bu yüzden volume'u yine de kaldırıyoruz.

Bu Pod, varsayılan Service Account'u kullanıyor — Pod'ların API'ye erişmek için kullandığı Kubernetes kimliği. Başka kullanıcılar kendi ihtiyaçları için o hesaba ek izinler vermiş olabilir ve bir saldırgan Pi uygulamasını ele geçirirse Secret'ları okumaya veya çalışan uygulamaları silmeye serbest erişimi olabilir.

fix-1.yaml, kimlik doğrulama token'ını bağlamayacak şekilde ayarlanmış özel bir ServiceAccount oluşturuyor ve Pod belirtimi o hesabı kullanıyor.

📋 Düzeltmeyi uygulayın. Yeni Pod'da token'ı okuyabiliyor musunuz?

Nasıl yapılacağını bilmiyor musunuz?

Değişiklikleri gönderin:

kubectl apply -f labs/container-security/specs/pi/fixes/fix-1.yaml

Yeni Pod'un başlamasını bekleyin:

kubectl get po -l app=pi-web --watch

Ve token'ı yazdırmayı deneyin:

# bir hata goreceksiniz - No such file or directory
kubectl exec deploy/pi-web -- cat /var/run/secrets/kubernetes.io/serviceaccount/token

Bu, bir güvenlik açığını kapatıyor. Kararlı saldırganları durdurmayacak ama işlerini bu kadar kolaylaştırmıyor.

Hesaplama kaynaklarını kısıtlamak

Container süreçleri doğrudan host makinenin işletim sistemi üzerinde çalışıyor. Varsayılan olarak o makinedeki tüm CPU çekirdeklerine ve tüm belleğe erişebiliyorlar. Kubernetes kümelerinde genellikle her düğümde bol miktarda Pod çalışıyor ve hesaplama kaynaklarını kısıtlamazsanız kendinizi bir hizmet engelleme (denial-of-service) saldırısına açık bırakıyorsunuz.

Pi uygulaması hiçbir hesaplama kısıtı olmadan çalışıyor. Pi'yi yüksek sayıda ondalık basamakla hesaplamayı deneyin — bu URL için iki sekme açın: http://localhost:30020/pi?dp=100000. Makinenizin CPU'suna bakın; Pi hesaplamak zahmetli bir iş olduğu için tırmandığını görebilirsiniz.

fix-2.yaml kaynak kısıtları uyguluyor:

  • requests, uygulamanızın çalışmak için ihtiyaç duyduğu CPU ve bellek

    miktarını belirtiyor; Kubernetes, Pod'u hangi düğümün çalıştıracağına karar verirken düğümlerdeki mevcut kaynak miktarına göre bunu kullanıyor

  • limits, uygulamanın kullanabileceği CPU ve belleğin katı üst sınırını

    belirtiyor. CPU kısıtlanıyor; yani 0.5 çekirdek ayarlarsanız uygulama %100 CPU'da çalışabilir ama sunucuda yalnızca 0.5 çekirdeği doldurabilir. Bellek de kısıtlanıyor ve uygulama limitin üzerine çıkmaya çalışırsa Pod bellek yetmedi (out-of-memory) hatasıyla öldürülebilir.

📋 Düzeltmeyi uygulayın. Pi'yi 100 bin basamağa hesaplamak hâlâ CPU tırmanmasına yol açıyor mu?

Nasıl yapılacağını bilmiyor musunuz?

Değişiklikleri gönderin:

kubectl apply -f labs/container-security/specs/pi/fixes/fix-2.yaml

Yeni Pod'un başlamasını bekleyin:

kubectl get po -l app=pi-web --watch

http://localhost:30020/pi?dp=100000 adresini açın — makinenizin CPU'sunda bir etki görmemelisiniz ama sayfanın yanıt vermesi çok daha uzun sürecek.

Kaynak limitleri, hizmet engelleme saldırısını önlemenin basit bir yolu; ama uygulamanızın etkili çalışmaya yetecek kaynağa sahip olduğundan emin olmak için zaman içinde onları değerlendirmeye devam etmeniz gerekiyor (umarız uygulamanız zamanla daha performanslı olur ve her sürümde limitleri düşürebilirsiniz).

İşletim sistemi yeteneklerini kısıtlamak

Container süreçleri sunucuda, sunucudaki bir kullanıcıya karşılık gelen bir kimlikle çalışıyor. Çok sayıda container imajı — resmi imajlar bile — uygulama süreci için root kullanıcısını kullanıyor.

Bu çok kötü. Bir saldırgan container'dan dışarı çıkmayı başarırsa (bu tür istismarlar keşfedildi), sunucudaki yönetici kullanıcı olur. Yani sunucudaki diğer container'lara saldırabilir ya da ağdaki başka makinelere erişebilir.

Pi uygulamasının kullanıcı hesabını kontrol edin:

kubectl exec deploy/pi-web -- whoami

root — ve bu imaj kasıtlı olarak güvensiz yapılmış değil. Dockerfile'a bakın — Microsoft'un resmi ASP.NET çalışma ortamı imajını hiçbir özel kurulum olmadan kullanıyor.

Container süreçleri, standart Kubernetes yapılandırmasıyla ihtiyaç duyduklarından fazla Linux yeteneğine (capability) de sahip. chown, dosya sahipliğini değiştirmenizi sağlayan bir Linux komutu — Pi container'ında mevcut:

kubectl exec deploy/pi-web -- chown root:root /app/Pi.Web.dll

fix-3.yaml container'ı root olmayan bir kullanıcı olarak çalıştırıyor, fazla Linux yeteneklerinin tamamını düşürüyor (uygulamanın onlara ihtiyacı yok) ve süreçlerin ek ayrıcalık istemesini engelliyor.

📋 Düzeltmeyi uygulayın. Uygulama nasıl görünüyor?

Nasıl yapılacağını bilmiyor musunuz?

Değişiklikleri gönderin:

kubectl apply -f labs/container-security/specs/pi/fixes/fix-3.yaml

Yeni Pod'un başlamasını bekleyin:

kubectl get po -l app=pi-web --watch

http://localhost:30020/ adresini açın — uygulama hâlâ çalışıyor.

Bu uygulama beklendiği gibi çalışmaya devam ediyor, ama bazı uygulamalarda izin kaldırmak onların hiç başlamaması anlamına geliyor — kısıtlı yeteneklerle 80 portunu dinlemek başarısız olabilir.

fix-4.yaml uygulamayı container içinde 5001 portunu dinleyecek şekilde yapılandırıyor; böylece 80 portu için ayrıcalıklı erişim ihtiyacı ortadan kalkıyor — uygulamanın bunu desteklemesi gerekiyor.

kubectl apply -f labs/container-security/specs/pi/fixes/fix-4.yaml

Container portu değişmiş olmasına rağmen uygulama http://localhost:30020 adresinde çalışmaya devam ediyor, çünkü Service hedef portu numarayla değil adıyla (http) gösteriyor. Orada 80 sabitlenmiş olsaydı Service hiçbir şeye işaret etmez hale gelirdi.


Lab

Bu, güvenliğin sonu değil — yalnızca başlangıcı. Container'ları güvenceye almak imajlarınızı güvenceye almakla başlayan katmanlı bir yaklaşım; ama sıkılaştırılmış Pi uygulaması varsayılan Pod güvenliğinden iyi bir adım ileride.

Yine de her uygulama bu kontrollerle çalışmayacak. İşte tüm güvenlik kontrolleri yorum satırına alınmış whoami uygulaması için bir Deployment.

Göreviniz, uygulamayı bozmadan hangi kontrol kümesinin uygulanabileceğini çözmek. Olduğu gibi dağıtarak başlayın:

kubectl apply -f labs/container-security/specs/whoami

Uygulamayı http://localhost:30022/ adresinde kullanabildiğinizi doğrulayın. Sonra uygulama hâlâ çalışır durumda kalacak şekilde, mümkün olan en çok kontrolü etkinleştirene kadar güvenlik kontrollerini ekleyin.

Takıldınız mı? İpuçlarına bakın veya çözümü inceleyin.


Temizlik

kubectl delete all -l kubernetes.courselabs.co=container-security