Container Hardening – Deo 4: Kubernetes – RBAC i osnove pristupa klasteru

Prethodna tri dela serije pokrila su Docker — pojedinačni host koji pokreće kontejnere. Ovaj i naredni delovi prelaze na Kubernetes, sistem koji orkestrira kontejnere preko više hostova odjednom. Veći deo principa iz Docker dela serije i dalje važi — minimalni image-i, seccomp, capabilities, sve to se i dalje primenjuje na pojedinačan kontejner unutar Kubernetes pod-a. Ono što je novo, i što ova celina serije pokriva, jeste sloj koji Kubernetes dodaje iznad toga: ko sme šta da radi unutar samog klastera. Prvi deo ove celine bavi se RBAC-om — mehanizmom koji na to pitanje odgovara.

Šta RBAC jeste, a šta nije

Vredi razjasniti ovo pre svega ostalog, jer je česta zabuna: RBAC (Role-Based Access Control) u Kubernetes-u ne bavi se time ko je neko (to je posao autentifikacije — sertifikati, tokeni, spoljni identity provajder), već isključivo time šta ta već potvrđena identifikovana osoba ili servis sme da uradi. Svaki zahtev upućen Kubernetes API serveru — bilo da dolazi od čoveka preko kubectl alata, ili od aplikacije koja radi unutar samog klastera — prolazi kroz RBAC proveru, i podrazumevano ponašanje je da se svaki zahtev bez eksplicitnog dozvoljavajućeg pravila odbija. Ovo je isti "default deny" princip koji se provlači kroz svaku seriju na ovom blogu, ovde primenjen na nivou API poziva unutar klastera.

Četiri gradivna bloka RBAC-a

RBAC u Kubernetes-u se sastoji od dva para objekata koji rade zajedno. Role definiše skup dozvola (koje akcije, npr. "čitaj", "izmeni", "obriši" — u Kubernetes terminologiji nazvane "verbs" — nad kojim tipom resursa, npr. pod-ovima ili konfiguracionim podacima) unutar jednog konkretnog namespace-a (logičke pregrade unutar klastera). ClusterRole radi identično, ali važi na nivou celog klastera, ne samo jednog namespace-a.

Sama definicija role ne daje nikome ništa — ona samo opisuje šta ta uloga podrazumeva. Da bi neko (korisnik, grupa, ili service account — identitet koji koriste same aplikacije unutar klastera) stvarno dobio te dozvole, mora postojati RoleBinding (povezuje Role sa konkretnim identitetom unutar jednog namespace-a) ili ClusterRoleBinding (povezuje ClusterRole sa identitetom na nivou celog klastera). Razdvajanje definicije uloge od njene dodele je namerno — omogućava da se ista, jednom definisana uloga (npr. "sme da čita, ali ne i menja konfiguracije") ponovo iskoristi za više različitih ljudi ili aplikacija, bez ponovnog pisanja istih pravila.

Šta treba uraditi

  • Dodeljivati dozvole na nivou namespace-a (Role + RoleBinding) kad god je to dovoljno za stvarnu potrebu, umesto automatskog posezanja za ClusterRole i ClusterRoleBinding — dozvola koja važi na celom klastera je po definiciji širi, rizičniji opseg nego dozvola ograničena na jedan namespace
  • Za svaku definisanu ulogu, eksplicitno navesti tačno potrebne "verbs" (get, list, watch, create, update, delete) i tačno potrebne tipove resursa — izbegavati wildcard ("*") koji dozvoljava sve akcije nad svim resursima, osim u retkim, svesno opravdanim slučajevima
  • Nikad ne dodeljivati ugrađenu cluster-admin ulogu (koja daje neograničen pristup celom klasteru) rutinski, "da bi se izbegli problemi sa dozvolama" — ovo je Kubernetes ekvivalent Domain Admin naloga iz AD hardening serije, i zaslužuje istu, izuzetnu opreznost
  • Redovno proveravati stvarne, efektivne dozvole konkretnog korisnika ili service account-a (kroz `kubectl auth can-i --as= --list`) kao proveru da li dodeljena uloga zaista odgovara onome što je namenjeno, umesto da se pretpostavi da je definicija role ispravna samo zato što je tako napisana

Service account-i — identitet koji aplikacije koriste, ne ljudi

Svaki pod (najmanja pokretna jedinica u Kubernetes-u, koja sadrži jedan ili više kontejnera) radi pod nekim service account-om — identitetom koji, ako pod treba da komunicira sa Kubernetes API serverom (npr. da pročita sopstvenu konfiguraciju ili da pokrene drugi pod), koristi taj identitet za autentifikaciju. Ako se ne navede eksplicitno, pod koristi podrazumevani ("default") service account tog namespace-a — praksa koja stvara ozbiljan problem: svi pod-ovi u tom namespace-u koji ne navedu sopstveni, namenski service account dele isti identitet, čineći nemogućim razlikovanje ko je od njih šta uradio, i čineći da širenje dozvola jednom od njih automatski utiče na sve ostale.

Šta treba uraditi

  • Kreirati po jedan, namenski service account za svako radno opterećenje (aplikaciju) koje zaista treba da komunicira sa Kubernetes API-jem, umesto oslanjanja na podrazumevani service account tog namespace-a
  • Nikad ne koristiti default service account za produkciona radna opterećenja — ovo je isti princip "dedikovan servisni nalog po aplikaciji", već poznat iz MSSQL hardening serije, ovde primenjen na Kubernetes identitete
  • Vezati (bind) ulogu za service account tačno onoliko usko koliko je stvarno potrebno za tu konkretnu aplikaciju — mnoge aplikacije koje rade unutar Kubernetes-a uopšte ne trebaju da komuniciraju sa Kubernetes API-jem, i njima service account treba samo formalno da postoji, bez ijedne dodeljene dozvole

