Sadržaj

Forenzika mikroservisa temeljenih na spremnicima

Sažetak

U poslovnom svijetu razvoja aplikacija vrlo su česte izmjene trendova. Veliki zamah trenutno ima prelazak s tradicionalnih monolitnih aplikacija na modularne, slabo povezane, samostalne mikroservise. Njima na ruku ide istovremeni napredak u tehnologiji virtualizacije okoline pomoću spremnika. Očita prednost u takvoj arhitekturi je razvijanje svake usluge aplikacije neovisno jedne o drugoj, s mogućnošću razvijanja u različitim programskim jezicima i slično. Iako korištenje mikroservisa ima brojne prednosti kod razvoja i održavanja aplikacija, jedan nedostatak je povećana kompleksnost aplikacija. Za jednu uslugu redovito se pokreće više spremnika, čak i nekoliko stotina. Za upravljanje tolikim resursima potrebni su razni programski alati koji pomažu pri upravljanju, nadzoru i eventualnom oporavku nakon ispada. Spremnici su vrlo kratkog životnog vijeka i ponovnim pokretanjem spremnika pokreću se novi procesi i ponovno zauzima memorija za njihovo izvršavanje što otežava digitalnu forenziku spremnika nakon eventualnog napada. Zato se pronalaze novi načini spremanja stanja spremnika i razvijaju pomoćni alati i za tu svrhu.

Keywords: Mikroservisi, spremnici, sigurnost mikroservisa, forenzika spremnika, Kubernetes, orkestracija, cloud, raspodijeljeni sustav

Uvod

Mikroservisi (mikrousluge, microsevices) i spremnici (containers) su samo neki od brojnih novonastalih pojmova u računalnom rječniku koji svakodnevno doprinose nevjerojatno brzom i opsežnom rastu uporabe svih, ali posebno online računalnih usluga. Posebno se odnose na izgradnju i održavanje velikih aplikacija, što je aplikacija veća i prima veći promet, prednosti korištenja mikroservisa, posebno sa spremnicima, su veće.

Arhitektura aplikacije temeljena na mikroservisima pruža brojne pogodnosti kao što su jednostavnost izgradnje, optimizacije i održavanja, neovisnost usluga i povezanost preko APIa, otpornost i skalabilnost. Spremnici, koji se pokreću kao izdvojeni procesi na računalu s upakiranim svim potrebnim alatima i neovisni su o platformi na kojoj se pokreću, idealna su podloga razvoju aplikacije pomoću mikroservisa. Izoliranost i neovisnost spremnika od ostatka sustava i s druge strane izoliranost jedne usluge u obliku mikroservisa od ostatka aplikacije podiže razinu sigurnosti cijelog sustava i olakšava analizu nakon ispada (forenziku).

Spremnici

Spremnici pružaju logičan mehanizam pakiranja u kojem se aplikacije mogu apstrahirati iz okoline u kojoj stvarno rade. Ovakva razdvojenost omogućuje laku i dosljednu primjenu aplikacija temeljenih na spremnicima, bez obzira je li ciljno okruženje privatni podatkovni centar, javni oblak (cloud) ili čak osobni laptop programera. Kontejnerizacija pruža čisto razdvajanje odgovornosti i briga, jer se programeri usredotočuju na logiku i ovisnosti aplikacija, dok se IT operativni timovi mogu usredotočiti na implementaciju i upravljanje bez zamaranja detaljima aplikacije, poput specifičnih verzija softvera i ostalih konfiguracija.

Spremnici su često uspoređivani s virtualnim strojevima, s kojima dijele svojstvo pakiranja i virtualizacije okoline. Međutim to rade na različitim razinama arhitekture. Umjesto da virtualiziraju čitav hardverski dio sustava kao kod pristupa virtualnih strojeva, spremnici se virtualiziraju na razini operativnog sustava, s više spremnika koji se izravno izvode nad jezgrom OS-a domaćina. To znači da su spremnici daleko “lakši”: dijele jezgru OS-a, pokreću se mnogo brže i koriste djelić memorije u usporedbi s dizanjem cijelog OS-a što rade virtualizacijski strojevi. Navedene razlike u arhitekturi, prikazane su na slici ispod.

