Blogi

Usalduse eksiarvamus: Kuidas meie mitmeüürnikuga Dockeri seadistus lekkis andmeid (ja kuidas me selle parandasime)

Õppige, kuidas ühe meeskonna naiivne Dockeri seadistus põhjustas üleüürnike andmelekke ja kihilise isolatsioonistrateegia, mis seda ära hoidis.

Kokkuvõte

Dockeri konteinerid ei ole vaikimisi isoleeritud – nad jagavad hosti kerneli ja ilma teadliku konfiguratsioonita võivad üürnikud üksteist segada. See artikkel kirjeldab reaalset stsenaariumit, kus mitmeüürnikuga hostimisteenuse pakkuja avastas, et kliendi konteinerid pääsevad ligi üksteise andmebaasidele jagatud võrgu ja nõrkade turvaseadete tõttu. Näitame samm-sammult muudatusi, mis rikkumise parandasid: üürnikupõhised kasutaja määratletud võrgud, mittejuurkasutajad, mahavõetud võimalused, kirjutuskaitstud failisüsteemid ja seccomp profiilid. Levinud eeldus on, et konteinerid pakuvad oma olemuselt tugevat isolatsiooni; me vaidlustame seda, selgitades, miks virtuaalmasinad pakuvad endiselt tugevamat piiri ja millal kaaluda hübriidlähenemist. Kokkuvõte rõhutab, et isolatsioon on kihiline harjutus, mitte üksik märkeruut.

Juhtum: Kui konteinerid räägivad liiga palju

Olete seadistanud Dockeri ühel hostil mitme kliendi veebisaitide käitamiseks. Igal kliendil on oma konteiner – kena, isoleeritud keskkond, eks? Nii me arvasime. Kuni rutiinne turvaaudit paljastas, et kliendi A konteiner luges kliendi B konteineri MySQL pistikupesa samal hostil. Nad jagasid vaikimisi bridge võrku. Hullem, konteinerid töötasid root kasutajana, nii et ründaja, kes ühe ohustas, võis manipuleerida hosti Dockeri pistikupesa või teise konteineri failisüsteemiga. Rikkumine polnud keerukas ärakasutamine; see oli põhiline valekonfigureerimine. Andmed lekkisid. Usaldus haihtus.

Ebaõnnestumise stsenaarium pole haruldane. Paljud meeskonnad eeldavad, et Dockeri nimeruumid ja cgroupid isoleerivad üürnikke automaatselt, kuid nad alahindavad, kui palju põgenemisluuke on vaikimisi avatud. Vaikimisi bridge võrgud ei paku konteinerite vahel võrguisolatsiooni. Root kasutajana töötamine annab konteinerile rohkem võimu kui vaja. Ja ilma selgete ressursipiiranguteta võib üks lärmakas naaber teisi CPU-st või mälust näljutada.

Samm 1: Lõpetage ühe võrgu jagamine

Meie esimene parandus oli anda igale üürnikule oma kasutaja määratletud Dockeri võrk. See takistab konteineritel teineteiseni jõudmist, välja arvatud juhul, kui te need selgesõnaliselt ühendate. Lõime skripti, mis iga üürniku jaoks käivitab spetsiaalse võrgu ja kinnitab nende rakenduskonteineri selle külge. Andmebaasi konteiner elab samas üürniku võrgus, kuid lisasime ka sisemise võrgu ainult üürnikusiseseks suhtluseks. Enam pole üleüürniku luuramist.

Isolatsioonisime ka andmebaasid, käivitades need eraldi konteinerites samas üürniku võrgus, kasutades eraldi andmemahtusid. See tagas, et isegi kui ründaja tungib rakenduskonteinerisse, ei saa ta teise üürniku andmebaasi liiklust nuhkida.

Põhjalikuma ülevaate saamiseks võrguisolatsiooni strateegiatest vaadake Praktiline Dockeri isolatsiooni turvakontrolli nimekiri mitmeüürnikuga hostimiseks.

Samm 2: Loobuge mittevajalikest õigustest