Automatsko montiranje tokena — podrazumevano uključeno, retko potrebno

Ovo je konkretno, tehnički lako razumljivo, a često previđeno podešavanje. Kubernetes podrazumevano automatski montira token service account-a (kredencijal koji se koristi za autentifikaciju ka API serveru) unutar svakog pod-a, čak i kad taj pod nikad ne planira da komunicira sa Kubernetes API-jem. Ovo znači da svaki takav pod, čak i običan veb server koji nikad ne poziva Kubernetes API, ima unutar sebe validan kredencijal koji bi napadač, u slučaju kompromitacije tog pod-a, mogao pokušati da iskoristi za dalje kretanje unutar klastera.

Šta treba uraditi

  • Postaviti automountServiceAccountToken: false u definiciji pod-a (ili na nivou samog service account-a) za sva radna opterećenja koja ne pozivaju Kubernetes API — ovo je jednostavna, gotovo besplatna mera koja uklanja kredencijal koji tom pod-u ionako nikad nije bio potreban
  • Za pod-ove kojima token stvarno treba, ostaviti automatsko montiranje uključenim, ali obezbediti da service account tog pod-a ima strogo ograničene, tačno potrebne dozvole opisane ranije u tekstu — sam token je bezopasan onoliko koliko su ograničene dozvole koje taj token predstavlja

Napomena o riziku: isključivanje automatskog montiranja tokena za pod koji, ispostavi se, ipak nešto poziva na Kubernetes API (možda posredno, kroz biblioteku ili operator koji programer nije unapred očekivao) izazvaće grešku pri pokušaju tog poziva. Proveriti stvarno ponašanje aplikacije pre uvođenja ove promene na produkcionim radnim opterećenjima, ne pretpostaviti unapred da aplikacija "sigurno" ne komunicira sa API-jem samo zato što to nije njena očigledna, primarna svrha.

Zašto pristup Secrets objektima zaslužuje posebnu pažnju

Kubernetes Secrets su namenski objekat za čuvanje osetljivih podataka — lozinki, tokena, sertifikata — unutar klastera. Dozvola koja omogućava "get" ili "list" akciju nad Secrets objektima na nivou celog klastera (ne ograničena na jedan namespace) je efektivno ekvivalentna mogućnosti čitanja svake lozinke i svakog kredencijala koji bilo koja aplikacija u tom klasteru koristi — isti nivo rizika kao i DCSync napad opisan u AD hardening seriji, samo u kontekstu Kubernetes-a umesto Active Directory-ja.

Šta treba uraditi

  • Nikad ne dodeljivati "get", "list" ili "watch" dozvole nad Secrets objektima na nivou celog klastera — ako je pristup Secrets objektima zaista potreban, ograničiti ga na tačno određen namespace i, gde je moguće, na tačno određene, imenovane Secret objekte, ne na sve Secrets u tom namespace-u
  • Razmotriti spoljni sistem za upravljanje tajnama (npr. HashiCorp Vault ili ekvivalentno rešenje kod cloud provajdera) za posebno osetljive kredencijale, umesto oslanjanja isključivo na ugrađeni Kubernetes Secrets mehanizam, koji po difoltu čuva podatke samo base64-kodirane, ne kriptografski zaštićene
  • Gde je dostupno kroz cloud provajdera (Workload Identity na GKE, IAM Roles for Service Accounts na EKS, Workload Identity na AKS), koristiti federaciju identiteta umesto dugotrajnih, statičkih kredencijala uskladištenih kao Kubernetes Secret — ovo eliminiše čitav rizik da neko izvuče trajan kredencijal iz klastera, jer se pristup dodeljuje privremeno, po zahtevu

Nasleđene, sistemske dozvole — proveriti šta je već tu

Sam Kubernetes dolazi sa određenim, unapred definisanim dozvolama za sistemske naloge, i deo tih podrazumevanih podešavanja je širi nego što je realno potrebno u svakom okruženju. Posebno vredi proveriti da li grupa system:unauthenticated (koja predstavlja bilo koga ko može mrežno da dopre do API servera, bez ikakve autentifikacije) ima bilo kakvu dodeljenu dozvolu — ako ima, to znači da apsolutno bilo ko sa mrežnim pristupom API serveru, čak i bez validnog identiteta, može izvršiti tu akciju.

Šta treba uraditi

  • Proveriti sve RoleBinding i ClusterRoleBinding objekte koji uključuju system:unauthenticated ili system:anonymous grupu, i ukloniti ih osim ako postoji vrlo konkretan, svesno donet razlog da neautentifikovan pristup nekoj funkciji zaista treba da postoji
  • Periodično (kao deo redovne bezbednosne revizije, po istom principu kao i pregled AD grupa ili sudo pravila u ranijim serijama) proći kroz sve RoleBinding i ClusterRoleBinding objekte u klasteru i proveriti da li svaki od njih i dalje ima jasnu, važeću poslovnu opravdanost
  • Koristiti dostupne alate za automatizovanu proveru RBAC konfiguracije (npr. Kubescape ili kube-bench, koji upoređuju konfiguraciju klastera sa CIS Benchmark preporukama) kao dopunu ručnoj reviziji, posebno u klasterima sa velikim brojem namespace-ova i timova

Sledeći deo ove celine serije bavi se Pod Security Standards i mrežnim politikama — kako se ograničenja poznata iz Docker runtime bezbednosti (read-only fajl sistem, capabilities, non-root korisnik) primenjuju dosledno na nivou celog klastera, i kako se ograničava koji pod-ovi uopšte smeju međusobno da komuniciraju, budući da Kubernetes podrazumevano dozvoljava svakom pod-u da dopre do svakog drugog.

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)