Mikroservisi

Mikroservisi dijele aplikaciju u puno manjih neovisnih, slabo povezanih, pojedinačno raspoloživih usluga. Ovakva arhitektura omogućuje da se svaka usluga koristi, skalira i ažurira samostalno, bez ometanja ostalih usluga u aplikaciji i omogućuje brzu i jednostavnu izgradnju velikih aplikacija. Mikroservisi dobivaju svoje ime jer svaka važna funkcija aplikacije djeluje kao neovisna usluga. Okvir mikroservisa stvara masivno skalabilan i distribuiran sustav koji izbjegava uska grla (bottlenecks) središnje baze podataka i diže poslovne sposobnosti na nove razine, poput omogućavanja kontinuirane integracije/isporuke aplikacija i modernizacije ostalih tehnoloških procesa.

Arhitektura mikroservisa stvorena je za rješavanje problema uzrokovanih monolitnim aplikacijama. Mikroservisi su već u širokoj primjeni, a neke aplikacije velikih razmjera već su transformirale svoje monolitne aplikacije u mikroservise. Nakon shvaćanja koncepta mikroservisa, nameće se pitanje, kako pokretati mikroservise. Odgovor je, naravno, pomoću spremnika, jer upravo je razvijanje spremnika kao tehnologije imalo ogroman utjecaj na ostvarenje mogućnosti i prednosti mikroservisa. Navedene su neke od prednosti razvijanja aplikacije pomoću mikroservisa:

Sigurnost mikroservisa

Iako upotreba mikroservisa rješava veliki dio problema monolitne arhitekture, njihova upotreba donosi vlastiti niz problema. Ispostavlja se da nije tako jednostavno složiti funkcionalnu aplikaciju pomoću mikroservisa kao postavljanje jedne instance aplikacije. Jedan bitan nedostatak aplikacije u obliku mikroservisa je povećanje kompleksnosti arhitekture aplikacije. Mikroservisima treba veća koordinacija. Također, očekuje se više mrežnih poziva pri komunikaciji među uslugama, što nije prisutno u monolitnim aplikacijama. Ostali problemi koje treba razmotriti su: kako upravljati komunikacijom između mikroservisa, riješiti greške kako bi se izbjeglo ometanje rada drugih mikroservisa i dodati više testnih slučajeva u svaku komponentu.

Jedno od područja gdje se očituje kompleksnost ovakve arhitekture jest sigurnost. Izgradnja bilo kojeg sigurnog sustava je izazovno. Klasični sigurnosni ciljevi su povjerljivost i cjelovitost podataka, autentifikacija entiteta i poruka, autorizacija i dostupnost sustava. Naravno, ovi apstraktni ciljevi mogu se ostvariti na mnogo različitih načina u praksi. Kako se ti ciljevi ostvaruju i do kojeg su stupnja odluke koje ovise o određenom modelu prijetnje, proračunu i stručnosti ovisne o infrastrukturi. Sigurnost mikroservisa višeslojni je problem i uvelike se oslanja na temeljne tehnologije i okruženje. Da bi se to riješilo, baš kao i samu aritekturu aplikacije, sigurnost mikroservisa treba razgraditi na manje komponente. Radi lakše ilustracije složenosti problema sigurnosti bilo kojeg raspodijeljenog sustava (ovdje naglasak na mikroservisima), podijeljen je u šest kategorija ili slojeva uz primjere prijetnji vezane uz određeni sloj [4]:

Upravljanje i kontrola mikroservisa

