Container Hardening – Deo 5: Pod Security Standards i mrežne politike

Prethodni deo serije pokrio je RBAC — ko sme šta da radi preko Kubernetes API-ja. Ovaj deo se bavi dvema dopunskim temama: šta sam pod (i kontejneri unutar njega) sme da radi na nivou operativnog sistema kad se pokrene, i koji pod-ovi uopšte smeju međusobno da komuniciraju preko mreže. Oba mehanizma dele istu osobinu koja ih čini posebno bitnim: Kubernetes podrazumevano ne postavlja gotovo nikakvo ograničenje ni na jedno ni na drugo, sve dok se administrator svesno ne odluči da ih uvede.

Pod Security Standards — nasledilo staru, uklonjenu funkciju

Kubernetes je nekad imao mehanizam pod nazivom PodSecurityPolicy (PSP) za ograničavanje bezbednosno osetljivih podešavanja pod-ova, ali je taj mehanizam označen kao zastareo u verziji 1.21, a potpuno uklonjen u verziji 1.25. Nasledio ga je jednostavniji, ugrađeni sistem — Pod Security Standards (PSS) — koji definiše tri unapred pripremljena, imenovana nivoa ograničenja, umesto da svaki klaster mora ručno da piše sopstvenu, prilagođenu politiku od nule.

Ova tri profila su namerno hijerarhijski postavljena, od najmanje do najviše restriktivnog: Privileged (bez ikakvih ograničenja — namenjen isključivo sistemskim komponentama koje zaista trebaju pun pristup hostu, poput mrežnih dodataka ili storage drajvera), Baseline (blokira poznate, česte vektore eskalacije privilegija — npr. deljenje mrežnog, PID ili IPC prostora imena hosta, privilegovane kontejnere, i većinu hostPath montiranja), i Restricted (dodaje strože zahteve — obavezan non-root korisnik, obavezno uklanjanje svih Linux capabilities, obavezan read-only fajl sistem, obavezan seccomp profil).

Vredi primetiti da su nazivi i zahtevi Restricted profila direktno isti oni koje smo detaljno objasnili u Docker delu serije — non-root korisnik, dropovane capabilities, read-only fajl sistem, seccomp. Kubernetes PSS ne izmišlja novu tehniku zaštite; on uzima iste, već poznate Docker/kontejner mehanizme i propisuje ih kao obavezan, proveren standard na nivou celog klastera, umesto da se oslanja na to da će svaki programer pojedinačno pravilno podesiti svaki pod.

Šta treba uraditi

  • Za produkciona, aplikativna radna opterećenja, ciljati Restricted profil kao standard — Baseline treba tretirati kao apsolutni minimum, ne kao krajnji cilj
  • Primenjivati profile kroz oznake (labels) na samom namespace-u, što je ugrađen, jednostavan mehanizam koji ne zahteva dodatne alate — namespace se označi odgovarajućom oznakom, i ugrađeni Pod Security admission kontroler automatski primenjuje odgovarajuća ograničenja na svaki pod koji se u tom namespace-u kreira
  • Koristiti "warn" i "audit" režime primene uporedo sa "enforce" režimom tokom prelaznog perioda — ovo omogućava da se vidi šta bi bilo blokirano (upozorenje korisniku, zapis u audit log) pre nego što se stvarno uključi tvrdo odbijanje, isti princip postepenog testiranja koji smo videli kod SELinux/AppArmor permissive/complain režima u ranijoj seriji
  • Rezervisati Privileged profil isključivo za sistemski, infrastrukturni namespace (gde rade CNI mrežni dodaci, storage drajveri i slične komponente kojima je pristup hostu zaista neophodan), nikad za namespace u kojem rade obične aplikacije

Napomena o riziku: direktno uvođenje Restricted profila na postojećem, aktivnom namespace-u sa pod-ovima koji nisu unapred pisani sa tim ograničenjima na umu (npr. kontejner koji očekuje da može da piše na sopstveni fajl sistem, ili koji radi kao root iz istorijskih razloga) će odbiti kreiranje tih pod-ova čim se enforce režim uključi. Koristiti prethodno pomenut warn/audit period da se identifikuju svi pod-ovi koji trenutno krše Restricted zahteve, prilagoditi njihove definicije (dodati odgovarajući securityContext, ukloniti nepotrebne capabilities), i tek nakon te pripreme preći na stvarno enforce ograničenje.

Mrežna politika — podrazumevano, svaki pod može svakome

Ovo je verovatno najveće, a najmanje intuitivno iznenađenje za nekog ko prvi put ozbiljnije gleda u Kubernetes bezbednost: bez ijedne dodatne konfiguracije, svaki pod u klasteru može mrežno da komunicira sa svakim drugim pod-om, bez obzira na to u kom se namespace-u nalaze. Ovo znači da kompromitovan pod u, recimo, namespace-u za testiranje, po difoltu ima mrežni pristup ka bazi podataka u produkcionom namespace-u — ne zato što je neko to namerno dozvolio, već zato što niko ništa nije zabranio.

