Emuārs

Kuriem klientiem patiešām ir nepieciešama sava VM? Daudzlīmeņu Docker izolācijas plāns

VM katram klientam ir pārspīlēti. Lūk, kā izlemt, cik liela izolācija nepieciešama katram tenantam — un automatizēt šo lēmumu.

Kopsavilkums

Aģentūras bieži krīt panikā, kad klients jautā, cik patiesi izolēti viņu dati ir no citiem tenantiem. Docker namespaces un cgroups sniedz reālu izolāciju, taču tās nav tas pats, kas aparatūras robeža. Tā vietā, lai katram klientam nodrošinātu VM—vai vēl ļaunāk, izturētos pret visiem klientiem vienādi—izveidojiet nelielu izolācijas līmeņu kopu un saskaņojiet katru klientu ar vienu no tiem pēc datu jutīguma, uzticamības un atbilstības. Nocietināts konteiners (ne-root, atņemtas spējas, seccomp, tikai lasāms root) aptver lielāko daļu vietņu; regulēti vai naidīgi darbi saņem VM vai konteiners-VM hibrīdu. Šī ziņa sniedz atkārtojamu lēmumu plūsmu, salīdzināšanas tabulu un godīgu ieskatu par to, kad lielāka izolācija ir pārspīlēta.

Vai jūs esat tajā pārdošanas zvana punktā, kad jaunais klients saka: “mēs esam veselības aprūpe, parādiet mums, ka mūsu dati ir izolēti no jūsu citiem klientiem”, un jūs drīzāk vēlētos runāt par jebko citu?

Tā ir aģentūras problēma: nevis viens ideāls izvietojums, bet gan tas pats uzticamais izvietojums, kas atkārtots duci klientu ar dažādiem budžetiem, riska profiliem un atbilstības prasībām. Lūk, godīgā versija. Docker izolācija ir reāla, bet tā ir specifiska. Namespaces sniedz katram konteineram savu procesu, tīklošanas un failu sistēmas skatījumu; cgroups ierobežo CPU, atmiņu un diska I/O, lai tenanti nevarētu viens otru izsalkt. Tas, ko tas jums nepērk, ir aparatūras siena starp konteineru un resursdatora kodolu. Ja uzbrucējs izkļūst no konteinera, viņš atrodas vienīgajā kodolā, kas jums ir. Pārējā šī raksta daļa pārvērš šo neērto faktu atkārtojamā lēmumā: klasificējiet katru klientu pēc datu jutīguma un uzticamības, piemērojiet bāzes nocietināšanas profilu, un ķerieties pie VM tikai tad, kad pārkāpuma izmaksas ir augstākas par VM izmaksām.

Pagaidiet, vai konteineri jau nav izolēti?

Docker darbojas uz Linux namespaces un cgroups, un šie vārdi dara reālu darbu. Namespaces atdala procesu ID, tīkla stekus, montāžas punktus un lietotājus, lai process vienā konteinerā nevarētu redzēt cita procesu tabulu. Cgroups nosaka ierobežojumus: dodiet konteineram 0,5 CPU, 512 MB atmiņas un fiksētu bloka I/O svaru, un tieši to tas arī saņem. Viena tenanta bezgalīga cilpa tiek ierobežota, nevis nogāž kaimiņu. Ja neesat konfigurējis ierobežojumus, esat izlaidis visvienkāršāko lietu, kam cgroups ir paredzēti.

Ņemsim vienkāršu PHP lietotni konteinerā A. Tā redz savu failu sistēmu, savu tīkla interfeisu, savu PID 1. Konteineram B ir tas pats, bet cits skatījums. Tās ir namespaces. Tagad aizejiet prom un izlaidiet atmiņas ierobežojumu: konteiners A var piepildīt resursdatora RAM un likt konteineram B rāpot. Tas ir tas, ko cgroups pastāv, lai novērstu. Bet divi konteineri var būt izolēti viens no otra ar namespaces un joprojām dalīties ar resursdatora kodolu, kas ir tā daļa, par ko ir katrs konteinera bēgšanas stāsts. Ekspluats, kas sasniedz kodolu, potenciāli var sasniegt katru tenantu šajā resursdatorā.

