Emuārs
Vai katram nomniekam ir nepieciešama sava VM?
Izvēlieties starp konteineriem katram nomniekam, VM un hibrīdiem risinājumiem, izmantojot uz risku balstītu lēmumu pieņemšanas sistēmu un nostiprināšanas soļus, kas padara katru iespēju pamatotu.
Kopsavilkums
Daudznomnieku mitināšana liek jums izlemt, cik tālu nomnieki var sasniegt viens otru. Konteineri izmanto Linux nosaukumvietas un cgroups, lai izolētu procesus un resursus, taču tie koplieto resursdatora kodolu. Virtuālās mašīnas pievieno aparatūras līmeņa robežu, par cenu — ātrumu un operacionālā sloga palielināšanos. Hibrīda pieeja — konteineri VM iekšpusē — var nodrošināt abus, bet tā dubulto virsmu, kas jālabo. Šis raksts jūs izvadīs cauri uz risku balstītam lēmumam, salīdzinājumam blakus un Docker nostiprināšanas soļiem, kas ir svarīgi pat VM iekšpusē. Beigās jūs zināsiet, kurš izolācijas modelis atbilst jūsu nomniekiem un kas jākonfigurē pirms palaišanas.
Jūsu daudznomnieku lietotne ir gandrīz gatava. Jums ir Docker Compose fails, kas katram klientam uzsāk steku, un tas ir ātrs. Tad draugs, kurš vada mitināšanas uzņēmumu, jautā: 'Vai jūs katram nomniekam piešķirat savu VM?' Jūs sastingstat. Jūs neplānojāt šo jautājumu. Šis raksts sniedz jums veidu, kā uz to atbildēt šodien, bez drošības komandas. Jūs to darāt viens pats, tāpēc lēmumam jābūt pietiekami vienkāršam, lai to varētu aizstāvēt plkst. 2 naktī.
Pārtrauciet meklēt 'labāko' modeli. Sāciet ar pierakstīšanu, kas notiek, ja nomnieka kods pārņem jūsu resursdatoru. Definējiet 'sprādziena rādiusu' pirms izvēlaties jebkuru rīku. Šis vingrinājums jums pateiks vairāk nekā jebkurš etalons.
Kodols ir istabas biedrs, kuru nevar izlikt
Konteineri ir efektīvi, jo tie koplieto resursdatora kodolu. Šī koplietošana ir viss triks un viss risks. Linux nosaukumvietas katram konteinerim sniedz savu skatījumu uz procesiem, tīklu un failu sistēmu. Kontroles grupas (cgroups) ļauj ierobežot CPU, atmiņu un diska I/O, lai viens nomnieks nevarētu badināt citus. Bet neviens no tiem nerada aparatūras sienu.
Domājiet par konteineru kā procesu ar ļoti labu viltus ID. Tas tic, ka atrodas uz savas mašīnas. Tomēr kodols ir viena Linux kopija, kas darbojas jūsu resursdatorā. Ja nomnieks izmanto kodola ievainojamību, nosaukumvietas kļūst par metadatiem un neko vairāk. Uzbrucējs, kurš var izsaukt kodola funkcijas, var sasniegt citas nosaukumvietas tajā pašā kodolā. Tas ir konteinera bēgšanas gadījums, par kuru jūs visu laiku dzirdat.
Pieņemsim, ka jūs mitināt mazu B2B rīku ar vienu konteineru katram klientam. Klients instalē aizdomīgu spraudni ar attālās koda izpildes kļūdu. Ar noklusējuma Docker iestatījumiem šis process darbojas kā root konteinerā. Root konteinerā joprojām ir UID 0, un kodols neatšķir šo UID no resursdatora root, ja vien jūs skaidri nemapējat lietotājus. Uzbrucējs var mēģināt izkļūt, un koplietotais kodols ir viņa mērķis.
Neveiksmei nav jābūt dramatiskai. Viens nomnieks, kas nopludina atmiņu, var iespiest resursdatoru swapā, palēninot visus citus nomniekus. Bez cgroup ierobežojumiem viens nepareizs cikls ir pieejamības uzbrukums. Ar tiem tas ir bloķēts process un brīdinājums.
Vai tas nozīmē, ka konteineri ir nedroši? Nē. Tas nozīmē, ka jums jāuztver kodols kā kopīga uzticības zona. Pirms izvēlaties, uzrakstiet vienas rindkopas riska paziņojumu: 'Ja nomnieka konteiners ir apdraudēts, uzbrucējs var piekļūt: [list]. Biznesa izmaksas būtu: [amount or impact].' Ja šī rindkopa jūs biedē, jūs neesat paranoisks. Jūs esat godīgs.
Lai dziļāk izprastu izolācijas spektru, no koplietotiem konteineriem līdz pilnīgi atdalītām kaudzēm, skatiet mūsu ceļvedi par daudznomnieku Docker arhitektūras projektēšanu.
Trīs veidi, kā to sadalīt (izvēlieties vienu pirms izvietošanas)
Patiesībā ir trīs daudznomnieku izolācijas arhitektūras. Katra 'labākā prakse' ir šo kombinācija.
| Pieeja | Izolācijas barjera | Kad vislabāk | Grūtākais brīdinājums |
|---|---|---|---|
| Konteineri katram nomniekam | Kodola nosaukumvietas + cgroups | Daudz mazu nomnieku, zems risks katram nomniekam, nepieciešams blīvums | Viens kodola ievainojamības izmantojums var salauzt visus nomniekus uz šī resursdatora |
| Viena VM katram nomniekam | Hipervizors/aparatūras virtualizācija | Regulēti dati, naidīgi nomnieki, augsta vērtība katram nomniekam | Smagāka, lēnāka nodrošināšana, jūs labojat OS katram nomniekam |
| Konteineri VM iekšpusē | VM robeža ap konteinerizētām slodzēm | Blīvums plus cieta apvalks starp grupām | Izmaksas un operacionālais slogs gandrīz dubultojas |
Konteineri katram nomniekam. Tas ir noklusējums lielākajai daļai SaaS dibinātāju. Katrs nomnieks saņem savu konteineru vai nelielu Compose steku. Nodrošināšana ir tūlītēja, attēli ir mazi, CI/CD ir vienkārša. Resursu ierobežojumi neļauj trokšņainiem kaimiņiem apēst serveri. Apmaiņa ir kopīgais kodols. Ja varat uzturēt slodzes neprivileģētas un regulāri labot resursdatoru, bieži vien tas ir pareizais pirmais solis.
Nelieciet divus nomniekus vienā konteinerā. Tas ir kopīgs kodols plus kopīga izpildlaika vide plus kopīga failu sistēma. Ja viens nomnieks augšupielādē failu, kas rada procesu, otrs nomnieks jau ir tajā pašā procesu tabulā. Konteiners ir jūsu izolācijas vienība; izveidojiet vienu nomnieku konteinerā.
Kā ar datubāzi? Ja katrs nomnieks savienojas ar vienu MongoDB vai PostgreSQL instanci ar tiem pašiem akreditācijas datiem, jūs jau esat pievienojis milzīgu kopīgu komponentu. Dodiet katram nomniekam atsevišķus akreditācijas datus un ideālā gadījumā atsevišķu datubāzi vai shēmu. Konteineri izolē lietotni; datubāze bieži ir pirmā noplūde, ko uzbrucējs pārbaudīs.
Viena VM katram nomniekam. Dodiet katram nomniekam pilnu virtuālo mašīnu. Hipervizors pievieno aparatūras līmeņa robežu, kas ir tieši tas, kas kodola ievainojamības izmantojumam jāšķērso, lai sasniegtu resursdatoru. Tas ir svarīgi regulētās vidēs vai tad, kad nomnieki nav uzticami. Izmaksas ir blīvums un laiks. Tagad jūs pārvaldāt operētājsistēmu floti, ne tikai konteinerus. Katrai VM ir nepieciešami atjauninājumi, drošības aģenti un uzraudzība. Vienam dibinātājam tas ir īsts darbs.
Modeļi, kas darbojas šajā līmenī: izmantojiet infrastruktūru kā kodu, lai izveidotu VM no tā paša bāzes attēla, iestrādājiet atjauninājumus jaunos attēlos, nevis labojiet tiešās sistēmas, un pārtrauciet slodzes, kuras neatpazīstat. Turiet VM pārvaldības portu slēgtu no interneta.
Konteineri VM iekšpusē. Šis hibrīds reti tiek apspriests iesācēju apmācībās. Jūs novietojat mazu VM ap katru nomnieku (vai nelielu nomnieku grupu), pēc tam palaidiet konteinerus šīs VM iekšpusē. VM ir 'sprādziena rādiusa' konteiners; konteineri ir tikai izvietojami mezgli. Tas sniedz jums virtualizācijas cieto malu un attēlu atkārtojamību. Tas maksā vairāk, jo jūs maksājat par virtualizācijas pieskaitāmajām izmaksām un konteineru elastību, bet tas var būt saprātīgākais ilgtermiņa modelis, ja nevarat pilnībā uzticēties nomniekiem.
Viens izplatīts mikro-piemērs: nomnieks darbina Node API un fona darbinieku. Tā vietā, lai izmantotu vienu milzīgu konteineru ar abiem procesiem, izmantojiet vienu VM, tad divus konteinerus ar dažādiem resursu ierobežojumiem, kopīgu tīklu un bez tiešas interneta pieejamības fona darbiniekam. VM nodrošina cieto malu; konteineri nodrošina struktūru.
Kuru jums vajadzētu izvēlēties? Tabula ir jūsu īsais saraksts. Nākamās sadaļas padara lēmumu konkrētu.
Ja izvēlaties konteinerus, dariet šīs sešas lietas vai neņemieties
Konteineri katram nomniekam ir labi, ja jūs katru konteineru uztverat kā potenciālu uzbrucēju. Tas sākas ar konfigurāciju, nevis vēlmju domāšanu.
0. Ierobežojiet resursus, pirms kādam uzticaties. Cgroups ir taisnīguma mehānisms un pieejamības aizsardzība. Iestatiet --memory un --cpus katram konteineram. Nomniekam, kas nopludina atmiņu, vajadzētu atsisties pret savu ierobežojumu, nevis jūsu servera ierobežojumu. Tas nav drošības ierobežojums, bet trokšņains kaimiņš ir uzbrukums bez vienas koda rindiņas. Praktisks sākums: --memory 512m --cpus 0.5. Fona procesam sāciet zemāk un palieliniet.
1. Darbojieties kā lietotājs, kas nav root. Nekad neļaujiet konteinera procesam izmantot UID 0, ja vien tas nav absolūti nepieciešams. Iestatiet lietotāju Dockerfailā un nododiet --user kā papildu aizsardzību. Ekspluatācijas kods, kas darbojas kā neprivileģēts lietotājs, ir daudz mazāk ceļu uz kodolu. Dockerfailā izveidojiet lietotāju: RUN useradd -u 10001 app un USER app. Neizlaidiet šo, lai ietaupītu laiku.
2. Atmetiet visas iespējas, kas jums nav vajadzīgas. Linux iespējas sadala root pilnvaras mazās daļās. Lielākajai daļai tīmekļa lietotņu gandrīz neviena nav nepieciešama. Sāciet ar --cap-drop=ALL un pievienojiet atpakaļ tikai to, kas, kā jūs zināt, ir nepieciešams. Konteineram bez CAP_SYS_ADMIN ir daudz grūtāk izmantot nosaukumvietu trikus. Ja jūsu lietotne mēģina piesaistīt privileģētu portu, palaidiet to uz augstu portu un novietojiet priekšā starpniekserveri, nevis piešķiriet NET_BIND_SERVICE.
3. Padariet failu sistēmu tikai lasāmu. Jūsu lietotnei nevajadzētu rakstīt savā konteinera slānī. Pievienojiet tmpfs stāvoklim. Uzbrucējam, kurš nevar rakstīt diskā, ir daudz grūtāk izveidot pastāvīgu klātbūtni. Apdraudēta PHP lietotne, kas mēģina ierakstīt tīmekļa čaulas failu, neizdosies, ja saknes failu sistēma ir tikai lasāma. Varat pievienot nosauktu sējumu rakstāmam direktorijam, kas jūsu lietotnei patiešām ir nepieciešams.
4. Lietojiet seccomp un AppArmor vai SELinux. Tie nosūta riskantas sistēmu izsaukumus uz atkritumu kaudzi. Docker ir noklusējuma seccomp profils; izmantojiet to. Pievienojiet AppArmor profilu vēl vienam slānim. Jums nav jāapgūst katrs sistēmas izsaukums. Jums ir jānoliedz tas, ko parasts tīmekļa darbinieks nekad neprasa. Nekad nedarbiniet ar --privileged. Šis karodziņš atspējo gandrīz visas aizsardzības, kuras tikko iestatījāt.
5. Segmentējiet tīklu. Nedodiet katram konteineram maršrutu uz katru citu konteineru. Noklusējuma aizliegums, pēc tam atveriet tikai vajadzīgos portus. Apdraudēts datubāzes konteiners nedrīkst skenēt jūsu administrācijas paneli. Ja nomnieki atrodas atsevišķos tīklos, pārkāpums vienā tīklā nevar izplatīties horizontāli.
Praktisks sākums:
docker run --user 10001 --cap-drop=ALL --security-opt no-new-privileges --read-only --tmpfs /tmp:rw,size=64M --security-opt seccomp=default.json --memory 512m --cpus 0.5 myimage
Ievietojiet tos pašus karodziņus Compose failā un lietojiet tos katram nomniekam. Tas nav pilnīgs, bet tas ir daudz spēcīgāks noklusējums nekā tas, ko docker run sniedz no kastes.
Lai iegūtu dziļāku ieskatu, izmantojiet mūsu soli pa solim sniegto nostiprināšanas ceļvedi Docker konteineriem daudznomnieku mitināšanā.
Docker uzlabotā konteinera izolācija ir izņēmums, par kuru jums vajadzētu zināt
Ja jūs darbojaties pārvaldītā Docker vidē, meklējiet Docker uzlaboto konteinera izolāciju (ECI). Tā izmanto lietotāja nosaukumvietu izolāciju un drošu konteinera izpildlaiku iekšpusē. Root konteinerā kartējas uz neprivileģētu lietotāju resursdatorā, tāpēc pat konteiners, kas darbojas kā root, neiegūst resursdatora root tiesības. Tā arī pēc noklusējuma bloķē bīstamas iespējas un sistēmas izsaukumus. To nevar atjaunot ar dažiem karodziņiem uz standarta Docker. Ja jūsu platforma to atbalsta, ieslēdziet to. Tas nenovērš nepieciešamību pēc ne-root lietotājiem un resursu ierobežojumiem, bet tas maina riska aprēķinus.
Jūs varat aptuveni atkārtot daļu no tā, izmantojot lietotāja nosaukumvietu pārkartēšanu (userns-remap) Docker dēmonā. Tas nav tik pilnīgs kā drošs izpildlaiks, bet tas ir labāk nekā nekas. Ja to izmantojat, pirms uzticaties, pārbaudiet, vai UID kartēšana darbojas.
VM maldība: pāreja uz virtuālajām mašīnām nav nostiprināšana
Šeit ir pretrunīgā daļa, un tā ir daļa, ko lielākā daļa izlaiž. Ja pāriet uz vienu VM katram nomniekam un pēc tam tajā izvietojat savus parastos konteinerus, jūs neesat noņēmis savu konteineru drošības problēmu. Jūs esat pievienojis plašu būri. Konteinera bēgšana joprojām darbojas; uzbrucējs vienkārši nonāk VM, nevis resursdatorā. Tas ir reāls uzlabojums, bet jums joprojām ir nepieciešami seši soļi.
Otrs slazds ir pieņemt, ka pati VM ir droša. Noklusējuma attēls ar vāju SSH paroli, nelabotiem bāzes pakotiem vai atvērtu pārvaldības portu ir dāvana. Hipervizora robežai ir nozīme tikai tad, ja viesis ir nostiprināts un atjaunināts. Pretējā gadījumā jūsu 'drošā VM' ir ātrāks ceļš uz kompromitēšanu, jo jūs jūtaties droši un pārtraucat pārbaudīt.
Tas, ko VM jums sniedz, ir samazināms 'sprādziena rādiuss'. Viena nomnieka katastrofa paliek vienā VM. Tas, ko tas jums izmaksā, ir jūsu laiks. Jūs kļūstat par sistēmas administratoru tik daudzām operētājsistēmām, cik jums ir nomnieku. Ja esat vientuļš dibinātājs, kas izlaiž produktu, jautājiet, vai jums ir stundas, lai labotu un uzraudzītu floti. Ja jā, VM katram nomniekam var būt pareizais lēmums. Ja nē, konteineri ar spēcīgu nostiprināšanu var būt godīgāki.
Atcerieties arī, ka jūsu hipervizora resursdators ir kritisks mērķis. Apdraudēts hipervizors var redzēt visus viesus. Labojiet resursdatoru, ne tikai viesus. VM neatbrīvo jūs no resursdatora labošanas; tas palielina likmes, ja to izlaižat.
Brīdinājums par hibrīdu: nepieņemiet, ka konteineri VM iekšpusē dod jums 'divus drošības slāņus' bez maksas. VM pievieno robežu; konteineram joprojām ir nepieciešami ne-root, iespējas un seccomp. Pretējā gadījumā pirmais slānis ir tikai tik spēcīgs, cik vājākais konteiners.
Četri jautājumi, kas desmit minūtēs atrisina diskusiju
Neoptimizējiet abstrakti. Uzdodiet sev šos četrus jautājumus secībā. Pierakstiet atbildes.
1. Kam manam nomniekam ir piekļuve? Ja nomnieks var sasniegt tikai savu tīmekļa lietotni un datubāzi, konteineri katram nomniekam ar stingriem tīkla noteikumiem ir aizstāvami. Ja nomnieka dati ir regulēti vai finansiāli jutīgi, virzieties uz VM.
2. Cik daudz man izmaksātu viena nomnieka kompromitēšana? Saskaitiet zaudētos klientus, juridiskos riskus un uzticību. Ja skaitlis ir lielāks par VM darbināšanas izmaksām, tērējiet naudu. Ja nē, konteineri ir racionāla izvēle.
3. Cik man ir nomnieku un cik viņi maksā? Daudz mazu abonentu: konteineru blīvumam ir nozīme. Daži lieli konti: dodiet katram VM un attiecīgi rēķiniet. Nomnieki, kuri maksā mazāk nekā kafijas tasi, nedrīkst katrs prasīt operētājsistēmas pārvaldību.
4. Vai es varu veikt labojumus pēc grafika? Konteineri koplieto vienu resursdatora kodolu, tāpēc resursdatora labošana aizsargā visus. VM reizina jūsu labošanas mērķus. Ja zināt, ka izlaižat atjauninājumus, izvēlieties arhitektūru ar mazāk kustīgu daļu un stingrākiem noklusējumiem.
Jūsu atbildes grupēsies. Divas vai vairākas atbildes, kas vērstas uz VM, nozīmē, ka jums nevajadzētu noklusēt konteinerus katram nomniekam. Trīs vai vairākas atbildes, kas vērstas uz konteineriem, nozīmē, ka VM ir priekšlaicīgas. Viena pretrunīga rezultāta: zemas peļņas nomniekam ar piekļuvi sensitīviem datiem joprojām ir nepieciešama VM, jo regulējuma izmaksām nav nekāda sakara ar to, cik viņi maksā.
Izlaidiet vismazāko, kam varat uzticēties, tad nopelniet vairāk izolācijas
Jūsu pirmajai arhitektūrai nav jābūt jūsu pēdējai. Sāciet ar visstingrāko iestatījumu, ko faktiski varat uzturēt, pēc tam pievienojiet izolāciju, kad jūsu nomnieku bāze to pamato. Lielākajai daļai vientuļo operatoru tas nozīmē konteinerus katram nomniekam ar ne-root, ierobežotām iespējām, tikai lasāmām failu sistēmām, seccomp un tīkla segmentāciju. Regulētiem vai augstas vērtības nomniekiem leciet tieši uz vienu VM katram nomniekam, ar konteineriem tikai kā iepakojuma slāni iekšpusē.
Neatkarīgi no tā, ko izvēlaties, pierakstiet lēmumu un pārskatiet to reizi ceturksnī. Kad saņemsiet savu pirmo jautājumu 'vai mums vajadzētu pārvietot šo nomnieku uz VM?', jums būs atbilde, un jums būs kontrolsaraksts, ko to apstiprināt. Tas patiesībā nozīmē izolāciju: kompromiss, ko jūs pārvaldāt, nevis tehnoloģija, ko pērkat.
Pirms palaišanas iziet cauri mūsu praktiskajam Docker izolācijas drošības kontrolsarakstam — tas pārvērš šos lēmumus sarakstā, ko varat pārbaudīt, pirms rādāt lapu klientam.

