Uvod u Kubernetes mrežne politike za profesionalce za sigurnost
Bilješka. transl.: Autor članka - Reuven Harrison - ima preko 20 godina iskustva u razvoju softvera, a danas je CTO i suosnivač Tufina, kompanije za upravljanje sigurnosnim politikama. Iako smatra da su Kubernetes mrežne politike dovoljno moćne da segmentiraju mrežu u klaster, on također vjeruje da ih nije tako lako implementirati u praksi. Ovaj materijal (prilično obiman) namijenjen je poboljšanju svijesti stručnjaka o ovom pitanju i pomoći im u stvaranju potrebnih konfiguracija.
Danas mnoge kompanije sve više biraju Kubernetes za pokretanje svojih aplikacija. Interesovanje za ovaj softver je toliko veliko da neki Kubernetes nazivaju "novim operativnim sistemom za centre podataka". Postepeno, Kubernetes (ili k8s) počinje da se doživljava kao kritični deo poslovanja koji zahteva organizaciju zrelih poslovnih procesa, uključujući mrežnu bezbednost.
Za profesionalce u oblasti bezbednosti koji su bili zbunjeni radom sa Kubernetesom, podrazumevana politika ove platforme može biti pravo otkriće: dozvolite sve.
Ovaj vodič će vam pomoći da shvatite unutrašnje djelovanje mrežnih politika; razumjeti po čemu se razlikuju od pravila za obične firewall. Također će se govoriti o nekim zamkama i dati preporuke koje će pomoći u zaštiti aplikacija u Kubernetesu.
Kubernetes mrežne politike
Mehanizam Kubernetes mrežnih politika vam omogućava da upravljate interakcijom aplikacija raspoređenih na platformi na mrežnom sloju (treći u OSI modelu). Mrežnim politikama nedostaju neke od naprednih karakteristika modernih zaštitnih zidova, kao što su kontrola OSI sloja 7 i otkrivanje prijetnji, ali one pružaju osnovni sloj mrežne sigurnosti koji je dobra polazna tačka.
Mrežne politike kontroliraju komunikaciju između podova
Radna opterećenja u Kubernetesu su raspoređena na podove, koji se sastoje od jednog ili više kontejnera koji su raspoređeni zajedno. Kubernetes svakom modulu dodeljuje IP adresu dostupnoj iz drugih podova. Kubernetes mrežne politike postavljaju dozvole pristupa za grupe podova na isti način na koji se sigurnosne grupe u oblaku koriste za kontrolu pristupa instancama virtuelne mašine.
Definiranje mrežnih politika
Kao i drugi Kubernetes resursi, mrežne politike su postavljene u YAML-u. U primjeru ispod, aplikacija balance otvara pristup postgres:
(Bilješka. transl.: ovaj snimak ekrana, kao i svi kasniji slični snimci ekrana, nije napravljen korišćenjem izvornih Kubernetes alata, već pomoću alata Tufin Orca, koji je razvila kompanija autora originalnog članka i koji se spominje na kraju materijala.)
Za definiranje vlastite mrežne politike potrebno je osnovno poznavanje YAML-a. Ovaj jezik se zasniva na uvlačenju (navedenom razmacima, a ne tabulatorima). Uvučeni element pripada najbližem uvučenom elementu iznad njega. Novi element liste počinje crticom, svi ostali elementi su u obliku ključ/vrijednost.
Nakon što opišete politiku u YAML-u, koristite kubectlda ga kreirate u klasteru:
kubectl create -f policy.yaml
Specifikacija mrežne politike
Specifikacija Kubernetes mrežne politike uključuje četiri elementa:
podSelector: definira podove na koje utiče ova politika (ciljevi) - obavezno;
policyTypes: označava koje vrste politika su uključene u ovu: ulazna i/ili izlazna - opciono, ali preporučujem da se eksplicitno specificira u svim slučajevima;
ingress: definira dozvoljeno dolazni promet do ciljnih podova - opciono;
egress: definira dozvoljeno odlazni promet iz ciljnih podova je opcioni.
Primjer posuđen sa Kubernetes stranice (zamijenio sam role na app), pokazuje kako se koriste sva četiri elementa:
Imajte na umu da nije neophodno uključiti sva četiri elementa. To je samo potrebno podSelector, ostali parametri se mogu koristiti po želji.
Ako izostavimo policyTypes, politika će se tumačiti na sljedeći način:
Podrazumevano je da se definiše ulazna strana. Ako politika to izričito ne naznači, sistem će pretpostaviti da je sav promet zabranjen.
Ponašanje na izlaznoj strani će biti određeno prisustvom ili odsustvom odgovarajućeg izlaznog parametra.
Da biste izbjegli greške, preporučujem uvijek budi eksplicitan policyTypes.
Prema gornjoj logici, u slučaju parametara ingress i / ili egress izostavljeno, politika će uskratiti sav promet (pogledajte "Pravilo čišćenja" ispod).
Zadana politika - dozvoli
Ako nema definisanih pravila, Kubernetes podrazumevano dozvoljava sav saobraćaj. Sve mahune mogu slobodno međusobno razmjenjivati informacije. Sa sigurnosne tačke gledišta, ovo može izgledati kontraintuitivno, ali zapamtite da su Kubernetes prvobitno kreirali programeri sa ciljem da aplikacije učine interoperabilnim. Mrežna pravila su dodana kasnije.
Imenski prostori
Prostori imena su mehanizam Kubernetes saradnje. Oni su dizajnirani da izoluju logička okruženja jedno od drugog, dok podrazumevano dozvoljavaju komunikaciju između prostora.
Kao i većina Kubernetes komponenti, mrežne politike žive u određenom imenskom prostoru. U bloku metadata možete odrediti kojem prostoru politika pripada:
Ako imenski prostor nije eksplicitno naveden u metapodacima, sistem će koristiti prostor imena naveden u kubectl (podrazumevano namespace=default):
kubectl apply -n my-namespace -f namespace.yaml
predlažem eksplicitno specificirajte imenski prostor, osim ako ne pišete politiku koja cilja više imenskih prostora odjednom.
Glavni element podSelector u politici će odabrati podove iz imenskog prostora kojem politika pripada (nema pristup podovima iz drugog imenskog prostora).
Slično, podSelectors u ulaznim i izlaznim blokovima mogu odabrati samo podove iz vlastitog imenskog prostora, osim ako ih, naravno, ne kombinirate s njima namespaceSelector (O tome će se raspravljati u odjeljku "Filtriraj po imenskim prostorima i podovima").
Pravila imenovanja politike
Nazivi politika su jedinstveni unutar istog imenskog prostora. Ne mogu postojati dvije politike s istim imenom u istom prostoru, ali mogu postojati politike s istim imenom u različitim prostorima. Ovo je korisno kada želite ponovo primijeniti istu politiku na više prostora.
Posebno mi se sviđa jedna od metoda imenovanja. Sastoji se od spajanja imena prostora imena sa ciljnim podovima. Na primjer:
Prilagođene oznake se mogu priložiti Kubernetes objektima kao što su podovi i prostori imena. Oznake (etikete oznake) su ekvivalent oznakama u oblaku. Kubernetes mrežna pravila koriste oznake za odabir podsna koje se odnose:
podSelector:
matchLabels:
role: db
… ili imenski prostorina koje se odnose. Ovaj primjer odabire sve podove u imenskim prostorima s odgovarajućim oznakama:
Jedno upozorenje: prilikom upotrebe namespaceSelectorprovjerite da li prostori imena koje odaberete sadrže ispravnu oznaku. Imajte na umu da ugrađeni prostori imena kao što su default и kube-system, ne sadrže oznake prema zadanim postavkama.
Prostoru možete dodati oznaku ovako:
kubectl label namespace default namespace=default
U ovom slučaju, imenski prostor u sekciji metadata treba da se odnosi na stvarni naziv prostora, a ne na oznaku:
Politike zaštitnog zida se sastoje od izvornih i odredišnih pravila. Kubernetes mrežne politike se definiraju prema cilju, skupu podova na koje se primjenjuju, a zatim postavljaju pravila za ulazni i/ili izlazni promet. U našem primjeru, cilj politike će biti svi podovi u imenskom prostoru default sa oznakom ključa app i značenje db:
Pododsjek ingress u ovoj politici otvara dolazni promet ciljnim podovima. Drugim riječima, ulaz je izvor, a cilj je odgovarajuće odredište. Slično, izlaz je odredište, a cilj je njegov izvor.
Ovo je ekvivalentno dvama pravilima zaštitnog zida: Ulaz → Cilj; Cilj → Izlaz.
Izlaz i DNS (važno!)
Ograničavanje odlaznog saobraćaja obratite posebnu pažnju na DNS - Kubernetes koristi ovu uslugu za mapiranje usluga na IP adrese. Na primjer, sljedeća politika neće raditi jer niste dozvolili aplikaciju balance pristup DNS-u:
Poslednji element to je prazan, pa tako indirektno bira svi podovi u svim imenskim prostorima, dozvoljavajući balance šaljite DNS upite odgovarajućoj Kubernetes usluzi (obično radi u prostoru kube-system).
Međutim, ovaj pristup funkcionira preterano popustljiv i nesiguran, jer vam omogućava usmjeravanje DNS upita izvan klastera.
Možete ga poboljšati u tri uzastopna koraka.
1. Dozvolite samo DNS upite unutar klaster dodavanjem namespaceSelector:
2. Dozvolite DNS upite samo u imenskom prostoru kube-system.
Da biste to učinili, trebate dodati oznaku imenskom prostoru kube-system: kubectl label namespace kube-system namespace=kube-system - i registrirati ga u polisu koristeći namespaceSelector:
3. Paranoici mogu ići još dalje i ograničiti DNS zahtjeve na određenu DNS uslugu kube-system. Odjeljak "Filtriraj po imenskim prostorima I podovima" će vam pokazati kako to postići.
Druga opcija je da riješite DNS na nivou imenskog prostora. U ovom slučaju, neće ga trebati otvarati za svaku uslugu:
Prazan podSelector bira sve podove u imenskom prostoru.
Prva utakmica i redoslijed pravila
U konvencionalnim zaštitnim zidovima, akcija (Dozvoli ili Odbij) na paketu je određena prvim pravilom koje zadovoljava. U Kubernetesu redosled politika nije bitan.
Prema zadanim postavkama, kada nije postavljena politika, komunikacija između podova je dozvoljena i oni mogu slobodno razmjenjivati informacije. Čim počnete da formulišete politike, svaka grupa na koju utiče barem jedna od njih postaje izolovana u skladu sa disjunkcijom (logičko ILI) svih politika koje su ga odabrale. Podovi na koje ne utiče nijedna politika ostaju otvoreni.
Ovo ponašanje možete promijeniti pomoću pravila čišćenja.
Pravilo čišćenja ("Zabraniti")
Pravila zaštitnog zida obično odbijaju svaki promet koji nije izričito dozvoljen.
Kubernetes nema akciju "odbijanje"., međutim, isti efekat se može postići normalnom (permisivnom) politikom odabirom prazne grupe izvornih podova (ingress):
Imajte na umu to sve dodatne politike koje dozvoljavaju promet prema podovima u imenskom prostoru imat će prednost nad ovim pravilom (slično dodavanju pravila dozvole prije pravila zabrane u konfiguraciji zaštitnog zida).
Dozvoli sve (Bilo koji-bilo-bilo-dopusti)
Da biste kreirali politiku "Dozvoli sve", morate dopuniti gornju politiku zabrane sa praznim elementom ingress:
Omogućuje pristup sve podove u svim imenskim prostorima (i sve IP adrese) na bilo koji pod u imenskom prostoru default. Ovo ponašanje je podrazumevano omogućeno, tako da ga obično nije potrebno dalje definisati. Međutim, ponekad može biti potrebno privremeno onemogućiti određene posebne dozvole kako bi se dijagnosticirao problem.
Pravilo se može suziti da dozvoli pristup samo određeni set mahuna (app:balance) u imenskom prostoru default:
2. Unutar odjeljka politike ingress može imati mnogo elemenata from (kombinovano logičkim ILI). Slično, odjeljak egress može uključivati mnoge elemente to (takođe kombinovano disjunkcijom):
3. Različite politike se takođe kombinuju sa logičnim ILI
Ali kada se kombinuju, postoji jedno ograničenje istaknuoChris Cooney: Kubernetes može kombinovati samo politike sa različitim policyTypes (Ingress ili Egress). Politike koje definiraju ulaz (ili izlaz) će prepisati jedna drugu.
Odnos između imenskih prostora
Podrazumevano je dozvoljena razmena informacija između imenskih prostora. Ovo se može promijeniti pomoću restriktivne politike koja ograničava odlazni i/ili dolazni promet u imenskom prostoru (pogledajte "Pravilo čišćenja" iznad).
Blokiranjem pristupa imenskom prostoru (pogledajte "Pravilo čišćenja" iznad), možete napraviti izuzetke od politike zabrane dozvoljavanjem konekcija iz određenog imenskog prostora sa namespaceSelector:
Kao rezultat, svi podovi u imenskom prostoru default dobiti pristup podovima postgres u imenskom prostoru database. Ali šta ako želite da otvorite pristup postgres samo određene podove u imenskom prostoru default?
Filtrirajte po imenskim prostorima I podovima
Kubernetes verzija 1.11 i novije vam omogućava da kombinujete operatore namespaceSelector и podSelector koristeći logički I. To izgleda ovako:
Zapiši to podSelector ne počinje crticom. U YAML-u to znači to podSelector i stoji ispred njega namespaceSelector odnose se na isti element liste. Stoga su kombinovani sa logičnim I.
Dodavanje crtice prije podSelector će rezultirati novim elementom liste koji će biti kombinovan sa prethodnim namespaceSelector koristeći logičko ILI.
Za odabir mahuna sa određenom oznakom u svim imenskim prostorima, unesite prazno namespaceSelector:
Pravila zaštitnog zida sa više entiteta (hostovi, mreže, grupe) se kombinuju pomoću logičkog OR. Sljedeće pravilo će se aktivirati ako se izvor paketa podudara Host_1 Or Host_2:
Naprotiv, u Kubernetesu različite oznake u podSelector ili namespaceSelector kombiniraju se s logičkim I. Na primjer, sljedeće pravilo će odabrati podove koji imaju obje oznake, role=db И version=v2:
podSelector:
matchLabels:
role: db
version: v2
Ista logika se primjenjuje na sve tipove izraza: birače cilja politike, selektore pod i birače prostora imena.
Podmreže i IP adrese (IPBlockovi)
Zaštitni zidovi koriste VLAN-ove, IP adrese i podmreže za segmentiranje mreže.
U Kubernetesu, IP adrese se automatski dodjeljuju podovima i mogu se često mijenjati, tako da se oznake koriste za odabir podova i imenskih prostora u mrežnim politikama.
Podmreže (ipBlocks) se koriste prilikom upravljanja dolaznim (ulaznim) ili odlaznim (izlaznim) vanjskim (sjever-jug) vezama. Na primjer, ova politika otvara sve podove iz imenskog prostora default pristup Google DNS servisu:
Prazan selektor pod u ovom primjeru znači "odaberi sve podove u imenskom prostoru".
Ova politika dozvoljava pristup samo 8.8.8.8; pristup bilo kojoj drugoj IP adresi je zabranjen. Dakle, u suštini, blokirali ste pristup internom Kubernetes DNS servisu. Ako ga i dalje želite otvoriti, navedite ga izričito.
obično ipBlocks и podSelectors se međusobno isključuju, budući da se interne IP adrese podova ne koriste u ipBlocks. Pokazujući interne IP pod, zapravo ćete dozvoliti konekcije na/iz podova sa tim adresama. U praksi, nećete znati koju IP adresu da koristite, zbog čega ne biste trebali da je koristite za odabir podova.
Kao kontra primjer, sljedeća politika uključuje sve IP adrese i stoga dozvoljava pristup svim ostalim podovima:
Podovi obično slušaju na jednom portu. To znači da možete jednostavno izostaviti brojeve portova u svojim politikama i ostaviti sve kao zadano. Međutim, preporučuje se da politike budu što restriktivnije, tako da u nekim slučajevima i dalje možete specificirati portove:
Imajte na umu da selektor ports odnosi se na sve elemente u bloku to ili from, koji sadrži. Da biste specificirali različite portove za različite skupove stavki, break ingress ili egress u nekoliko podsekcija to ili from i u svaki upišite svoje portove:
Ako u potpunosti izostavite definiciju portova (ports), što znači sve protokole i sve portove;
Ako izostavite definiciju protokola (protocol), što znači TCP;
Ako izostavite definiciju porta (port), što znači sve portove.
Najbolja praksa: Nemojte se oslanjati na zadane vrijednosti, izričito navedite šta vam je potrebno.
Imajte na umu da trebate koristiti pod portove, a ne usluge (više o tome u sljedećem paragrafu).
Definirane politike za podove ili usluge?
Obično, podovi u Kubernetesu međusobno komuniciraju putem usluge - virtuelnog balansera opterećenja koji preusmerava saobraćaj na podove koji implementiraju uslugu. Možda mislite da mrežne politike kontroliraju pristup uslugama, ali to nije slučaj. Kubernetes mrežne politike rade sa pod portovima, a ne uslugama.
Na primjer, ako usluga sluša port 80, ali preusmjerava promet na port 8080 svojih podova, morate navesti 8080 u mrežnoj politici.
Takav mehanizam treba prepoznati kao neoptimalan: ako se promijeni interni uređaj usluge (čiji portovi slušaju podove), mrežne politike će se morati ažurirati.
Novi arhitektonski pristup koristeći Service Mesh (na primjer, pogledajte o Istiu ispod - pribl. prevod) omogućava vam da se nosite sa ovim problemom.
Da li je potrebno pisati i Ingress i Egress?
Kratak odgovor je da, da bi pod A mogao komunicirati sa podom B, morate mu omogućiti da kreira odlaznu vezu (za to morate konfigurirati izlaznu politiku), a pod B mora biti u stanju prihvatiti dolaznu vezu (za ovo vam je, shodno tome, potrebna ingress-polisa).
Međutim, u praksi se možete osloniti na zadanu politiku da biste omogućili veze u jednom ili oba smjera.
Ako neki pod-izvor će biti odabran od strane jednog ili više njih izlazak-političari, ograničenja koja su joj nametnuta biće određena njihovom disjunkcijom. U ovom slučaju, morat ćete eksplicitno dopustiti vezu s podomprimalac. Ako pod nije odabran nijednom politikom, njegov odlazni (izlazni) promet je po defaultu dozvoljen.
Slično, sudbina pod'a-adresatodabrao jedan ili više njih ulazak-politike će biti određene njihovom disjunkcijom. U ovom slučaju, morate mu izričito dopustiti da prima promet iz izvornog modula. Ako pod nije odabrana nijedna politika, sav ulazni promet do njega je po defaultu dozvoljen.
Pogledajte "S državljanstvom ili bez državljanstva" u nastavku.
Dnevnici
Kubernetes mrežne politike ne znaju kako evidentirati promet. Ovo otežava utvrđivanje da li politika radi kako se očekuje i čini analizu sigurnosti veoma teškom.
Kontrola saobraćaja prema eksternim servisima
Kubernetes mrežna pravila vam ne dozvoljavaju da navedete potpuno kvalificirano ime domene (DNS) u izlaznim odjeljcima. Ova činjenica dovodi do značajne neugodnosti kada pokušavate ograničiti promet na eksterna odredišta koja nemaju fiksnu IP adresu (kao što je aws.com).
Provjera politike
Zaštitni zidovi će vas upozoriti ili čak odbiti da prihvatite pogrešnu politiku. Kubernetes radi i neke provjere. Prilikom postavljanja mrežne politike putem kubectl-a, Kubernetes može izjaviti da je politika netačna i odbiti je prihvatiti. U drugim slučajevima, Kubernetes će preuzeti politiku i popuniti je detaljima koji nedostaju. Možete ih vidjeti naredbom:
kubernetes get networkpolicy <policy-name> -o yaml
Imajte na umu da Kubernetes sistem validacije nije nepogrešiv i da može propustiti neke vrste grešaka.
Izvršenje
Kubernetes ne sprovodi mrežne politike sam po sebi, već je samo API gateway koji stavlja teret kontrole na osnovni sistem koji se zove Container Networking Interface (CNI). Postavljanje politika na Kubernetes klasteru bez dodjeljivanja odgovarajućeg CNI je isto kao i postavljanje politika na server za upravljanje firewall bez naknadnog postavljanja na firewall. Na vama je da budete sigurni da imate pristojan CNI ili, u slučaju Kubernetes platforme, hostovan u oblaku (Za listu provajdera pogledajte ovdje - cca. trans.), omogućite mrežne politike koje će postaviti CNI za vas.
Imajte na umu da vas Kubernetes neće upozoriti ako postavite mrežnu politiku bez odgovarajućeg pomoćnog CNI-a.
Sa državljanstvom ili bez državljanstva?
Svi Kubernetes CNI-ovi na koje sam naišao su sa stanjem (na primjer, Calico koristi Linux conntrack). Ovo omogućava modulu da primi odgovore na TCP vezu koju je pokrenuo bez potrebe da je ponovo uspostavi. Međutim, nisam svjestan Kubernetes standarda koji bi garantirao zadržavanje stanja.
Napredno upravljanje sigurnosnom politikom
Evo nekoliko načina da poboljšate efikasnost sprovođenja bezbednosnih politika u Kubernetesu:
Arhitektonski obrazac Service Mesh koristi bočne prikolice za pružanje detaljne telemetrije i kontrole prometa na sloju usluge. Kao primjer, može se uzeti Istio.
Neki od dobavljača CNI-a proširili su svoje alate da prevaziđu Kubernetes mrežne politike.
Tufin Orca pruža transparentnost i automatizaciju Kubernetes mrežnih politika.
Tufin Orca paket upravlja Kubernetes mrežnim politikama (i izvor je snimaka ekrana iznad).
Kubernetes mrežne politike nude dobar skup alata za segmentiranje klastera, ali nisu intuitivne i imaju mnogo suptilnosti. Vjerujem da su zbog ove složenosti politike mnogih postojećih klastera pogrešne. Moguća rješenja za ovaj problem su automatizacija definicija politika ili korištenje drugih alata za segmentaciju.
Nadam se da će vam ovaj vodič pomoći da razjasnite neka pitanja i riješite probleme na koje možete naići.