“Docker ir izolēts” ir pustiesa frāze. Precīzāk būtu: “Docker izolē ar namespaces un cgroups, un kodola ievainojamība ir sprādziena rādiuss.” Pirms uzticat tenantam izpildīt neuzticamu kodu, pārdomājiet to minūti. Atbilde nav “nekad neizmantojiet konteinerus”—tā ir vieglā panika. Atbilde ir līmeņu sistēma.

Tātad, kāpēc dažiem klientiem ir vajadzīgs vairāk nekā namespaces?

Godīgā atbilde ir tāda, ka izolācija nav slēdzis, tā ir spektrs. Vienā galā jums ir pilnībā koplietots konteiners, kurā visi faktiski atrodas vienā lietotnē. Otrā galā jums ir atsevišķa VM katram tenantam ar savu kodolu. Lielākā daļa aģentūru darbu dzīvo neērtajā vidū, un vidus nav bināra izvēle starp “Docker ir labi” un “darbiniet VM visiem”.

Tas, kas virza klientu pa labi, nav viņu lielums. Tie ir četri jautājumi:

  • Vai viņi glabā regulētus datus? Veselības ieraksti, maksājumu karšu dati, jebkas, ko regulators sauktu par sensitīvu.
  • Vai pārkāpums viņu tenantā ir reālistisks ceļš uz citu tenantu? Ja viņi var izpildīt patvaļīgu kodu, jā.
  • Vai jūs uzticaties kodam un cilvēkiem, kas to izvieto? Klients, kurš nolīgst lētāko ārštata darbinieku, nav tāds pats uzticamības līmenis kā klients, kura izstrādes komandu jūs pazīstat.
  • Vai viņu līgumā teikts “īpašs”, “izolēts” vai “privāts”? Ja tā, jūs jau esat apsolījuši līmeni; vienīgais darbs tagad ir izvēlēties pareizo.

Ja uz šiem jautājumiem vēl nevarat atbildēt, ievietojiet klientu bāzes līmenī un pierakstiet pieņēmumus. Tas nav drošības audits; tas ir veselā saprāta pārbaude, ko atkārtojat katrā onboardingā.

Kā es varu izlemt par katru klientu, katru reizi neveicot drošības auditu?

Izveidojiet nelielu tabulu un apņemieties to ievērot. Jums nav vajadzīga matrica ar četrdesmit šūnām. Četri līmeņi aptvers gandrīz katru klientu, ko aģentūra redz.

Klienta pozīcijaKas viņus faktiski atdalaLieto, kad
1. līmenis: Koplietota lietotne/konteinersTikai lietotnes loģikaIekšējie utilīti, zema riska dati, projekti, kuros visi ir nepārprotami vienā pieteikšanās sistēmā
2. līmenis: Viens resursdators, atsevišķi konteineriNamespaces un cgroupsLielākā daļa mārketinga vietņu, kontaktformas, nav sensitīvu datu
3. līmenis: Nocietināts konteiners2. līmenis + ne-root, atņemtas spējas, seccomp, tikai lasāms root, tīkla segmentācijaE-komercija, PII, pielāgots kods, kuram pilnībā neuzticaties
4. līmenis: VM katram tenantamHipervizors un atsevišķs kodolsVeselības aprūpe, finanses, atbilstības dokumenti, neuzticams kods, trokšņaini kaimiņi

Lūk, kā tas izskatās praksē. Maizes ceptuves klients ar kontaktformu un Instagram saiti nonāk 2. līmenī: viens konteiners koplietotā resursdatorā, noklusējuma Docker tīklošana, resursu ierobežojumi, darbs padarīts. Tiešsaistes veikals, kas glabā klientu vārdus, adreses un maksājumu pāradresācijas, nonāk 3. līmenī: tas pats koplietotais resursdators, bet konteiners darbojas kā ne-root lietotājs, tam nav papildu kodola spēju, tas izmanto seccomp profilu un atklāj tikai portu 443. Medicīnas uzņemšanas portāls, kas glabā aizsargātu veselības informāciju, nonāk 4. līmenī: VM katram tenantam, jo pārkāpuma izmaksas nav “mēs to sakopsim”, bet “mēs nevaram klientam parādīt, ka uztvērām viņus nopietni”.

