Emuārs
Uzticības maldība: Kā mūsu vairāku nomnieku Docker iestatījums nopludināja datus (un kā mēs to izlabojām)
Uzziniet, kā vienas komandas naivs Docker iestatījums izraisīja starpnomnieku datu noplūdi un kā slāņota izolācijas stratēģija to novērsa.
Kopsavilkums
Docker konteineri pēc noklusējuma nav izolēti — tie koplieto resursdatora kodolu, un bez apzinātas konfigurācijas nomnieki var traucēt viens otram. Šis raksts aplūko reālu scenāriju, kurā vairāku nomnieku mitināšanas pakalpojumu sniedzējs atklāja, ka klientu konteineri var piekļūt viens otra datubāzēm koplietotā tīklošanas un vāju drošības noklusējumu dēļ. Mēs parādām soli pa solim veiktās izmaiņas, kas novērsa pārkāpumu: katra nomnieka lietotāja definēti tīkli, lietotāji, kas nav root, atceltas spējas, tikai lasāmas failu sistēmas un seccomp profili. Bieži tiek pieņemts, ka konteineri pēc būtības nodrošina spēcīgu izolāciju; mēs to apstrīdam, izskaidrojot, kāpēc virtuālās mašīnas joprojām piedāvā stingrāku robežu un kad apsvērt hibrīda pieeju. Secinājums uzsver, ka izolācija ir slāņota darbība, nevis viena atzīme.
Incidents: kad konteineri pārāk daudz runā
Jūs esat iestatījuši Docker vienā resursdatorā, lai palaistu vairākas klientu tīmekļa vietnes. Katram klientam ir savs konteiners — glīta, izolēta vide, vai ne? Tā mēs domājām. Līdz kārtējā drošības auditā atklājās, ka Klienta A konteiners lasa Klienta B konteinera MySQL ligzdu tajā pašā resursdatorā. Tie koplietoja noklusējuma bridge tīklu. Vēl ļaunāk, konteineri darbojās kā root, tāpēc uzbrucējs, kurš kompromitēja vienu, varēja manipulēt ar resursdatora Docker ligzdu vai cita konteinera failu sistēmu. Pārkāpums nebija sarežģīts eksploits; tā bija pamata nepareiza konfigurācija. Dati noplūda. Uzticība izkusa.
Nepaveikšanās scenārijs nav rets. Daudzas komandas pieņem, ka Docker vārdu telpas un cgroups automātiski norobežo nomniekus, taču tās nenovērtē, cik daudz bēgšanas lūku pēc noklusējuma paliek atvērtas. Noklusējuma tiltu tīkli nenodrošina tīkla izolāciju starp konteineriem. Darbošanās kā root piešķir konteineram vairāk jaudas nekā nepieciešams. Un bez skaidriem resursu ierobežojumiem viens trokšņains kaimiņš var atņemt CPU vai atmiņu citiem.
1. solis: pārtrauciet koplietot vienu tīklu
Mūsu pirmais labojums bija piešķirt katram nomniekam savu lietotāja definētu Docker tīklu. Tas neļauj konteineriem sasniegt viens otru, ja vien jūs tos tieši nesavienojat. Mēs izveidojām skriptu, kas katram nomniekam izveido veltītu tīklu un pievieno tam viņu lietojumprogrammas konteineru. Datu bāzes konteiners atrodas tajā pašā nomnieka tīklā, bet mēs pievienojām arī iekšējo tīklu tikai iekšējai komunikācijai starp nomniekiem. Vairs nav starpnomnieku izspiegošanas.
Mēs arī izolējām datubāzes, palaižot tās atsevišķos konteineros vienā nomnieka tīklā, izmantojot atsevišķus datu apjomus. Tas nodrošināja, ka pat tad, ja uzbrucējs iekļuva lietotnes konteinerā, tas nevarēja noklausīties cita nomnieka datubāzes trafiku.
Lai dziļāk iedziļinātos tīkla izolācijas stratēģijās, skatiet Praktisks Docker izolācijas drošības kontrolsaraksts vairāku nomnieku mitināšanai.
2. solis: atmetiet nevajadzīgās privilēģijas
Pēc noklusējuma Docker konteineri darbojas ar ierobežotu Linux spēju kopu, taču tām joprojām ir vairāk nekā lielākā daļa lietojumprogrammu nepieciešams. Mūsu konteineri darbojās kā root, kas ļāva procesiem iekšpusē veikt darbības, piemēram, montēt failu sistēmas vai mainīt kodola parametrus. Mēs pārgājām uz lietojumprogrammas palaišanu kā lietotājs, kas nav root, konteinerā (izmantojot USER direktīvu Docker failā) un atmetām visas spējas, izņemot tās, kas ir absolūti nepieciešamas. Tipiskai tīmekļa lietotnei tās var būt tikai NET_BIND_SERVICE (lai piesaistītos portiem zem 1024) un CHOWN (lai rakstītu direktorijos). Mēs arī pievienojām --security-opt no-new-privileges, lai novērstu privilēģiju eskalāciju.
Šis solis vien novērsa daudzus izplatītus konteineru bēgšanas vektorus. Uzbrucējs, kurš kompromitē tīmekļa serveri, nevar instalēt pakotnes, modificēt sistēmas bināros failus vai piekļūt resursdatora Docker ligzdai, jo procesam trūkst CAP_SYS_ADMIN vai CAP_DAC_OVERRIDE spēju.
3. solis: bloķējiet failu sistēmu
Rakstāmās failu sistēmas ir biežs uzbrukumu mērķis. Mēs padarījām saknes failu sistēmu tikai lasāmu (--read-only) visiem konteineriem un pēc tam pievienojām pagaidu failu sistēmas (tmpfs) direktorijiem, kuriem nepieciešama rakstīšanas piekļuve, piemēram, /tmp un lietojumprogrammas kešatmiņas direktorijam. Tas neļauj uzbrucējam modificēt lietojumprogrammas kodu vai saglabāt ļaunprātīgus bināros failus.
Turklāt mēs izmantojām Docker --mount opciju, lai saistītu sensitīvus direktorijus, piemēram, Docker ligzdu, tikai tad, kad tas ir absolūti nepieciešams — un nekad ražošanas konteineros. Princips: ja konteineram nav jāraksta ceļā, padariet to tikai lasāmu.
4. solis: pielietojiet Seccomp un AppArmor profilus
Noklusējuma seccomp profili jau bloķē daudzus bīstamus sistēmas izsaukumus, taču mēs tos vēl pielāgojām, lai iekļautu baltajā sarakstā tikai tos sistēmas izsaukumus, kas mūsu lietojumprogrammai patiešām ir nepieciešami. Tas ir kompromiss, jo tas prasa lietojumprogrammas profilēšanu. Vienkāršāka pieeja ir izmantot Docker noklusējuma seccomp profilu un pēc tam pievienot --security-opt seccomp=path/to/profile.json, ja nepieciešami stingrāki noteikumi. Līdzīgi AppArmor profili var ierobežot konteineru procesus līdz konkrētiem failu ceļiem un spējām. Mēs iespējojām AppArmor un izmantojām pielāgotu profilu, kas ierobežoja piekļuvi tikai lietojumprogrammas datu direktorijiem.
Lai iegūtu visaptverošu ceļvedi par šiem stiprināšanas soļiem, skatiet Docker konteineru stiprināšana vairāku nomnieku mitināšanai: izolācijas ceļvedis soli pa solim.
Pretējs viedoklis: dažreiz jums ir nepieciešamas virtuālās mašīnas
Neatkarīgi no tā, cik stiprināti, konteineri koplieto resursdatora kodolu. Kodola ievainojamība var vienlaikus salauzt visu izolāciju. Tāpēc daudzas drošības apzinātas platformas palaiž konteinerus vieglu virtuālo mašīnu iekšpusē — katrs nomnieks saņem savu kodolu. Tas rada papildu slogu, bet nodrošina aparatūras līmeņa robežu, ko konteineri vieni paši nevar. Ja jūsu nomnieki apstrādā kredītkaršu datus vai veselības ierakstus, hibrīda pieeja (konteineri virtuālajās mašīnās) var būt pareizā izvēle. Nepieņemiet, ka konteineru izolācija ir pietiekama jūsu draudu modelim; novērtējiet datu jutīgumu un normatīvās prasības.
Lai dziļāk salīdzinātu izolācijas līmeņus, izlasiet Daudznomnieku Docker arhitektūras projektēšana: piemērotā izolācijas līmeņa izvēle.
Secinājums: izolācija ir kaudze, nevis slēdzis
Labojums nebija viena izmaiņa — tā bija slāņošana: tīkla izolācija, ierobežotas privilēģijas, tikai lasāmas failu sistēmas un sistēmas izsaukumu filtrēšana. Pat tad mēs pieņēmām, ka perfekta izolācija nav iespējama ar koplietota kodola konteineriem. Mūsu visaugstākās drošības nomniekiem mēs tos pārvietojām uz atsevišķiem resursdatoriem. Mācība: neuzticieties nevienam noklusējumam. Auditujiet savu Docker iestatījumu tā, it kā pārkāpums jau būtu noticis. Laiks bloķēt ir pirms noplūdes, nevis pēc tam.