Ustanovljeno je da u okruženju mikroservisa, spremnici se konstantno gase i pokreću, što znači da imaju kratak rok trajanja i cijela struktura je vrlo dinamična. Spremnici zahtijevaju skup pomoćnih usluga, poput API poslužitelja, kao i sigurnosne mjere. Premještanje svih tih spremnika na poslužitelj i van njega, provjeravanje jesu li pravilno povezani, njihovo praćenje kako bi se nadogradnje aplikacija mogle neometano izvoditi - sve to je komplicirano. To dovodi do zaključka da je potreban alat, odnosno skup alata za upravljanje i kontrolu životnog ciklusa spremnika. U prethodnom poglavlju spomenuta je kategorija sigurnosti orkestracija. Kod spremnika, orkestracija pokriva puno više od same sigurnosti. Iako postoje brojni drugi, najrasprostranjeniji skup alata, koji je također open-source, za orkestraciju spremnika pod zajedničkim nazivom je Kubernetes. Objekti u koje Kubernetes sprema spremnike zovu se podovi. Pod je najmanji, osnovni isporučivi objekt u Kubernetesu. Pod predstavlja jedan primjerak pokrenutog procesa u radnom klasteru. Podovi sadrže jedan ili više spremnika, npr. Docker spremnika. Kada Pod pokreće više spremnika, spremnicima se upravlja kao jedinstvenim entitetom i dijele se resursi Poda, poput mrežnih i skladišnih resursa. Na primjer jedan pod nakon pokretanja poprima jednu IP adresu. Prilikom pokretanja podova, Kubernetes obično pokrene više istih, redundantnih podova radi mogućnosti ispada i slično. Kubernetes pokreće radne procese postavljanjem spremnika u podove za izvođenje na čvorovima (Nodes). Čvor može biti virtualni ili fizički stroj, ovisno o okruženju. Svaki čvor sadrži usluge potrebne za pokretanje podova, kojima upravlja kontrolni sloj koji izlaže API i sučelja za definiranje, postavljanje i upravljanje životnim ciklusom spremnika. U nastavku je dana ilustracija strukture.

Već iz prvih par osnovnih definicija radne strukture Kuberentesa, vidljivo je koliko je ta struktura slojevita i komplicirana, pogotovo u poslovnim okruženjima gdje gdje postoje klasteri s puno čvorova koji nose puno podova. Iz tog razloga potreban je dodatan alat koji će prikupljati metričke i analitičke podatke sa svih objekata strukture u svrhu praćenja performansi, ali i kontrole sigurnosti. Za tu namjenu koristi se vrlo moćan, open-source alat koji se lako integrira s Kubernetesom, zvan Prometheus. Prometheus je sustav koji šalje HTTP zahtjeve, takozvano struganje (scrape), na temelju konfiguracije definirane u datoteci za postavljanje. Odgovor na ovaj zahtjev za struganjem pohranjuje se i parsira u memoriji zajedno s metričkim podacima za samo struganje. Podaci se pohranjuju u prilagođenu bazu podataka na Prometheus poslužitelju koji može obrađivati masovni priljev podataka. Moguće je istovremeno pratiti tisuće strojeva s jednim poslužiteljem. Kubernetes klaster već ima oznake i anotacije te izvrstan mehanizam za praćenje promjena i statusa svojih elemenata. Stoga Prometheus koristi Kubernetes API za otkrivanje ciljeva za struganje.

Nakon što sustav prikupi podatke, moguće im je pristupiti pomoću jezika za upite PromQL, izvesti ih na grafička sučelja poput Grafane ili upotrijebiti za slanje upozorenja s Alertmanager-om. Grafana je alat za vizualizaciju podataka prikupljenih Prometheusom. Ona pruža grafičko sučelje sa ugrađenih mnoštvom grafova koji se mogu oblikovati prema želji, pruža konzolu za PromQL upite, i mnoštvo ostalih stvari. Neophodan je alat u analizi i praćenju stanja svih Kubernetes objekata. Primjer sučelja na kojem su prikazani razni grafovi performansi prikupljeni s Prometheus servera je dan na slici u nastavku [6].

Forenzika spremnika