Viss triks ir tas, ka jūs nepārdomājat arhitektūru katram klientam. Jūs izvēlaties rindu no tabulas, uz kuru jau esat piekrituši. Tā piecu cilvēku aģentūra var darbināt simts vietnes bez simts atsevišķām drošības apsēstībām. Tas arī nozīmē, ka nākamais klients nesaņems atbildi, kas ir atkarīga no tā, kurš komandas loceklis atbildēja uz tālruni. Lai padziļināti izprastu šo izvēļu arhitektūras debates, šis ceļvedis par daudztenantīgu izolācijas līmeņu izstrādi sīkāk aplūko kompromisus.

Kā nocietināts konteiners faktiski izskatās?

Pārtrauksim teikt “nocietināts” un kļūsim konkrēti. Lūk, ko 3. līmenis nozīmē tipiskam WordPress vai PHP klientam.

Pirmkārt, nomainiet lietotāju. Lielākā daļa oficiālo attēlu pēc noklusējuma joprojām darbojas kā root; savā Dockerfailā izveidojiet ne-root lietotāju un palaidiet lietotni kā šo lietotāju. Tas uzreiz novērš visizplatītāko veidu, kā konteinera apdraudējums kļūst par resursdatora apdraudējumu.

Otrkārt, atmetiet spējas, kas jums nav vajadzīgas. Palaidiet ar --cap-drop ALL un pievienojiet atpakaļ tikai vienu, parasti NET_BIND_SERVICE, lai lietotne varētu klausīties 80. portā. Tas vien ir lielākas izmaiņas, nekā vairums sagaida.

Treškārt, padariet root failu sistēmu tikai lasāmu ar --read-only, un pievienojiet rakstāmos direktorijus (augšupielādes, datu bāzes datu direktoriju) kā sējumus vai tmpfs.

Ceturtkārt, piemērojiet seccomp profilu un, ja jūsu resursdators to atbalsta, AppArmor vai SELinux. Visbeidzot, ievietojiet konteineru īpašā Docker tīklā un atklājiet tikai tos portus, kuriem faktiski jābūt sasniedzamiem.

Izmēģināsim WordPress piemēru. Bāzes attēls, iespējams, darbojas kā root, tāpēc pievienojiet useradd soli un USER direktīvu. Konteineru palaidiet ar atmiņas ierobežojumu un CPU ierobežojumu, lai plugin satiksmes pārspriegums nekaitētu kaimiņam. Pievienojiet /var/www/html/wp-content/uploads kā rakstāmu sējumu. Iestatiet --read-only. Pievienojiet to tīklam, kuram tuvumā nav neviena --privileged karoga. Rezultāts ir konteiners, kas agrāk bija “WordPress vietne” un tagad ir “WordPress vietne, kas ir vairāk nocietināta nekā lielākā daļa virtuālo privāto serveru”.

Ja manuāla visu to izveide šķiet trausla, ir vieglāks vidusceļš: Docker uzlabotā konteinera izolācija (Enhanced Container Isolation), kas izmanto lietotāja namespace izolāciju un drošu konteinera izpildlaiku. Tas ir leģitīms īsceļš, bet tas nav bezmaksas karte, lai izlaistu ne-root vai spēju atmešanu. Tenantam joprojām ir nepieciešams saprātīgs attēls. Atšķirība ir tā, ka kodolam vērstā uzbrukuma virsma kļūst mazāka, neprasot jums vienas nakts laikā kļūt par seccomp ekspertu.

Ja vēlaties precīzu secību vienam tenantam, soli pa solim izolācijas nocietināšanas ceļvedis pārvērš šo sadaļu kopēšanas un ielīmēšanas komandās.

Kad es pārtraucu slāņošanu un vienkārši iedodu viņiem VM?

Lūk, pretējā daļa: lielāka izolācija nav automātiski labāka. VM sniedz aparatūras līmeņa izolāciju, atsevišķu kodolu un daudz mazāku uzbrukuma virsmu, ja viesa kodols krīt. Tieši to veselības aprūpes un finanšu klienti sagaida, kad viņi saka “mēs vēlamies būt izolēti”. Bet katra VM pievieno ielāgu, dublēšanas un skaitļošanas izmaksas, un tā palielina darbu, lai atjauninātu floti. Ja jūs VM visiem klientiem, jo kāds klients reiz teica, ka Docker viņus biedē, jūs par īstu naudu esat nopircis drošības teātri.

