Ağ politikaları ve pod güvenlik standartları
- Küme ağı varsayılan olarak düzdür; ağ politikası önce her şeyi kapatır, pod güvenlik standartları üç seviyede sertleştirir.
- Ağ politikası önce her şeyi kapatır, sonra gereken yolu açar.
- Pod güvenlik standartları üç seviyede sertleştirme tanımlar.
Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +60 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.
Bu derste kümeyi iki katmanda sertleştirirsin. Önce ağ: podlar arası trafiği varsayılan açıklıktan alıp bilinen yollara daraltırsın. Sonra pod: konteynerlerin düğümde ne yapabileceğini kısarsın.
İki katman birbirini tamamlar; biri yan geçişi zorlaştırır, öteki ele geçen bir podun düğüme çıkmasını engeller. Bir saldırgan tek bir açıkla içeri girse bile, bu iki katman onun ilerlemesini durdurur. Komutları ve tanımları kendi laboratuvar kümende deneyebilirsin.
Varsayılan düz ağ ve ağ politikası
Yeni kurulan bir kümede podlar arası trafik tamamen serbesttir. Ön yüzdeki bir pod, başka bir ad alanındaki veritabanı poduna doğrudan bağlanır. Ad alanı bir yalıtım sınırı gibi görünür ama ağ katmanında değildir; yalnız bir etiket kümesidir.
Pod IP'sini bilen herkes doğrudan bağlanır. Bulut güvenlik grubu da bu ayrımı yapamaz: aynı düğümdeki iki podun trafiği düğümden hiç çıkmaz, farklı düğümler arasındaki trafik ise çoğu kurulumda bir tünelde akar. Bu yüzden bir denetim, dış güvenlik duvarına bakıp temiz demekle tamamlanmaz; asıl soru küme içinde hangi podun hangi poda ulaşabildiğidir.
Ağ politikası bu düzlüğü bozar ve etiketlerle çalışır, IP ile değil. Hangi etiketli podun hangi etiketli poda, hangi portta erişeceğini yazarsın; podlar yeniden oluşsa ve IP'leri değişse de kural geçerli kalır, çünkü kural etikete bağlıdır. İşe en kolay başlangıç, bir ad alanına boş seçicili ve kuralsız bir politika yazmaktır.
Boş seçici o ad alanındaki tüm podları kapsar, boş kural listesi hiçbir giriş izni bırakmaz. O andan sonra ne gerekiyorsa tek tek açarsın; varsayılan artık reddetmektir, izin vermek değil.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: varsayilan-kapali
namespace: uretim
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]Çıkış trafiğini de düşünmek gerekir. Girişi kapatmak içeri girmeyi zorlaştırır; çıkışı kapatmak ise veri sızdırmayı ve komuta sunucusuna bağlanmayı engeller. Ele geçmiş bir pod dışarı veri gönderemiyorsa, saldırganın işi yarıda kalır.
Pod ağından üstveri adresine giden çıkışı kapatmak ayrı bir kazançtır ve bir sonraki dersin konusuna bağlanır. Bir uyarı da gerekir: ağ politikası yalnız onu uygulayan bir ağ eklentisi varsa çalışır. Eklenti desteklemiyorsa nesne yazılır, kabul edilir ve hiçbir etkisi olmaz. Bu yüzden politikayı yazdıktan sonra bir test poduyla bağlantının gerçekten kesildiğini doğrularsın.
Etkinlik 1 / 6
Bu ağ politikası uygulandığında uretim ad alanındaki podlara ne olur?
Önce kodu oku, sonra çıktıyı seç.
kind: NetworkPolicy
metadata:
name: varsayilan-kapali
namespace: uretim
spec:
podSelector: {}
policyTypes: ["Ingress"]Gereken yolu açmak
Varsayılan kapalı politikadan sonra gereken yolları tek tek açarsın. Politika yazmaya tersten başlamak en hızlı sonucu verir: önce en hassas iş yükünü seçersin, ona gelen trafiği tamamen kapatırsın, sonra yalnız gerçek çağıranı açarsın. Tek bir veritabanı podunu doğru korumak, tüm kümeyi bir günde kapatmaya çalışmaktan daha az kırılma yaratır ve daha çabuk biter. Aşağıdaki politika uretim ad alanındaki veritabanı podlarına yalnız api etiketli podlardan ve yalnız 5432 numaralı TCP portundan giriş açar.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-girisi
namespace: uretim
spec:
podSelector:
matchLabels:
app: db
policyTypes: ["Ingress"]
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 5432Tanımı oku. podSelector politikanın hangi podları koruduğunu söyler: app=db etiketli podlar.
ingress altındaki from bölümü kimin gelebileceğini, ports bölümü hangi porttan gelebileceğini yazar. İkisi aynı kural içinde durduğu için birlikte geçerlidir: api podu başka bir porta, başka bir pod da 5432'ye bağlanamaz. Çıkışı da kapattıysan iş bitmez.
api podlarının db'ye giden çıkışını ayrıca açarsın, DNS sorgularını da unutmazsın. Çıkış kapalıyken kube-system'deki DNS podlarına giden UDP ve TCP 53 trafiği açılmazsa her ad çözümü düşer. Varsayılan kapalı çıkışın en sık kırdığı şey budur.
$ kubectl run test -n uretim --rm -it --restart=Never --image=busybox:1.36 --labels=app=api -- nc -zv -w 2 db 5432 db (10.96.12.40:5432) open pod "test" deleted $ kubectl run test -n deneme --rm -it --restart=Never --image=busybox:1.36 -- nc -zv -w 2 db.uretim 5432 nc: db.uretim (10.96.12.40:5432): Connection timed out pod "test" deleted
Test çıktısını oku. İlk podun app=api etiketi var ve bağlantı açılıyor.
İkinci pod başka bir ad alanından ve etiketsiz geliyor; iki saniye sonra zaman aşımına düşüyor. Politika beklendiği gibi çalışıyor. İkinci bağlantı da açılsaydı ilk şüphe ağ eklentisi olurdu.
Doğrulamaya politikadan önce başlamak da işe yarar. Hiç politika yokken aynı etiketsiz test podu ad alanı gözetmeden her poda ulaşır. Bu taban ölçümü, kurulumdan hemen sonra yalıtım sandığın yerin aslında açık olduğunu gösterir ve her yeni kuralın neyi değiştirdiğini kanıtlar.
Etkinlik 2 / 6
Ağ politikası tanımlanmamış bir kümede podlar arası trafik nasıl davranır?
Pod güvenlik standartları ve kabul modları
İkinci sertleştirme katmanı pod güvenlik standartlarıdır ve üç seviye tanımlar. Ayrıcalıklı seviye hiçbir kısıt koymaz; yalnız bilinçli istisnalar, örneğin düğüm ajanları için vardır. Temel seviye bilinen kaçış yollarını kapatır: ayrıcalıklı konteyneri, ana makine ağını ve ana makine yolu birimlerini yasaklar.
Kısıtlı seviye bunun üstüne sertleştirme şartları koyar: kök olmama, yetki yükseltmeyi kapatma, tüm yetenekleri düşürme ve varsayılan sistem çağrısı süzgecini uygulama. Çoğu iş yükü kısıtlı seviyede sorunsuz koşar ve hedef de budur; ayrıcalıklı seviye bir kaçış, kural değildir.
Seviyeler arasındaki fark nerede durduklarını bilmekle anlaşılır. Temel seviye konteynerin düğüme kaçmasını zorlaştıran kapıları kapatır; ayrıcalıklı mod ya da ana makine ağı, konteyner sınırını baştan deldiği için bu seviyede yasaktır. Kısıtlı seviye ise konteynerin kendi içinde en az yetkiyle çalışmasını zorlar; kök olarak başlayan ya da ekstra yetenek isteyen bir pod bu seviyede reddedilir. Bir iş yükünü kısıtlı seviyeye taşırken genelde birkaç satır eklemek yeter, ama kök kullanıcı bekleyen eski imajlar kırılabilir; bu yüzden geçiş aşamalı yapılır ve önce uyarı moduyla ölçülür.
Standartlar bir ad alanına kabul denetleyicisiyle uygulanır. Ad alanına bir etiket koyarsın: pod-security.kubernetes.io/<mod> değeri bir seviyeye ayarlanır. Üç mod vardır. enforce ihlal eden podu baştan reddeder.
audit ihlali denetim günlüğüne yazar ama podu yine geçirir. warn ise podu oluştururken kullanıcıya bir uyarı gösterir.
Yaygın yol önce warn ve audit ile başlamaktır; hangi iş yükünün kırılacağını önceden görür, düzeltir, sonra enforce moduna alırsın. Böylece sertleştirme bir ekibi gafil avlamaz. Eski PodSecurityPolicy 1.25'te kaldırıldığı için yeni kümelerde bu yerleşik denetleyici kullanılır.
Etiketi bir sürüme sabitlemek de işe yarar. Mod etiketinin yanına bir sürüm etiketi koyabilirsin; o ad alanı seviyeyi belirli bir Kubernetes sürümünün kurallarıyla uygular. Böylece küme yükseldiğinde kuralların sessizce sertleşip bir iş yükünü beklenmedik anda kırması önlenir.
Yaygın düzen şudur: enforce modunu güncel ama sabit bir sürüme bağlarsın, warn ve audit modlarını ise en son kurallara açık bırakırsın. O zaman uyarı günlüğü gelecekteki sertleşmeyi önceden gösterir, sen de iş yüklerini acele etmeden hazırlarsın.
Etkinlik 3 / 6
Her ayarı ait olduğu pod güvenlik standardına göre ayır.
Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.
0/6 seçenek yerleşti.
securityContext ile sertleştirme
Kısıtlı seviyeye geçmeden önce etkiyi ölçersin. Ad alanını warn modunda kısıtlı seviyeye bağlar, var olan bir pod tanımını uygularsın.
Pod yine oluşur ama kabul denetleyicisi her ihlali kubectl çıktısına yazar. Bu çıktı, düzeltilecek alanların adını tek tek verdiği için bir yapılacaklar listesi gibi okunur. Böylece hangi iş yükünün kırılacağını enforce moduna geçmeden görürsün. Aşağıdaki örnekte etiket ve uygulama komutu art arda çalışıyor.
$ kubectl label ns uretim pod-security.kubernetes.io/warn=restricted $ kubectl apply -n uretim -f temel-pod.yaml Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile pod/ornek created
Uyarıyı oku: pod oluştu, ama dört madde kısıtlı seviyeyi kırıyor ve her biri eksik alanı adıyla söylüyor. allowPrivilegeEscalation false değil, yetenekler düşürülmemiş, runAsNonRoot true değil ve seccomp profili tanımsız. warn modunda bu yalnız bir uyarıdır. Aynı pod enforce modunda hiç oluşmazdı ve kubectl bir hata döndürürdü.
Asıl sertleştirme pod tanımındaki securityContext alanında yapılır. Aşağıdaki tanım bu dört maddeyi kapatır ve bir adım daha ekler.
apiVersion: v1
kind: Pod
metadata:
name: api
namespace: uretim
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: uygulama:1.4
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]Tanımı yukarıdan aşağı oku. Pod düzeyindeki runAsNonRoot, kök kullanıcıyla başlayan konteyneri reddettirir. runAsUser 10001 ise imajda kök olmayan bir kullanıcı tanımlı değilse süreci bu kimlikle başlatır. seccompProfile değerini RuntimeDefault yapmak, çalışma ortamının varsayılan sistem çağrısı süzgecini açar.
Konteyner düzeyinde allowPrivilegeEscalation false olunca setuid ikililerle yetki kazanmak kapanır. capabilities altında ALL düşürülünce fazladan çekirdek yetkisi kalmaz. readOnlyRootFilesystem standardın şartı değildir ama iyi bir ek katmandır: konteyner kendi dosyalarını değiştiremez. Uygulamanın geçici dosyaya ihtiyacı varsa yalnız o dizine bir emptyDir bağlarsın.
Etkinlik 4 / 6
Bu pod tanımında güvenlik standardını kıran satırı bul.
Ölçme ve doğrulama
Pod güvenlik standartları hazır bir çerçeve verir ama her şartı karşılamaz; sabit üç seviyeyle sınırlıdır. Küme genelinde kendi kurallarını zorlamak için bir politika motoru kullanılır. Kyverno ve Gatekeeper gibi araçlar kabul aşamasında çalışır ve standartların ötesine geçer: imza zorunluluğu, etiket zorunluluğu, kaynak sınırı koyarsın.
Kubernetes'in yerleşik doğrulayan kabul politikası da benzer işi küçük bir ifade diliyle yapar ve ek bir bileşen kurmadan küme içinde çalışır; 1.30'dan beri kararlıdır. İmza, kaynak sınırı ve etiket gibi kurumsal kurallar bu katmanda tek yerden tanımlanır ve her yeni iş yüküne otomatik uygulanır.
Sertleştirmeyi ölçmek için kube-bench çalıştırılır. Araç CIS Kubernetes ölçütündeki maddeleri tek tek koşar ve her maddeyi işaretler: PASS geçti, FAIL kaldı, WARN elle bakılmalı, INFO ise yalnız bilgi. İlk turda FAIL ve WARN listesi uzun olur, sonraki turlarda kısalır. Araç bir iş olarak kümede çalıştırılır ve çıktısı bir pod günlüğünden okunur.
Yönetilen kümede denetim düzlemi maddeleri sağlayıcıya aittir, bu yüzden ağırlık düğüm maddelerindedir. Ölçmenin asıl değeri karşılaştırmadadır; aynı denetimi üç ayda bir koşarsan sertleştirmenin ilerlediğini ya da geri gittiğini görürsün. Tek seferlik bir rapor rafta kalır ve kısa sürede eskir.
Ağ ve pod katmanının yanında kaynak sınırı da bir sertleştirmedir. ResourceQuota bir ad alanının toplam işlemci ve bellek tavanını koyar; LimitRange ise tek bir konteynerin varsayılan ve en yüksek payını belirler. Sınırsız bir pod, bir açıkla kötüye kullanıldığında düğümün tüm kaynağını yiyip komşu iş yüklerini de düşürebilir, bu yüzden sınır bir erişilebilirlik önlemidir.
Daha ileri bir adım, podlar arası trafiği şifrelemektir. Cilium ya da bir servis ağı, aynı küme içindeki pod bağlantılarını da şifreli taşır. Böylece düğümler arası trafiği dinlemek anlamsız hale gelir.
Etkinlik 5 / 6
Doğru mu, yanlış mı?
kube-bench kümenin yapılandırmasını kabul görmüş sertleştirme ölçütlerine göre denetler.
Bir politikanın gerçekten uygulandığını görmek için podun tam tanımını okursun. Panelde görünmeyen bir ayrıcalıklı işareti ya da bağlanmış bir ana makine yolu, ancak tam YAML'da ortaya çıkar; özet görünümler bu alanları çoğu zaman gizler. Bu yüzden bir denetimde özete değil, kaynağın kendisine bakarsın.
Sertleştirmeyi tek seferde uygulamaya çalışmak genelde geri teper; ekipler kırılan iş yükleriyle uğraşır ve kurallar sessizce gevşetilir. Aşamalı yol daha kalıcıdır: önce yeni iş yüklerine uygula, sonra var olanları taşı, her adımda hangi kuralın ne kadar iş yükünü etkilediğini ölç ve paylaş.
Etkinlik 6 / 6
uretim ad alanındaki api-7d9 podunun tam tanımını YAML olarak oku.
Derinleş:Kabul politikası motoru
Pod güvenlik standartları sabit üç seviye sunar; kuruma özel bir kural için bir politika motoru gerekir. Kubernetes'in yerleşik doğrulayan kabul politikası iki nesneyle kurulur. ValidatingAdmissionPolicy kuralı tanımlar: hangi kaynaklara bakılacağını ve Common Expression Language ile yazılmış doğrulama ifadesini taşır.
Örneğin object.spec.containers.all(c, c.image.contains('@sha256:')) ifadesi her imajın özetiyle sabitlenmesini ister. ValidatingAdmissionPolicyBinding ise kuralı hangi ad alanlarına uygulayacağını ve ihlalde ne olacağını söyler.
Deny isteği reddeder, Warn kullanıcıya uyarı gösterir, Audit ihlali denetim günlüğüne yazar. Bu üç eylem pod güvenlik kabulündeki enforce, warn ve audit modlarına benzer, bu yüzden aynı aşamalı geçiş burada da işler. Kyverno kuralları YAML ile yazar, Gatekeeper ise Open Policy Agent'ın Rego dilini kullanır. İkisi de ayrı bir bileşen olarak kurulur ve kabul webhook'u üstünden çalışır.
Okumayı istediğin sırayla sürdürebilirsin. Ders, bütün etkinlikleri cevapladığında tamamlanır.