NetworkPolicy je Kubernetes-ov ugrađen resurs za rešavanje ovog problema — definiše dozvoljene mrežne tokove (ko sme da se poveže ka kome, na kom portu) na osnovu oznaka pod-ova i namespace-ova, radeći na nivou 3/4 (IP adrese, portovi, protokoli), analogno standardnom firewall pravilu, samo primenjenom unutar samog klastera, na saobraćaj između pod-ova ("istok-zapad" saobraćaj), ne na saobraćaj koji ulazi ili izlazi iz klastera kao celine (za to služi mrežni firewall na granici, "sever-jug" saobraćaj — oba su potrebna, jedno ne zamenjuje drugo).

Šta treba uraditi

  • Primeniti default-deny NetworkPolicy kao prvo, polazno pravilo u svakom produkcionom namespace-u — prazan podSelector (odnosi se na sve pod-ove u namespace-u) uz definisane Ingress i Egress tipove politike bez ijednog dozvoljavajućeg pravila blokira sav dolazni i odlazni saobraćaj tog namespace-a, isti "default deny" princip primenjen na nivou pojedinačnih pod-ova
  • Odmah nakon default-deny pravila, dodati eksplicitno pravilo koje dozvoljava DNS saobraćaj (tipično ka kube-system namespace-u, na port 53) — ovo je korak koji se lako zaboravi, a bez njega pod-ovi ne mogu ni da razreše imena drugih servisa unutar klastera, što izgleda kao slomljena aplikacija, ne kao ispravno funkcionišuća bezbednosna mera
  • Graditi dodatna pravila po modelu slojeva (npr. frontend sme ka backend-u, backend sme ka bazi podataka, ali ne obrnuto, i ne "svako svakome") — svako pravilo treba da bude ograničeno na tačno određen port i tačno određenu oznaku izvornog/odredišnog pod-a, ne generičko "dozvoli sve iz ovog namespace-a"
  • Za pod-ove koji nikad ne treba da imaju izlaz ka internetu (tipičan primer — baza podataka), ne dodavati nikakvo Egress pravilo van neophodnog DNS-a i internog saobraćaja unutar klastera — ovo direktno otežava napadaču da iz kompromitovanog takvog pod-a izvuče podatke ka spoljnom serveru
  • Dodati posebno, usko pravilo za monitoring saobraćaj (npr. dozvola da alat poput Prometheus-a iz svog namespace-a "očita" metrike sa određenog porta), umesto da se monitoring namespace-u da širok pristup "za svaki slučaj"

Napomena o riziku, i tehnički detalj koji je lako previdi: NetworkPolicy objekat je samo deklaracija namere — njegovo stvarno sprovođenje zavisi u potpunosti od CNI (Container Network Interface) mrežnog dodatka koji klaster koristi. Ako klaster koristi CNI koji ne podržava sprovođenje NetworkPolicy pravila (klasičan primer je Flannel u podrazumevanoj konfiguraciji), Kubernetes API server će prihvatiti kreiranje NetworkPolicy objekta bez ikakve greške, ali taj objekat neće imati nikakav stvaran efekat na saobraćaj — lažan osećaj sigurnosti, bez stvarne zaštite iza njega. Pre nego što se osloni na NetworkPolicy kao stvarnu meru zaštite, proveriti da klaster koristi CNI koji podržava njeno sprovođenje (Calico, Cilium, Weave Net i Antrea sve podržavaju), i obavezno potvrditi stvarno funkcionisanje kroz test — kreirati politiku koja bi trebalo nešto da blokira, i konkretno proveriti da je saobraćaj zaista blokiran, ne samo pretpostaviti da jeste na osnovu toga što je objekat prihvaćen.

Zajedno — dva sloja koja se dopunjuju, ne preklapaju

Pod Security Standards i NetworkPolicy rešavaju različite probleme, i vredi to eksplicitno naglasiti da se ne bi stvorio pogrešan utisak da je jedno dovoljno bez drugog. PSS ograničava šta pod sme da radi na nivou operativnog sistema — na primer, sprečava ga da radi kao root ili da montira osetljive delove hosta. NetworkPolicy ograničava sa kim taj pod sme da razgovara preko mreže. Kompromitovan pod koji poštuje strog PSS Restricted profil, ali nema nikakvo mrežno ograničenje, i dalje može slobodno da komunicira sa svakim drugim pod-om u klasteru — dobra izolacija na nivou operativnog sistema ne nadoknađuje odsustvo mrežne segmentacije, i obrnuto.

Ovim se zaokružuje pregled kontejnerske serije — Docker (host, image, runtime) i Kubernetes (RBAC, Pod Security Standards, mrežne politike) zajedno pokrivaju osnovni, praktičan opseg onoga što sistem inženjer ili auditor treba da proveri u kontejnerizovanom okruženju. Dalji nastavak može ići u dubinu na specifične teme poput bezbednosti samog etcd skladišta (gde Kubernetes čuva celokupno stanje klastera, uključujući Secrets), enkripcije podataka u mirovanju na nivou klastera, ili detaljnijeg pregleda admission kontrolera poput Kyverno i OPA Gatekeeper za pravila koja izlaze van onoga što ugrađeni PSS profili pokrivaju, u zavisnosti od toga šta se pokaže najkorisnijim za dalje čitanje.

Comments

Popular posts from this blog

Šta je ISO 27001 i da li je mojoj firmi stvarno potreban?

ISO 22301:2019 u praksi — Praktična obuka na primeru fabrike piva

ISO 27031: Upravljanje IRBC-om i usklađivanje sa ciljevima kontinuiteta (klauzula 6.1–6.3)