Spremnici čine digitalnu forenziku nevjerojatno složenom jer su raspoređeni i upravljani na različitim domaćinima ovisno o potrebi. Za razliku od okruženja virtualnih strojeva, spremnici koji se izvode na domaćinu dijele osnovnu jezgru operacijskog sustava, što znači da nema nikakve hardverske izolacije. Ali postoje neka nova ograničenja, poput izolacije mrežnog pokrivanja, čak i unutar istog domaćina. Dobra vijest je da je IT industrija već ranije vidjela ovakvu vrstu složenosti. Kada su prvi put predstavljeni virtualni strojevi, uobičajena je praksa bila kopirati sadržaj memorije i diska izravno s fizičkog poslužitelja. Višestruki virtualni strojevi možda su premješteni na ili s računala domaćina koji je prvi put napadnut ili se kopija možda izvodi na nekom računalu bez OS-a (bare metal). Unatoč činjenici da se virtualni strojevi mogu migrirati između različitih podatkovnih centara, smatraju se dovoljno samostalnima da omoguće evidencijsko očuvanje [7]. Slično prijelazu s fizičkih poslužitelja na virtualne strojeve, postoje različite nijanse složenosti, s pripadajućim prednostima i nedostacima kod spremnika. Trenutno nije dostupna neka opće prihvaćena funkcija snimke spremnika; snimke moraju biti ujedinjene kao skup različitih komponenata.

Vodeći formati spremnika koriste datotečni sustav oblika copy-on-write. To je velika prednost forenzičke nabave. Sve zadane datoteke sustava i aplikacija postoje unutar slike spremnika. Sve promjene od pokretanja spremnika pohranjuju se u zaseban direktorij od izvorne slike. Nadalje, bilježi se i svako brisanje izvornih datoteka sa slike. U primjeru Dockera, razlike između slojeva slike može se vidjeti unutar pokrenutog spremnika na putanji “/var/lib/docker”. Trenutni spremnik, bilo da je pokrenut ili zaustavljen, u Dockeru se može pohraniti u novu sliku, ne izmjenjujući spremnik ni u kakvom smislu. Kao i u fizičkim strojevima, pohranjivanje spremnika u novu sliku sprema samo trenutno stanje datotečnog sustava, a ne stanje trenutnih procesa. Ako se spremnik nastavi iz nove slike, on će pokrenuti nove procese i nije zajamčeno da će izvršiti bilo kakvo sumnjivo ponašanje.

Za trenutno stanje radne memorije, spremnici također imaju rješenje. Procesi koji se izvode u spremniku upravljaju memorijom jednako kao i bilo koji drugi proces. Prema zadanim postavkama, procesi unutar spremnika ne smiju komunicirati niti ometati memoriju kojom upravlja bilo koji proces izvan spremnika. To znači da ako se za svaki proces u spremniku snimi sva memorija, snimljena je sva dodijeljena memorija za taj spremnik.

Bitno je napomenuti da spremnici imaju mogućnost mapiranja direktorija s datotečnog sustava domaćina na onaj u spremniku. Tu nastaju potencijalni sigurnosni problemi jer napadač ima ulaz u datotečni sustav domaćina. Takve se opasnosti uklanjaju ograničenjem pristupa tom direktoriju ili kako to zna biti slučaj kod arhitekture mikroservisa, zabrana mapiranja direktorija u potpunosti. Zlonamjeran softver možda nije svjestan kratkog životnog vijeka spremnika i upisuje neke zanimljive podatke na dodijeljeni prostor spremnika na disku. Međutim, najosjetljiviji podaci vjerojatno se pohranjuju putem volumea, koji služe za pohranu trajnih podataka (persistent data). Ti podaci ostaju pohranjeni na disku nakon gašenja spremnika i obično se posebno moraju brisati. Tu prestaje izolacija spremnika. Dodijeljeni volumei oslanjaju se na back-end za pohranu. Prema zadanim postavkama to je izvorni datotečni sustav domaćina. U arhitekturi mikroservisa uobičajeno se koristi distribuirani sustav ili datotečni sustav u oblaku. Za dohvaćanje i istraživanje ovih datotečnih sustava potrebna je izravna interakcija s datotečnim sustavom.