VM ir pareiza atbilde, ja risks uz vienu tenantu ir lielāks par VM ekspluatācijas izmaksām uz vienu tenantu. Tas nozīmē regulētus datus, rakstiskas atbilstības prasības, neuzticamu trešās puses kodu vai klientu, kuram ir jālikvidē trokšņains kaimiņš. Tā ir arī pareiza atbilde, ja klienta līgums burtiski sola īpašu vidi, jo “konteiners” nav tas, ko viņi iztēlojas, parakstot “īpašs”.

Bet VM neattaisno paviršu konteineru. Bieža lamatas ir ievietot klientu VM un pēc tam izlaist nocietināšanu, jo “VM viņus aizsargā”. VM aizsargā resursdatoru no tenanta, nevis tenantu no viņa paša sliktā attēla. Jūs joprojām vēlaties ne-root, atņemtas spējas un seccomp šajā VM. Hibrīda pieeja—konteineri VM iekšienē—bieži ir labākais risinājums: VM nodrošina robežu atbilstības sarunām, un konteiners sniedz jums izvietošanas darbplūsmu, kuru jūs jau pazīstat. Par šo debati ir garāka versija rakstā Vai katram tenantam vajadzētu būt savai VM?, bet īsā atbilde ir tāda, ka VM ir līgumam, nevis bailēm.

Kā padarīt šo atkārtojamu katram klientam?

Jūs to padarāt atkārtojamu, veidojot līmeņu sistēmu kā veidni, nevis atmiņu. Glabājiet Compose failu direktoriju, vienu katram līmenim: tier2-baseline, tier3-locked, tier4-vm-hybrid. Kad parādās jauns klients, nokopējiet veidni, mainiet vides mainīgos, un jūs jau zināt izolācijas formu, pirms esat uzrakstījis nevienu rindiņu jaunas infrastruktūras.

Pēc tam pierakstiet lēmumu. Nevis 400 lappušu drošības ziņojumu, bet īsu rindkopu klienta repozitorijā: kādus datus viņi glabā, kādā līmenī viņi atrodas, kāpēc un kas viņus pārceltu uz augstāku līmeni. Šī rindkopa ir vērtīgāka par simts ugunsmūra noteikumiem, jo tā ir lieta, ko varat parādīt nākamajam auditoram vai nākamajam norūpējušam klientam. Tā arī neļauj jums atcerēties, kāpēc maizes ceptuve ieguva 2. līmeni un e-komercijas veikals ieguva 3. līmeni pēc tam, kad sākotnējais pārdošanas zvans ir izbalējis.

Automatizējiet garlaicīgās pārbaudes. Lieciet savam CI skenēt katru klienta attēlu un neveiksmi būvējumam, ja tas darbojas kā root, ja tam ir visas spējas, vai ja tas mēģina publicēt portu, kas nav atļauts līmenī. Nekas no tā nav eksotisks; tas tikai nodrošina, ka veidni nejauši nesabojā labi domāts izstrādātājs. Ja tik un tā veidojat hostinga darbplūsmu, gatavai ražošanai paredzēto Docker hostinga stratēģiju raksts aptver daļu, kas nāk pēc konteineru definēšanas.

Nekas no tā nav krāšņs. Neviens emuāra ieraksts neliks “tenant izolācijai” izklausīties tik aizraujošai kā zaļa lauka arhitektūras diagramma. Bet tā ir atšķirība starp aģentūru, kas uz jautājumu “cik izolēti mēs esam?” atbild ar sakrustotiem pirkstiem “pilnīgi”, un tādu, kas var parādīt līmeni, konfigurāciju un iemeslu. Konteineri nav burvju siena. VM nav burvju lode. Līmeņu sistēma ir tikai lēmums, kuru jūs pierakstāt un izmantojat atkārtoti—un aģentūrai atkārtojamība ir visa spēle.

Sources (5)