Vaikimisi töötavad Dockeri konteinerid piiratud Linuxi võimalustega, kuid neil on siiski rohkem kui enamik rakendusi vajab. Meie konteinerid töötasid root kasutajana, mis võimaldas protsessidel sees teha toiminguid nagu failisüsteemide ühendamine või kerneli parameetrite muutmine. Lülitusime rakenduse käitamisele mittejuurkasutajana konteineri sees (kasutades USER direktiivi Dockerfile'is) ja eemaldasime kõik võimalused, välja arvatud need, mis on hädavajalikud. Tüüpilise veebirakenduse puhul võivad need olla ainult NET_BIND_SERVICE (portide alla 1024 sidumiseks) ja CHOWN (kataloogidesse kirjutamiseks). Lisasime ka --security-opt no-new-privileges, et vältida õiguste eskaleerumist.

See samm üksi kõrvaldas paljud tavalised konteinerist põgenemise vektorid. Ründaja, kes ohustab veebiserverit, ei saa paigaldada pakette, muuta süsteemi binaare ega juurdepääsu hosti Dockeri pistikupesale, kuna protsessil puuduvad CAP_SYS_ADMIN või CAP_DAC_OVERRIDE võimalused.

Samm 3: Lukustage failisüsteem

Kirjutatavad failisüsteemid on tavaline ründepind. Tegime kõigi konteinerite juurfailisüsteemi kirjutuskaitstuks (--read-only) ja ühendasime ajutised failisüsteemid (tmpfs) kataloogidele, mis vajavad kirjutusõigust, nagu /tmp ja rakenduse vahemälu kataloog. See takistab ründajal rakenduse koodi muutmast või pahatahtlike binaaride püsivaks muutmist.

Lisaks kasutasime Dockeri --mount valikut tundlike kataloogide, nagu Dockeri pistikupesa, sidumiseks ainult siis, kui see on hädavajalik – ja mitte kunagi tootmiskonteinerites. Põhimõte: kui konteiner ei pea teele kirjutama, tehke see kirjutuskaitstuks.

Samm 4: Rakendage Seccomp ja AppArmor profiilid

Vaikimisi seccomp profiilid blokeerivad juba palju ohtlikke süsteemikutseid, kuid me kohandasime neid veelgi, et lubada ainult need süsteemikutsed, mida meie rakendus tegelikult vajab. See on kompromiss, kuna see nõuab rakenduse profileerimist. Lihtsam lähenemine on kasutada Dockeri vaikimisi seccomp profiili ja seejärel lisada --security-opt seccomp=path/to/profile.json, kui vajate rangemaid reegleid. Sarnaselt saavad AppArmor profiilid piirata konteineri protsesse konkreetsete failiteede ja võimalustega. Lubasime AppArmori ja kasutasime kohandatud profiili, mis piiras juurdepääsu ainult rakenduse andmekataloogidele.

Põhjaliku juhendi nende tugevdamise sammude kohta leiate Dockeri konteinerite tugevdamine mitmeüürnikuga hostimiseks: samm-sammuline isolatsioonijuhend.

Vastandvaade: Mõnikord vajate virtuaalmasinaid

Ükskõik kui tugevdatud, jagavad konteinerid hosti kerneli. Kerneliväärtus võib korraga kogu isolatsiooni murda. Seetõttu käitavad paljud turvateadlikud platvormid konteinereid kergete virtuaalmasinate sees – iga üürnik saab oma kerneli. See lisab üldkulusid, kuid pakub riistvarataseme piiri, mida konteinerid üksi ei suuda. Kui teie üürnikud käitlevad krediitkaardiandmeid või tervisekaarte, võib hübriidne lähenemine (konteinerid virtuaalmasinates) olla õige valik. Ärge eeldage, et konteineri isolatsioon on teie ohumudeli jaoks piisav; hinnake andmete tundlikkust ja regulatiivseid nõudeid.

Isolatsioonitasemete sügavamaks võrdluseks lugege Mitmeüürnikuga Dockeri arhitektuuri kujundamine: õige isolatsioonitaseme valimine.

Kokkuvõte: Isolatsioon on virn, mitte lüliti

Parandus ei olnud üksik muudatus – see oli kihitamine: võrguisolatsioon, piiratud õigused, kirjutuskaitstud failisüsteemid ja süsteemikutsete filtreerimine. Isegi siis nõustusime, et täiuslik isolatsioon on jagatud kerneliga konteinerite puhul võimatu. Meie kõrgeima turvalisusega üürnike jaoks kolisime nad pühendatud hostidele. Õppetund: ärge usaldage vaikeväärtusi. Auditige oma Dockeri seadistust nagu rikkumine oleks juba juhtunud. Aeg lukustada on enne leket, mitte pärast.

Sources (5)