Blog
Ktorí klienti skutočne potrebujú vlastný VM? Plán izolácie Dockeru podľa úrovní
VM pre každého klienta je prehnané. Tu je návod, ako rozhodnúť, koľko izolácie každý nájomca potrebuje – a ako toto rozhodnutie automatizovať.
Zhrnutie
Agentúry často prepadnú panike, keď sa klient opýta, ako skutočne izolované sú ich dáta od ostatných nájomcov. Dockerove namespaces a cgroups poskytujú skutočnú izoláciu, ale nie sú to isté ako hardvérová hranica. Namiesto toho, aby ste každého klienta spúšťali na VM – alebo ešte horšie, správali sa ku každému rovnako – vytvorte malú sadu izolačných úrovní a priraďte každého klienta k jednej podľa citlivosti dát, dôvery a zhody. Uzamknutý kontajner (non-root, odobraté capabilities, seccomp, read-only root) pokrýva väčšinu stránok; regulované alebo nepriateľské workloads dostanú VM alebo hybrid kontajner-v-VM. Tento príspevok ponúka opakovateľný rozhodovací postup, porovnávaciu tabuľku a úprimný pohľad na to, kedy je viac izolácie zbytočné.
Ste v bode predajného hovoru, keď nový klient povie: „sme zdravotníctvo, ukážte mi, že naše dáta sú izolované od vašich ostatných klientov“ a vy by ste radšej hovorili o čomkoľvek inom?
Toto je problém agentúr: nie jedno dokonalé nasadenie, ale rovnaké spoľahlivé nasadenie opakované pre tucet klientov s rôznymi rozpočtami, rizikovými profilmi a požiadavkami na zhodu. Tu je úprimná verzia. Docker izolácia je skutočná, ale je špecifická. Namespaces dávajú každému kontajneru vlastný pohľad na procesy, sieť a súborový systém; cgroups obmedzujú CPU, pamäť a diskové I/O, aby sa nájomcovia navzájom nevyhladovali. Čo vám to nekúpi, je hardvérová stena medzi kontajnerom a hostiteľským jadrom. Ak útočník unikne z kontajnera, je vo vnútri jediného jadra, ktoré máte. Zvyšok tohto článku mení tento nepríjemný fakt na opakovateľné rozhodnutie: klasifikujte každého klienta podľa citlivosti dát a dôvery, aplikujte základný hardening profil a siahnite po VM len vtedy, keď sú náklady na porušenie vyššie ako náklady na VM.
Počkať, nie sú kontajnery už izolované?
Docker beží na Linuxových namespaces a cgroups a tieto slová robia skutočnú prácu. Namespaces oddeľujú ID procesov, sieťové zásobníky, mount body a používateľov, takže proces v jednom kontajneri nemôže vidieť tabuľku procesov iného. Cgroups nastavujú limity: dajte kontajneru 0,5 CPU, 512 MB pamäte a pevnú váhu blokového I/O a presne to dostane. Nekontrolovaná slučka v jednom nájomcovi sa obmedzí namiesto toho, aby zhodila suseda. Ak ste nenakonfigurovali limity, vynechali ste najzákladnejšiu vec, na ktorú cgroups slúžia.
Vezmite jednoduchú PHP aplikáciu v kontajneri A. Vidí vlastný súborový systém, vlastné sieťové rozhranie, vlastné PID 1. Kontajner B má to isté, ale iný pohľad. To sú namespaces. Teraz odíďte a vynechajte pamäťový limit: kontajner A môže zaplniť RAM hostiteľa a spomaliť kontajner B na lezenie. To je to, čo cgroups existujú, aby zabránili. Ale dva kontajnery môžu byť od seba izolované namespaces a stále zdieľať hostiteľské jadro, čo je tá časť, o ktorej sú všetky príbehy o úniku z kontajnera. Exploit, ktorý sa dostane k jadru, môže potenciálne dosiahnuť každého nájomcu na tomto hostiteľovi.
„Docker je izolovaný“ je polopravdivá veta. Presná verzia je: „Docker izoluje pomocou namespaces a cgroups a zraniteľnosť jadra je polomer výbuchu.“ Skôr než dôverujete nájomcovi, aby spúšťal nedôveryhodný kód, chvíľu pri tej myšlienke posedte. Odpoveď nie je „nikdy nepoužívajte kontajnery“ – to je ľahká panika. Odpoveďou je systém úrovní.
Tak prečo niektorí klienti potrebujú viac ako namespaces?
Úprimná odpoveď je, že izolácia nie je prepínač, ale spektrum. Na jednom konci máte plne zdieľaný kontajner, kde je každý efektívne v jednej aplikácii. Na druhom konci máte samostatný VM pre každého nájomcu s vlastným jadrom. Väčšina agentúrnej práce žije v nepohodlnom strede a stred nie je binárna voľba medzi „Docker je v poriadku“ a „spustiť VM pre každého.“
Čo posúva klienta doprava, nie je jeho veľkosť. Sú to štyri otázky:
- Ukladajú regulované dáta? Zdravotné záznamy, údaje o platobných kartách, čokoľvek, čo by regulátor nazval citlivým.
- Má porušenie na ich nájomcovi reálnu cestu k inému nájomcovi? Ak môžu spúšťať ľubovoľný kód, áno.
- Dôverujete kódu a ľuďom, ktorí ho nasadzujú? Klient, ktorý si najme najlacnejšieho freelancera, nie je na rovnakej úrovni dôvery ako klient, ktorého dev tím poznáte.
- Hovorí ich zmluva „vyhradené“, „izolované“ alebo „súkromné“? Ak áno, už ste sľúbili úroveň; jedinou úlohou je teraz vybrať tú správnu.
Ak na tieto otázky ešte neviete odpovedať, zaradte klienta do základnej úrovne a zapíšte si predpoklady. Toto nie je bezpečnostný audit; je to kontrola zdravého rozumu, ktorú opakujete pri každom onboardingu.
Ako sa mám rozhodnúť pre každého klienta bez toho, aby som zakaždým spúšťal bezpečnostný audit?
Vytvorte malú tabuľku a držte sa jej. Nepotrebujete maticu so štyridsiatimi bunkami. Štyri úrovne pokryjú takmer každého klienta, ktorého agentúra vidí.
| Pozícia klienta | Čo ich skutočne oddeľuje | Použiť, keď |
|---|---|---|
| Úroveň 1: Zdieľaná aplikácia/kontajner | Iba aplikačná logika | Interné nástroje, dáta s nízkym rizikom, projekty, kde sú všetci explicitne v jednom prihlasovacom systéme |
| Úroveň 2: Rovnaký hostiteľ, samostatné kontajnery | Namespaces a cgroups | Väčšina marketingových stránok, kontaktné formuláre, žiadne citlivé dáta |
| Úroveň 3: Uzamknutý kontajner | Úroveň 2 + non-root, odobraté capabilities, seccomp, read-only root, segmentácia siete | E-commerce, PII, vlastný kód, ktorému úplne nedôverujete |
| Úroveň 4: VM pre každého nájomcu | Hypervisor a samostatné jadro | Zdravotníctvo, financie, compliance dokumentácia, nedôveryhodný kód, hluční susedia |
Takto to funguje v praxi. Pekársky klient s kontaktným formulárom a odkazom na Instagram pôjde do Úrovne 2: jeden kontajner na zdieľanom hostiteľovi, predvolená Docker sieť, limity zdrojov, hotovo. Internetový obchod, ktorý ukladá mená zákazníkov, adresy a presmerovania platieb, pôjde do Úrovne 3: rovnaký zdieľaný hostiteľ, ale kontajner beží ako non-root používateľ, nemá žiadne extra kernel capabilities, používa seccomp profil a vystavuje iba port 443. Medicínsky vstupný portál, ktorý ukladá chránené zdravotné informácie, pôjde do Úrovne 4: VM pre každého nájomcu, pretože náklady na porušenie nie sú „vyčistíme to“, ale „nemôžeme klientovi ukázať, že sme ho brali vážne.“
Celý trik je v tom, že nepremýšľate o architektúre pre každého klienta odznova. Vyberáte riadok z tabuľky, na ktorej ste sa už dohodli. Takto môže päťčlenná agentúra prevádzkovať sto stránok bez sto samostatných bezpečnostných posadnutostí. To tiež znamená, že ďalší klient nedostane odpoveď, ktorá závisí od toho, ktorý člen tímu zdvihol telefón. Pre hlbšiu architektonickú diskusiu za týmito voľbami tento sprievodca navrhovaním multi-tenant izolačných úrovní podrobnejšie pokrýva kompromisy.
Ako vlastne vyzerá uzamknutý kontajner?
Prestaňme hovoriť „uzamknutý“ a poďme na konkrétnosti. Toto znamená Úroveň 3 pre typického WordPress alebo PHP klienta.
Po prvé, zmeňte používateľa. Väčšina oficiálnych obrazov stále štandardne beží ako root; vo vašom Dockerfile vytvorte non-root používateľa a spustite aplikáciu ako tento používateľ. Okamžite to odstráni najbežnejší spôsob, akým sa kompromitácia kontajnera stane kompromitáciou hostiteľa. Po druhé, odoberte capabilities, ktoré nepotrebujete. Spustite s --cap-drop ALL a pridajte späť iba jeden, zvyčajne NET_BIND_SERVICE, aby aplikácia mohla počúvať na porte 80. Už to samo o sebe je väčšia zmena, než väčšina ľudí očakáva. Po tretie, urobte koreňový súborový systém read-only pomocou --read-only a pripojte zapisovateľné adresáre (uploady, dátový adresár databázy) ako volumes alebo tmpfs. Po štvrté, aplikujte seccomp profil a, ak to váš hostiteľ podporuje, AppArmor alebo SELinux. Nakoniec umiestnite kontajner na vyhradenú Docker sieť a vystavte iba porty, ktoré skutočne musia byť dosiahnuteľné.
Poďme si prejsť príklad WordPress. Základný obraz pravdepodobne beží ako root, takže pridáte krok useradd a direktívu USER. Spustíte kontajner s pamäťovým limitom a CPU limitom, aby nápor pluginovej prevádzky nepoškodil suseda. Pripojíte /var/www/html/wp-content/uploads ako zapisovateľný volume. Nastavíte --read-only. Pripojíte ho k sieti, ktorá nemá nikde v blízkosti príznak --privileged. Výsledkom je kontajner, ktorý býval „WordPress stránka“ a teraz je „WordPress stránka, ktorá je náhodou viac uzamknutá ako väčšina virtuálnych privátnych serverov.“
Ak sa vám ručné nastavovanie všetkého zdá krehké, existuje jednoduchšia stredná cesta: Docker Enhanced Container Isolation, ktorá používa user namespace izoláciu a bezpečný runtime pre kontajnery. Je to legitímna skratka, ale nie je to voľný lístok na vynechanie non-root alebo odoberania capabilities. Nájomca stále potrebuje rozumný obraz. Rozdiel je v tom, že útočná plocha smerom k jadru sa zmenší bez toho, aby ste sa cez noc stali expertom na seccomp. Ak chcete presnú postupnosť pre jedného nájomcu, podrobný sprievodca hardeningom izolácie premení túto sekciu na príkazy na kopírovanie a vkladanie.
Kedy prestanem pridávať vrstvy a jednoducho im dám VM?
Tu je kontroverzná časť: viac izolácie nie je automaticky lepšie. VM poskytujú izoláciu na úrovni hardvéru, samostatné jadro a oveľa menšiu útočnú plochu, ak padne hostiteľské jadro. To je presne to, čo klienti v zdravotníctve a financiách očakávajú, keď povedia „chceme byť izolovaní.“ Ale každý VM pridáva náklady na patchovanie, zálohovanie a výpočtový výkon a znásobuje prácu s udržiavaním flotily. Ak dáte VM každému klientovi, pretože vám jeden klient kedysi povedal, že sa Docker bojí, kúpili ste si divadlo bezpečnosti za skutočné peniaze.
VM je správna odpoveď, keď je riziko na nájomcu vyššie ako prevádzkové náklady na VM na nájomcu. To znamená regulované dáta, písomné požiadavky na zhodu, nedôveryhodný kód tretej strany alebo klient, ktorý potrebuje odstrániť hlučného suseda. Je to tiež správna odpoveď, keď zmluva klienta doslova sľubuje vyhradené prostredie, pretože „kontajner“ nie je to, čo si predstavujú, keď podpisujú „vyhradené.“
Ale VM neospravedlňuje nedbalý kontajner. Častou pascou je dať klienta do VM a potom vynechať hardening, pretože „VM ich chráni.“ VM chráni hostiteľa pred nájomcom, nie nájomcu pred jeho vlastným zlým obrazom. Vnútri toho VM stále chcete non-root, odobraté capabilities a seccomp. Hybridný prístup – kontajnery vo vnútri VM – je často ideálny: VM poskytuje hranicu pre compliance rozhovory a kontajner vám dáva nasadzovací workflow, ktorý už poznáte. Dlhšia verzia tejto diskusie je v Má mať každý nájomca vlastný VM?, ale krátka odpoveď je, že VM je pre zmluvu, nie pre strach.
Ako to urobím opakovateľné pre každého klienta?
Urobíte to opakovateľným tým, že systém úrovní urobíte šablónou, nie pamäťou. Udržiavajte adresár Compose súborov, jeden pre každú úroveň: tier2-baseline, tier3-locked, tier4-vm-hybrid. Keď sa objaví nový klient, skopírujte šablónu, zmeňte environmentálne premenné a už viete tvar izolácie skôr, než napíšete riadok novej infraštruktúry.
Potom si zapíšte rozhodnutie. Nie 400-stranovú bezpečnostnú správu, ale krátky odsek v repozitári klienta: aké dáta ukladajú, na ktorej úrovni sú, prečo a čo by ich posunulo o úroveň vyššie. Tento odsek má väčšiu hodnotu ako sto firewallových pravidiel, pretože je to vec, ktorú môžete ukázať ďalšiemu audítorovi alebo ďalšiemu znepokojenému klientovi. Tiež vám bráni v tom, aby ste si museli pamätať, prečo pekár dostal Úroveň 2 a e-shop Úroveň 3, keď pôvodný predajný hovor už vyprchal.
Automatizujte nudné kontroly. Nechajte vaše CI skenovať každý obraz klienta a zlyhať build, ak beží ako root, ak má všetky capabilities alebo ak sa pokúša publikovať iný port, než aké úroveň povoľuje. Nič z toho nie je exotické; je to len zabezpečenie toho, aby šablónu náhodou nerozbil dobre mienený vývojár. Ak aj tak budujete okolitý hostingový workflow, článok o produkčných Docker hostingových stratégiách pokrýva časť, ktorá prichádza po definovaní kontajnerov.
Nič z toho nie je očarujúce. Žiadny blogový príspevok nespraví „izoláciu nájomcov“ tak vzrušujúcou, ako diagram architektúry na zelenej lúke. Ale toto je rozdiel medzi agentúrou, ktorá odpovedá „ako sme izolovaní?“ so zaťatými prstami „úplne“ a tou, ktorá môže ukázať úroveň, konfiguráciu a dôvod. Kontajnery nie sú magická stena. VM nie sú magická guľka. Systém úrovní je len rozhodnutie, ktoré si zapíšete a znovu použijete – a pre agentúru je opakovateľnosť celá hra.

