Abeceda sigurnosti u Kubernetesu: autentifikacija, autorizacija, revizija
Prije ili kasnije, u radu bilo kojeg sistema, postavlja se pitanje sigurnosti: osiguravanje autentifikacije, razdvajanja prava, revizije i drugih zadataka. Već kreiran za Kubernetes mnoga rješenja, koji vam omogućavaju da postignete usaglašenost sa standardima čak iu vrlo zahtjevnim okruženjima... Isti materijal posvećen je osnovnim aspektima sigurnosti implementiranih u okviru ugrađenih mehanizama K8s. Prije svega, bit će korisno onima koji počinju da se upoznaju sa Kubernetesom - kao polaznom tačkom za proučavanje sigurnosnih pitanja.
Autentifikacija
Postoje dvije vrste korisnika u Kubernetesu:
Servisni računi — nalozi kojima upravlja Kubernetes API;
korisnici — „normalni“ korisnici kojima upravljaju eksterni, nezavisni servisi.
Glavna razlika između ovih tipova je u tome što za račune usluge postoje posebni objekti u Kubernetes API-ju (tako se zovu - ServiceAccounts), koji su vezani za imenski prostor i skup autorizacijskih podataka pohranjenih u klasteru u objektima tipa Secrets. Takvi korisnici (nalozi usluge) prvenstveno su namijenjeni upravljanju pravima pristupa Kubernetes API-ju procesa koji se pokreću u Kubernetes klasteru.
Obični korisnici nemaju unose u Kubernetes API: njima moraju upravljati eksterni mehanizmi. Namijenjeni su ljudima ili procesima koji žive izvan klastera.
Svaki API zahtjev povezan je ili sa servisnim računom, korisnikom ili se smatra anonimnim.
Podaci za autentifikaciju korisnika uključuju:
Korisničko — korisničko ime (razlikuje velika i mala slova!);
UID - mašinski čitljiv identifikacioni niz korisnika koji je „dosledniji i jedinstveniji od korisničkog imena“;
Grupe — lista grupa kojima korisnik pripada;
ekstra — dodatna polja koja se mogu koristiti od strane mehanizma autorizacije.
Kubernetes može koristiti veliki broj mehanizama za autentifikaciju: X509 certifikate, tokene nosioca, proxy za autentifikaciju, HTTP Basic Auth. Koristeći ove mehanizme, možete implementirati veliki broj šema autorizacije: od statične datoteke sa lozinkama do OpenID OAuth2.
Štaviše, moguće je koristiti nekoliko šema autorizacije istovremeno. Klaster podrazumevano koristi:
tokeni servisnih računa - za račune usluge;
X509 - za korisnike.
Pitanje o upravljanju servisnim računima je izvan okvira ovog članka, ali za one koji se žele detaljnije upoznati s ovim problemom, preporučujem da počnu s zvanične stranice dokumentacije. Pobliže ćemo pogledati pitanje kako X509 certifikati funkcioniraju.
obrada zahtjeva za certifikatom pomoću CA ključeva Kubernetes klastera, pribavljanje korisničkog certifikata (da biste dobili certifikat, morate koristiti račun koji ima pristup CA ključu Kubernetes klastera, koji se po defaultu nalazi u /etc/kubernetes/pki/ca.key):
Da biste olakšali prijenos konfiguracije između računa i servera, korisno je urediti vrijednosti sljedećih ključeva:
certificate-authority
client-certificate
client-key
Da biste to učinili, možete kodirati datoteke navedene u njima koristeći base64 i registrirati ih u konfiguraciji, dodajući sufiks imenu ključeva -data, tj. primivši certificate-authority-data i slično.
Certifikati sa kubeadm
Sa izdanjem Kubernetes 1.15 rad sa sertifikatima je postao mnogo lakši zahvaljujući alfa verziji njegove podrške u kubeadm uslužni program. Na primjer, ovako bi sada moglo izgledati generiranje konfiguracijske datoteke s korisničkim ključevima:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200
NB: Obavezno reklamirati adresu može se naći u konfiguraciji api-servera, koja se po defaultu nalazi u /etc/kubernetes/manifests/kube-apiserver.yaml.
Rezultirajuća konfiguracija će biti izlazna na stdout. Treba ga sačuvati ~/.kube/config korisnički račun ili u datoteku specificiranu u varijabli okruženja KUBECONFIG.
Dig Deeper
Za one koji žele da razumiju detaljnije opisane probleme:
zaseban članak o radu sa sertifikatima u zvaničnoj Kubernetes dokumentaciji;
Zadani ovlašteni račun nema prava za rad na klasteru. Da bi dao dozvole, Kubernetes implementira mehanizam autorizacije.
Prije verzije 1.6, Kubernetes je koristio tip autorizacije pod nazivom ABAC (Kontrola pristupa zasnovana na atributima). Detalje o tome možete pronaći u službena dokumentacija. Ovaj pristup se trenutno smatra naslijeđenim, ali ga i dalje možete koristiti zajedno s drugim tipovima provjere autentičnosti.
Trenutni (i fleksibilniji) način podjele prava pristupa klasteru se zove RBAC (Kontrola pristupa zasnovana na ulogama). Od verzije je proglašen stabilnim Kubernetes 1.8. RBAC implementira model prava u kojem je zabranjeno sve što nije izričito dozvoljeno. Da biste omogućili RBAC, potrebno je da pokrenete Kubernetes api-server sa parametrom --authorization-mode=RBAC. Parametri se postavljaju u manifestu sa konfiguracijom api-servera, koji se po defaultu nalazi duž putanje /etc/kubernetes/manifests/kube-apiserver.yaml, u odjeljku command. Međutim, RBAC je već uključen prema zadanim postavkama, tako da najvjerovatnije ne biste trebali brinuti o tome: to možete provjeriti pomoću vrijednosti authorization-mode (u već pomenutom kube-apiserver.yaml). Usput, među njegovim značenjima mogu biti i druge vrste ovlaštenja (node, webhook, always allow), ali ćemo njihovo razmatranje ostaviti van okvira materijala.
Inače, već smo objavili članak sa prilično detaljnim opisom principa i karakteristika rada sa RBAC-om, pa ću se dalje ograničiti na kratko navođenje osnova i primera.
Sljedeći API entiteti se koriste za kontrolu pristupa u Kubernetes putem RBAC-a:
Role и ClusterRole — uloge koje služe za opisivanje prava pristupa:
Role omogućava vam da opišete prava unutar imenskog prostora;
ClusterRole - unutar klastera, uključujući objekte specifične za klaster kao što su čvorovi, url-ovi koji nisu resursi (tj. nisu povezani s Kubernetes resursima - na primjer, /version, /logs, /api*);
RoleBinding и ClusterRoleBinding - koristi se za vezivanje Role и ClusterRole na korisnika, korisničku grupu ili servisni račun.
Entiteti Role i RoleBinding ograničeni su prostorom imena, tj. mora biti unutar istog imenskog prostora. Međutim, RoleBinding može referencirati ClusterRole, što vam omogućava da kreirate skup generičkih dozvola i kontrolišete pristup koristeći ih.
Uloge opisuju prava koristeći skupove pravila koja sadrže:
nazivi resursa (resourceNames) - za slučaj kada trebate omogućiti pristup određenom resursu, a ne svim resursima ove vrste.
Detaljniju analizu autorizacije u Kubernetesu možete pronaći na stranici službena dokumentacija. Umjesto toga (ili bolje rečeno, pored ovoga) navest ću primjere koji ilustruju njen rad.
Primjeri RBAC entiteta
Jednostavno Role, koji vam omogućava da dobijete listu i status podova i nadgledate ih u imenskom prostoru target-namespace:
Primjer: ClusterRole, što vam omogućava da dobijete listu i status podova i nadgledate ih u cijelom klasteru:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# секции "namespace" нет, так как ClusterRole задействует весь кластер
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Primjer: RoleBinding, što omogućava korisniku mynewuser "čitaj" podove u imenskom prostoru my-namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: target-namespace
subjects:
- kind: User
name: mynewuser # имя пользователя зависимо от регистра!
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # здесь должно быть “Role” или “ClusterRole”
name: pod-reader # имя Role, что находится в том же namespace,
# или имя ClusterRole, использование которой
# хотим разрешить пользователю
apiGroup: rbac.authorization.k8s.io
Revizija događaja
Šematski, Kubernetes arhitektura se može predstaviti na sljedeći način:
Ključna Kubernetes komponenta odgovorna za obradu zahtjeva je api-server. Sve operacije na klasteru prolaze kroz njega. Više o ovim internim mehanizmima možete pročitati u članku “Šta se dešava u Kubernetesu kada pokrenete kubectl run?".
Revizija sistema je zanimljiva karakteristika u Kubernetesu, koja je podrazumevano onemogućena. Omogućava vam da evidentirate sve pozive na Kubernetes API. Kao što možete pretpostaviti, sve radnje vezane za praćenje i promjenu stanja klastera izvode se preko ovog API-ja. Dobar opis njegovih mogućnosti može se (kao i obično) naći u službena dokumentacija K8s. Zatim ću pokušati da predstavim temu jednostavnijim jezikom.
Tako da se omogući revizija, moramo prenijeti tri potrebna parametra u kontejner u api-serveru, koji su detaljnije opisani u nastavku:
Pored ova tri neophodna parametra, postoje mnoge dodatne postavke vezane za reviziju: od rotacije dnevnika do opisa webhooka. Primjer parametara rotacije dnevnika:
Kao što je već spomenuto, svi parametri su postavljeni u manifestu sa konfiguracijom api-servera (podrazumevano /etc/kubernetes/manifests/kube-apiserver.yaml), u odjeljku command. Vratimo se na 3 potrebna parametra i analiziramo ih:
audit-policy-file — putanja do YAML datoteke koja opisuje politiku revizije. Kasnije ćemo se vratiti na njegov sadržaj, ali za sada ću napomenuti da fajl mora biti čitljiv od strane procesa api-servera. Stoga ga je potrebno montirati unutar kontejnera, za šta možete dodati sljedeći kod u odgovarajuće dijelove konfiguracije:
audit-log-path — putanja do datoteke evidencije. Putanja također mora biti dostupna procesu api-servera, tako da opisujemo njegovo montiranje na isti način:
audit-log-format — format dnevnika revizije. Podrazumevano je json, ali je dostupan i naslijeđeni tekstualni format (legacy).
Politika revizije
Sada o pomenutom fajlu koji opisuje politiku evidentiranja. Prvi koncept politike revizije je level, nivo evidentiranja. One su sljedeće:
None - ne logovati;
Metadata — zabilježite metapodatke zahtjeva: korisnik, vrijeme zahtjeva, ciljni resurs (pod, imenski prostor, itd.), tip radnje (glagol) itd.;
Request — metapodatke dnevnika i tijelo zahtjeva;
RequestResponse — metapodatke dnevnika, tijelo zahtjeva i tijelo odgovora.
Posljednja dva nivoa (Request и RequestResponse) ne evidentirajte zahtjeve koji nisu pristupili resursima (pristupi tzv. neresursnim URL-ovima).
Također svi zahtjevi prolaze nekoliko faza:
RequestReceived — faza kada je zahtjev primljen od strane procesora i još nije proslijeđen dalje duž lanca procesora;
ResponseStarted — šalju se zaglavlja odgovora, ali prije slanja tijela odgovora. Generirano za dugotrajne upite (na primjer, watch);
ResponseComplete — tijelo za odgovor je poslano, više informacija neće biti poslano;
Panic — događaji se generiraju kada se otkrije nenormalna situacija.
Da biste preskočili sve korake koje možete koristiti omitStages.
U datoteci politike možemo opisati nekoliko sekcija sa različitim nivoima evidentiranja. Biće primijenjeno prvo podudarno pravilo pronađeno u opisu politike.
Kubelet daemon prati promjene u manifestu s konfiguracijom api-servera i, ako ih otkrije, ponovo pokreće kontejner s api-serverom. Ali postoji jedan važan detalj: promjene u datoteci politike će biti zanemarene. Nakon unošenja izmjena u datoteku politike, morat ćete ručno ponovo pokrenuti api-server. Pošto je api-server pokrenut kao static pod, tim kubectl delete neće uzrokovati ponovno pokretanje. Morat ćete to učiniti ručno docker stop na kube-masters, gdje je promijenjena politika revizije:
Prilikom omogućavanja revizije, važno je to zapamtiti povećava se opterećenje na kube-apiserveru. Posebno se povećava potrošnja memorije za pohranjivanje konteksta zahtjeva. Zapisivanje počinje tek nakon što se pošalje zaglavlje odgovora. Opterećenje također ovisi o konfiguraciji politike revizije.
Primjeri politika
Pogledajmo strukturu datoteka politika koristeći primjere.
Evo jednostavne datoteke policyda se sve evidentira na nivou Metadata:
U politici možete odrediti listu korisnika (Users и ServiceAccounts) i grupe korisnika. Na primjer, ovako ćemo zanemariti korisnike sistema, ali ćemo sve ostalo evidentirati na nivou Request:
Moguće je brzo odgovoriti na događaje revizije opišite webhook. Ovo pitanje je pokriveno u službena dokumentacija, ostavit ću to izvan okvira ovog članka.
Ishodi
Članak daje pregled osnovnih sigurnosnih mehanizama u Kubernetes klasterima, koji vam omogućavaju da kreirate personalizovane korisničke naloge, odvojite njihova prava i zabeležite njihove radnje. Nadam se da će biti od koristi onima koji se susreću sa ovakvim problemima u teoriji ili praksi. Takođe preporučujem da pročitate spisak drugih materijala na temu sigurnosti u Kubernetesu, koji je dat u “PS” – možda među njima pronađete potrebne detalje o problemima koji su vam relevantni.