Blogi
Pitäisikö jokaisella vuokralaisella olla oma VM?
Valitse vuokralaiskohtaisten konttien, VM:ien ja hybridiasetusten välillä riskipohjaisen päätöksentekokehyksen ja niiden kovettamistoimien avulla, jotka tekevät jokaisesta vaihtoehdosta puolustettavan.
Yhteenveto
Monivuokraajaympäristö pakottaa sinut valitsemaan, kuinka pitkälle vuokralaiset voivat ulottua toistensa alueille. Kontit käyttävät Linux-nimiavaruuksia ja cgroup-ryhmiä eristääkseen prosessit ja resurssit, mutta ne jakavat isäntäytimen. Virtuaalikoneet lisäävät laitteistorajapinnan, mutta kustannuksena on nopeus ja operatiivinen kuorma. Hybridilähestymistapa – kontit VM:ien sisällä – voi antaa sinulle molemmat, mutta se kaksinkertaistaa korjattavan alueen. Tämä artikkeli johdattaa sinut riskipohjaisen päätöksen, rinnakkaisvertailun ja Dockerin kovettamistoimien läpi, joilla on merkitystä myös VM:n sisällä. Lopussa tiedät, mikä eristysmalli sopii vuokralaisillesi ja mitä määrittää ennen käynnistystä.
Monivuokraajasovelluksesi on melkein valmis. Sinulla on Docker Compose -tiedosto, joka pystyttää pinon jokaiselle asiakkaalle, ja se on nopea. Sitten ystävä, joka pyörittää hosting-yritystä, kysyy: 'Annatko jokaiselle vuokralaiselle oman VM:n?' Jäähdyt. Et suunnitellut tuota kysymystä. Tämä artikkeli antaa sinulle tavan vastata siihen tänään ilman tietoturvatiimiä. Teet tämän yksin, joten päätöksen on oltava tarpeeksi yksinkertainen puolustettavaksi kello 2 aamuyöllä.
Lopeta 'parhaan' mallin etsiminen. Aloita kirjoittamalla ylös, mitä tapahtuu, jos vuokralaisen koodi ottaa isäntäsi hallintaansa. Määritä räjähdyssäde ennen kuin valitset minkään työkalun. Tämä harjoitus kertoo sinulle enemmän kuin mikään vertailu koskaan.
Ydin on se kämppäkaveri, jota et voi häätää
Kontit ovat tehokkaita, koska ne jakavat isäntäytimen. Tämä jakaminen on koko temppu ja koko riski. Linux-nimiavaruudet antavat jokaiselle kontille oman näkymän prosesseihin, verkkoon ja tiedostojärjestelmään. Ohjausryhmät (cgroups) antavat sinun rajoittaa suoritinta, muistia ja levyn I/O:ta, jotta yksi vuokralainen ei voi näännyttää muita. Mutta kumpikaan ei luo laitteistomuuria.
Ajattele konttia prosessina, jolla on todella hyvä väärennetty henkilöllisyys. Se uskoo olevansa omalla koneellaan. Ydin on kuitenkin yksi Linux-kopio, joka toimii isännälläsi. Jos vuokralainen hyödyntää ydinten haavoittuvuutta, nimiavaruuksista tulee pelkkää metatietoa. Hyökkääjä, joka voi kutsua ytimen toimintoja, voi ulottua muihin nimiavaruuksiin samalla ytimellä. Tämä on se konttipako, josta jatkuvasti kuulet.
Oletetaan, että isännöit pientä B2B-työkalua, jossa on yksi kontti per asiakas. Asiakas asentaa epämääräisen lisäosan, jossa on etäkoodin suorittamisen haavoittuvuus. Oletusarvoisilla Docker-asetuksilla prosessi toimii kontin sisällä pääkäyttäjänä. Pääkäyttäjä kontissa on edelleen UID 0, ja ydin ei erota tätä UID:tä isännän pääkäyttäjästä, ellet erikseen määritä käyttäjien kartoitusta. Hyökkääjä voi yrittää murtautua ulos, ja jaettu ydin on hänen kohteensa.
Epäonnistumisen ei tarvitse olla dramaattinen. Yksittäinen vuokralainen, joka vuotaa muistia, voi työntää isännän swap-tilaan, hidastaen kaikkia muita vuokralaisia. Ilman cgroup-rajoja yksi väärin toimiva silmukka on saatavuusuhka. Niiden kanssa se on estetty prosessi ja hälytys.
Tarkoittaako tämä, että kontit ovat turvattomia? Ei. Se tarkoittaa, että sinun on kohdeltava ydintä jaettuna luottamusvyöhykkeenä. Ennen kuin valitset, kirjoita yhden kappaleen riskilausunto: 'Jos vuokralaisen kontti vaarantuu, hyökkääjä voi käyttää: [list]. Liiketoiminnallinen kustannus olisi: [amount or impact].' Jos tämä kappale pelottaa sinua, et ole vainoharhainen. Olet rehellinen.
Jos haluat syvemmän katsauksen eristysspektriin jaetuista konteista täysin erillisiin pinoihin, katso oppaamme monivuokraaja-Docker-arkkitehtuurin suunnittelusta.
Kolme tapaa leikata se (Valitse yksi ennen käyttöönottoa)
Monivuokraajaeristyksessä on todella kolme arkkitehtuuria. Jokainen 'paras käytäntö' on näiden yhdistelmä.
| Lähestymistapa | Eristysraja | Paras, kun | Vaikein varoitus |
|---|---|---|---|
| Vuokralaiskohtaiset kontit | Ytimen nimiavaruudet + cgroups | Monet pienet vuokralaiset, alhainen riski per vuokralainen, tarvetta tiheydelle | Yksi ydinten hyökkäys voi murtaa kaikki vuokralaiset tällä isännällä |
| Yksi VM per vuokralainen | Hypervisor/laitteistovirtualisointi | Säännelty data, vihamieliset vuokralaiset, korkea arvo per vuokralainen | Raskaampi, hitaampi käyttöönotto, korjaat käyttöjärjestelmän per vuokralainen |
| Kontit VM:ien sisällä | VM-raja kontitettujen työkuormien ympärillä | Tiheys plus kova kuori ryhmien välillä | Kustannukset ja operatiivinen kuorma lähes kaksinkertaistuvat |
Vuokralaiskohtaiset kontit. Tämä on oletus useimmille SaaS-perustajille. Jokainen vuokralainen saa oman kontin tai pienen Compose-pinon. Käyttöönotto on välitön, imaget ovat pieniä, CI/CD on yksinkertaista. Resurssirajat estävät meluisia naapureita syömästä palvelinta. Vastapainona on jaettu ydin. Jos voit pitää työkuormat ei-etuoikeutettuina ja korjata isäntää säännöllisesti, tämä on usein oikea ensimmäinen liike.
Älä laita kahta vuokralaista samaan konttiin. Se on jaettu ydin plus jaettu runtime plus jaettu tiedostojärjestelmä. Jos yksi vuokralainen lataa tiedoston, joka luo prosessin, toinen vuokralainen on jo samassa prosessitaulukossa. Kontti on eristysyksikkösi; tee siitä yksi vuokralainen per kontti.
Entä tietokanta? Jos jokainen vuokralainen yhdistää samaan MongoDB- tai PostgreSQL-esiintymään samoilla tunnuksilla, olet jo lisännyt suuren jaetun komponentin. Anna jokaiselle vuokralaiselle erilliset tunnukset, ja mieluiten erillinen tietokanta tai skeema. Kontit eristävät sovelluksen; tietokanta on usein ensimmäinen vuoto, jota hyökkääjä testaa.
Yksi VM per vuokralainen. Anna jokaiselle vuokralaiselle täysi virtuaalikone. Hypervisor lisää laitteistotason rajan, joka on täsmälleen se, mitä ydinten hyökkäyksen on ylitettävä päästäkseen isäntään. Tämä on tärkeää säännellyissä ympäristöissä tai kun vuokralaiset ovat epäluotettavia. Kustannuksena ovat tiheys ja aika. Hallinnoit nyt käyttöjärjestelmälaivastoa, et vain kontteja. Jokainen VM tarvitsee päivitykset, tietoturva-agentit ja seurannan. Yksin toimivalle perustajalle se on todellista työtä.
Tällä tasolla toimivat mallit: käytä infrastruktuuri koodina -menetelmää luodaksesi VM samasta perusimagesta, paista päivitykset uusiin imagiin sen sijaan, että korjaisit eläviä järjestelmiä, ja päätä tuntemattomat työkuormat. Pidä VM:n hallintaportti suljettuna internetistä.
Kontit VM:ien sisällä. Tästä hybridistä puhutaan harvoin aloittelijan opetusohjelmissa. Laitat pienen VM:n jokaisen vuokralaisen (tai pienen vuokralaisryhmän) ympärille ja ajat sitten kontteja VM:n sisällä. VM on räjähdyssäteen säiliö; kontit ovat vain käyttöönotettavia yksiköitä. Tämä antaa sinulle virtualisoinnin kovan reunan ja imagien toistettavuuden. Se maksaa enemmän, koska maksat virtualisoinnin ylimääräisestä ja konttien joustavuudesta, mutta se voi olla järkevin pitkän aikavälin malli, kun et voi täysin luottaa vuokralaisiin.
Yksi yleinen mikroesimerkki: vuokralainen pyörittää Node-sovellusliittymää ja taustatyöntekijää. Sen sijaan, että käyttäisit yhtä valtavaa konttia molemmilla prosesseilla, käytä yhtä VM:ää ja sitten kahta konttia eri resurssirajoilla, jaetulla verkolla ja ilman suoraa internet-altistusta työntekijälle. VM tarjoaa kovan reunan; kontit tarjoavat rakenteen.
Minkä sinun pitäisi valita? Taulukko on lyhyt listasi. Seuraavat osiot tekevät päätöksestä konkreettisen.
Jos valitset kontit, tee nämä kuusi asiaa tai älä vaivaudu
Vuokralaiskohtaiset kontit ovat hyviä, jos kohtelet jokaista konttia mahdollisena hyökkääjänä. Se alkaa konfiguraatiosta, ei toiveajattelusta.
0. Rajoita resursseja ennen kuin luotat kehenkään. Cgroupit ovat oikeudenmukaisuusmekanismi ja saatavuuspuolustus. Aseta --memory ja --cpus jokaiselle kontille. Vuokralainen, joka vuotaa muistia, osuu omaan rajaansa, ei palvelimesi rajaan. Tämä ei ole tietoturvaraja, mutta meluisa naapuri on hyökkäys ilman yhtäkään koodiriviä. Käytännön alku: --memory 512m --cpus 0.5. Työntekijäprosessille aloita pienemmästä ja skaalaa ylöspäin.
1. Aja ei-pääkäyttäjänä. Älä koskaan anna konttiprosessin käyttää UID 0:aa, ellet ehdottomasti tarvitse sitä. Aseta käyttäjä Dockerfileen ja anna --user lisäsuojaksi. Hyökkäys, joka toimii ei-etuoikeutettuna käyttäjänä, avaa huomattavasti vähemmän polkuja ytimeen. Dockerfilessä luo käyttäjä: RUN useradd -u 10001 app ja USER app. Älä ohita tätä säästääksesi aikaa.
2. Pudota kaikki valmiudet, joita et tarvitse. Linux-valmiudet jakavat pääkäyttäjän oikeudet pieniin osiin. Useimmat verkkosovellukset eivät tarvitse juuri mitään. Aloita --cap-drop=ALL ja lisää takaisin vain ne, jotka tiedät tarvitsevasi. Kontti ilman CAP_SYS_ADMIN-valmiutta on paljon vaikeampi käyttää nimiavaruustemppuihin. Jos sovelluksesi yrittää sitoa etuoikeutetun portin, aja se korkeassa portissa ja aseta proxy eteen sen sijaan, että myöntäisit NET_BIND_SERVICE-valmiuden.
3. Tee tiedostojärjestelmästä kirjoitussuojattu. Sovelluksesi ei saa kirjoittaa omaan konttikerrokseensa. Asenna tmpfs tietotilaa varten. Hyökkääjä, joka ei voi kirjoittaa levylle, saa paljon vaikeammin istutettua pysyvyyttä. Vaarantunut PHP-sovellus, joka yrittää kirjoittaa webshellin, epäonnistuu, kun juuritiedostojärjestelmä on kirjoitussuojattu. Voit asentaa nimetyt volyymin kirjoitettavalle hakemistolle, jota sovelluksesi todella tarvitsee.
4. Ota käyttöön seccomp ja AppArmor tai SELinux. Näillä lähetetään riskialttiit järjestelmäkutsut hylkäämislistalle. Docker sisältää oletusarvoisen seccomp-profiilin; käytä sitä. Lisää AppArmor-profiili toiseksi kerrokseksi. Sinun ei tarvitse hallita jokaista järjestelmäkutsua. Sinun on kiellettävä sellaiset, joita normaali verkkotyöntekijä ei koskaan tarvitse. Älä koskaan aja --privileged-lipulla. Tämä lippu poistaa käytöstä melkein kaikki puolustukset, jotka juuri asetit.
5. Jaa verkko segmentteihin. Älä anna jokaiselle kontille reittiä jokaiseen muuhun konttiin. Oletusarvoisesti kiellä kaikki, ja avaa vain tarvitsemasi portit. Vaarantuneen tietokantakontin ei pitäisi pystyä skannaamaan hallintapaneeliasi. Jos vuokralaiset ovat eri verkoissa, yhden verkon tietomurto ei voi levitä sivusuunnassa.
Käytännön alku:
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
Laita samat liput Compose-tiedostoon ja sovella niitä jokaiseen vuokralaiseen. Tämä ei ole täydellinen, mutta se on paljon vahvempi oletus kuin mitä docker run antaa sinulle suoraan laatikosta.
Jos haluat syvemmän läpikäynnin, käytä vaiheittaista kovettamisopastamme Docker-konteille monivuokraajaympäristöissä.
Dockerin Enhanced Container Isolation -toiminto on poikkeus, joka sinun kannattaa tuntea
Jos ajat hallitussa Docker-ympäristössä, etsi Dockerin Enhanced Container Isolation (ECI) -toimintoa. Se käyttää käyttäjä-nimiavaruuseristystä ja turvallista konttiajoympäristöä taustalla. Kontin sisällä oleva pääkäyttäjä kartoittuu ei-etuoikeutetuksi käyttäjäksi isännällä, joten edes pääkäyttäjänä toimiva kontti ei saa isännän pääkäyttäjän oikeuksia. Se myös estää vaaralliset valmiudet ja järjestelmäkutsut oletusarvoisesti. Tätä ei voi jäljitellä muutamalla lipulla vanilja-Dockerissa. Jos alustasi tukee sitä, ota se käyttöön. Se ei poista ei-pääkäyttäjien ja resurssirajojen tarvetta, mutta se muuttaa riskilaskelmaa.
Voit arvioida osan tästä käyttäjänimiavaruuskartoituksella (userns-remap) Docker-daemonissa. Se ei ole yhtä täydellinen kuin turvallinen ajonaikainen ympäristö, mutta se on parempi kuin ei mitään. Jos käytät sitä, varmista että UID-kartoitus toimii ennen kuin luotat siihen.
VM-harha: virtuaalikoneisiin siirtyminen ei ole kovettamista
Tässä on vastakkainen osa, ja se on osa, jonka useimmat ohittavat. Jos siirryt yhteen VM:ään per vuokralainen ja otat sitten normaalit kontit käyttöön sen sisällä, et ole poistanut konttisi tietoturvaongelmaa. Olet lisännyt leveän häkin. Konttipako toimii edelleen; hyökkääjä päätyy vain VM:ään isännän sijaan. Se on todellinen parannus, mutta tarvitset silti ne kuusi vaihetta.
Toinen ansa on olettaa, että itse VM on turvallinen. Oletusimago heikolla SSH-salasanalla, korjaamattomilla peruspaketeilla tai avoimella hallintaportilla on lahja. Hypervisor-raja on merkityksellinen vain, jos vieras on kovetettu ja päivitetty. Muuten 'turvallinen VM:si' on nopeampi tie tietomurtoon, koska tunnet olosi turvalliseksi ja lopetat tarkistamisen.
Sen, minkä VM antaa sinulle, on pienennettävä räjähdyssäde. Yhden vuokralaisen katastrofi pysyy yhdessä VM:ssä. Sen, minkä se maksaa sinulle, on aikaasi. Sinusta tulee järjestelmänvalvoja niin monelle käyttöjärjestelmälle kuin sinulla on vuokralaisia. Jos olet yksin toimiva perustaja, joka toimittaa tuotteen, kysy itseltäsi, onko sinulla tunteja korjata ja seurata laivastoa. Jos on, VM per vuokralainen voi olla oikea valinta. Jos ei, kontit vahvalla kovettamisella voivat olla rehellisempiä.
Muista myös, että hypervisor-isäntä on kriittinen kohde. Vaarantunut hypervisor voi nähdä kaikki vieraat. Korjaa isäntä, ei vain vieraita. VM ei vapauta sinua isännän korjaamisesta; se nostaa panoksia sen puuttumisen osalta.
Huomautus hybridistä: älä oleta, että kontit VM:n sisällä antavat sinulle 'kaksi turvakerrosta' ilmaiseksi. VM lisää rajan; kontti tarvitsee silti ei-pääkäyttäjän, valmiudet ja seccompin. Muuten ensimmäinen kerros on vain niin vahva kuin heikoin kontti.
Neljä kysymystä, jotka ratkaisevat keskustelun kymmenessä minuutissa
Älä optimoi abstraktisti. Kysy itseltäsi nämä neljä kysymystä järjestyksessä. Kirjoita vastaukset ylös.
1. Mihin vuokralaisellani on pääsy? Jos vuokralainen voi päästä vain omaan verkkosovellukseensa ja tietokantaansa, vuokralaiskohtaiset kontit tiukoilla verkkosäännöillä ovat puolustettavissa. Jos vuokralaisen data on säänneltyä tai taloudellisesti arkaluonteista, siirry kohti VM:iä.
2. Kuinka paljon yhden vuokralaisen tietomurto maksaisi minulle? Laske yhteen menetetyt asiakkaat, oikeudellinen altistuminen ja luottamus. Jos luku on suurempi kuin VM:ien käytön kustannus, käytä rahat. Jos ei, kontit ovat järkevä valinta.
3. Kuinka monta vuokralaista minulla on ja kuinka paljon he maksavat? Monet pienet tilaajat: konttitiheys on tärkeää. Kourallinen suuria tilejä: anna jokaiselle VM ja laskuta sen mukaan. Vuokralaiset, jotka maksavat sinulle vähemmän kuin kahvikupin, eivät saisi jokainen vaatia hallinnoitavaa käyttöjärjestelmää.
4. Voinko korjata asioita aikataulun mukaan? Kontit jakavat yhden isäntäytimen, joten isännän korjaaminen suojaa kaikkia. VM:t moninkertaistavat korjauskohteesi. Jos tiedät jättäväsi päivitykset väliin, valitse arkkitehtuuri, jossa on vähemmän liikkuvia osia ja kovemmat oletusasetukset.
Vastauksesi klusteroituvat. Kaksi tai useampi VM-painotteinen vastaus tarkoittaa, että sinun ei pitäisi oletusarvoisesti käyttää vuokralaiskohtaisia kontteja. Kolme tai useampi konttipainotteinen vastaus tarkoittaa, että VM:t ovat ennenaikaisia. Yksi vastahakoinen tulos: alhaisen liikevaihdon vuokralainen, jolla on pääsy arkaluonteiseen dataan, tarvitsee silti VM:n, koska sääntelykustannuksella ei ole mitään tekemistä sen kanssa, kuinka paljon he maksavat.
Toimita vähin, johon voit luottaa, ja ansaitse lisää eristystä
Ensimmäisen arkkitehtuurisi ei tarvitse olla lopullinen. Aloita tiukimmalla asetelmalla, jota voit oikeasti ylläpitää, ja lisää eristystä, kun vuokralaispohjasi oikeuttaa sen. Useimmille yksintoimijoille se tarkoittaa vuokralaiskohtaisia kontteja ei-pääkäyttäjällä, rajoitetuilla valmiuksilla, kirjoitussuojatuilla tiedostojärjestelmillä, seccompilla ja verkkosegmentoinnilla. Säännellyille tai korkean arvon vuokralaisille hyppää suoraan yhteen VM:ään per vuokralainen, ja käytä kontteja vain pakkauskerroksena sisällä.
Mitä tahansa valitsetkin, kirjoita päätös ylös ja käy se läpi neljännesvuosittain. Kun saat ensimmäisen kysymyksen 'pitäisikö meidän siirtää tämä vuokralainen VM:ään?', sinulla on vastaus ja sinulla on tarkistuslista sen tueksi. Sitä eristys todella tarkoittaa: kompromissi, jota hallitset, ei teknologia, jonka ostat.
Ennen käynnistystä käy läpi käytännöllinen Docker-eristyksen tietoturvatarkistuslistamme – se muuttaa nämä päätökset listaksi, jonka voit tarkistaa ennen kuin näytät sivua asiakkaalle.