Trenutno ne postoji formalni mehanizam za pokretanje snimljenog spremnika. Jednom kada se isključe, čak i ako se izvezu i sadržaj datotečnog sustava i radne memorije, ne postoji mehanizam za kombiniranje tog dvoje kako bi se u potpunosti rekreiralo prethodno pokrenuto stanje. Spremnici su dizajnirani tako da budu kratkotrajni i tako pokreću procese i dodjeljuju novu memoriju nakon inicijalizacije. Iz tog razloga, interakcija sa spremnikom tijekom njegovog rada je obavezna pa je moguće sačuvati spremnik i ukloniti ga iz proizvodnog okruženja. Postoji nekoliko mehanizama koje se mogu upotrijebiti da se održi spremnik koji radi, a da spremnik dalje ne utječe na klaster na značajan način. Prvo, spremnici se mogu pauzirati u bilo kojem trenutku. Izvršenje spremnika u potpunosti je obustavljeno, memorija ostaje dodijeljena, volumei ostaju pohranjeni, itd. Bilo koji zlonamjerni softver koji se trenutno izvršava je prekinut. Drugo, spremnici se mogu staviti u karantenu uklanjanjem mrežnog pristupa ili privilegija sistemskih poziva. Procesi spremnika, i moguće zlonamjerni softver, nastavit će se izvršavati, ali neće moći slati, primati, čitati ili pisati bilo kakve podatke. Međutim, to uzrokuje greške u radu. Ovisno o tome kako procesi obrađuju ove greške, to može isključiti spremnik. Navedene akcije mogu se izvršiti ručno ili automatizirano pomoću nekog od sigurnosnih alata. Jednom kada je spremnik pauziran ili stavljen u karantenu (ako se želi postići čisto radno okruženje), moguće je povećati resurse klastera. Administrator može dodati novi čvor u sustav, isprazniti sve ostale spremnike s ovog čvora i po želji ga ukloniti iz orkestratora (Kubernetesa). U tom trenutku pristup mreži može biti ograničen s čvora, a spremnik se može nastaviti ili prebaciti na drugu mrežu.

Zaključak

Iako se poduzeća odmiču od monolitnih aplikacija prema arhitekturi spremnika i mikroservisa, i dalje se suočavaju sa širokim spektrom cyber napada usmjerenih na krađu vrijednih podataka, kontrolnu infrastrukturu ili uzrokovanje poremećaja i uništenja sustava. Forenzička analiza kritična je sposobnost bilo kojeg sigurnosnog programa poduzeća i mora uzeti u obzir obilježja značajno različite rizične površine i okoliša koji čine spremnici. Razumijevanje prolaznosti i izolacije spremnika potrebno je kako bi se identificirali ugroženi spremnici, snimile komponente i sigurno analizirale.

Literatura

[1] https://avinetworks.com/what-are-microservices-and-containers

[2] https://www.slideshare.net/MichaelDucy/monitoring-securing-microservices-in-kubernetes Ducy M. 2018.

[3] https://developer.ibm.com/depmodels/microservices/articles/why-should-we-use-microservices-and-containers/|Amanse A. 2018.

[4] https://bora.uib.no/bora-xmlui/bitstream/handle/1956/18696/Tetiana_Yarygina.pdf?sequence=1&isAllowed=y#page=54|Yarygina T., Bagge A. H. Overcoming Security Challenges in Microservice Architectures. In: 12th IEEE International Symposium on Service-Oriented System Engineering (SOSE’18). Bamberg, Germany:IEEE, Mar. 2018, pp. 11–20. doi: 10.1109/SOSE.2018.00011

[5] https://phoenixnap.com/kb/prometheus-kubernetes-monitoring|Kaplarević V. 2020.

[6] https://prometheus.io/docs/visualization/grafana|© Prometheus Authors 2014-2020 | Documentation Distributed under CC-BY-4.0

[7] https://www.stackrox.com/post/2017/08/csi-container-edition-forensics-in-the-age-of-containers|StackRox 2017.