Blog
Obramba pred izhodom iz kontejnerja: Praktični vodnik po Dockerjevi izolaciji za gostovanje več najemnikov
Naučite se zaščititi Dockerjeve kontejnerje pred ranljivostmi izhoda in napakami pri izolaciji v okoljih z več najemniki s konkretnimi koraki in primeri.

Povzetek
Dockerjevi kontejnerji delijo gostiteljsko jedro, zato je izolacija ključna – še posebej pri gostovanju več najemnikov, kjer lahko en sam izhod iz kontejnerja ogrozi vse najemnike. Mnogi razvijalci domnevajo, da so kontejnerji popolnoma izolirani virtualni stroji, vendar je resničnost drugačna. Ta članek pojasnjuje funkcije gostiteljskega jedra Linux, ki stojijo za Dockerjevo izolacijo (imena prostorov, cgroups), in vektorje napadov, ki jih ogrožajo. Naučili se boste praktičnih korakov za utrditev vaše Dockerjeve nastavitve: omejevanje privilegijev, uporaba varnega zagona, skeniranje slik in izvajanje omrežne segmentacije. Z uporabo primera iz resničnega sveta ponudnika gostovanja WordPressa za več najemnikov boste videli, kako uporabiti te obrambe. Pokrivamo tudi opozorila, kot so kompromisi glede zmogljivosti in uporaba seccomp/AppArmor. Cilj je zagotoviti vam robustno strategijo izolacije, ki preprečuje izhode iz kontejnerjev in ohranja vaše najemnike varne.
Uvod
Če upravljate platformo za gostovanje z več najemniki – ne glede na to, ali gre za skupno gostovanje WordPressa, aplikacijo SaaS ali storitev razvojnega okolja – je izhod iz kontejnerja nočna mora. Ranljivost v jedru ali napačna konfiguracija lahko enemu najemniku omogoči izhod iz njegovega kontejnerja in dostop do podatkov drugih najemnikov ali samega gostitelja. Dockerjeva izolacija se zanaša na funkcije jedra Linux, kot so imena prostorov in cgroups, vendar izhodiščne nastavitve pogosto niso zadostne za robustno varnost. Ta članek vas bo popeljal skozi vektorje napadov in ponudil uporabne korake za zaklepanje vaših Dockerjevih kontejnerjev, ponazorjene s primerom gostovanja WordPressa za več najemnikov iz resničnega sveta. Za širši pogled na produkcijsko orkestracijo si oglejte naš vodnik o Orkestraciji produkcijsko pripravljenih kontejneriziranih aplikacij.
Razumevanje Dockerjeve izolacije
Dockerjevi kontejnerji uporabljajo imena prostorov Linux za zagotavljanje izolacije na ravni procesov: imena prostorov PID izolirajo drevesa procesov, omrežna imena prostorov ločujejo omrežne vmesnike, imena prostorov za montažo izolirajo datotečne sisteme, imena prostorov uporabnikov pa omogočajo preslikavo korenskega uporabnika kontejnerja na neprivilegiranega gostiteljskega uporabnika. Kontrolne skupine (cgroups) omejujejo uporabo virov, kot so CPU, pomnilnik in I/O diska. Te funkcije skupaj ustvarijo »peskovnik« okoli vsakega kontejnerja. Vendar, za razliko od virtualnega stroja, ki uporablja ločeno jedro, kontejnerji delijo gostiteljsko jedro. To pomeni, da lahko ranljivost v jedru (npr. CVE-2022-0492) izkoristite za izhod iz izolacije imen prostorov kontejnerja. Poleg tega lahko napačne konfiguracije, kot je zagon kontejnerjev kot korenski uporabnik znotraj kontejnerja, dodelitev vseh zmožnosti kontejnerju ali nedopuščanje nepotrebnih zmožnosti Linux, razširijo površino napada.
Vektorji napadov
Pogosti vektorji napadov vključujejo:
- Izkoristki jedra: Izkoristek napake v gostiteljskem jedru za pridobitev dostopa do gostitelja.
- Privilegirani kontejnerji: Zagon s
--privilegeddodeli vse zmožnosti in obide večino izolacije. - Zloraba zmožnosti: Tudi brez polnega privilegiranega načina lahko kontejner z nevarnimi zmožnostmi, kot sta
CAP_SYS_ADMINaliCAP_NET_ADMIN, montira datotečne sisteme ali manipulira z omrežnimi nastavitvami. - Nevarni postopki slik: Uporaba osnovnih slik z znanimi ranljivostmi ali vključevanje nepotrebnih orodij, kot so prevajalniki ali interpretatorji lupine.
- Deljena imena prostorov za montažo: Montiranje gostiteljskih map v kontejnerje lahko omogoči izhod, če niso samo za branje.
Praktični varnostni koraki
1. Zagon kontejnerjev kot neprivilegiran uporabnik
Privzeto Docker zaganja kontejnerje kot korenski uporabnik znotraj kontejnerja. Če napadalec pridobi korenski dostop znotraj kontejnerja, ima več možnosti. Ustvarite uporabnika v svojem Dockerfile in uporabite direktivo USER. Izogibajte se tudi uporabi zastavice --user v Docker Compose za preslikavo na poljubnega gostiteljskega uporabnika, če je mogoče.
2. Zavrzi vse zmožnosti in dodaj samo potrebne
Zmožnosti Linux razdelijo privilegije superuporabnika na manjše enote. V Docker Compose uporabite cap_drop: ALL, nato pa cap_add samo zahtevane (npr. NET_BIND_SERVICE). Izogibajte se nevarnim zmožnostim, kot so SYS_ADMIN, NET_ADMIN, SYS_PTRACE.
3. Uporaba korenskega datotečnega sistema samo za branje
Nastavite read_only: true v definiciji vašega kontejnerja. To preprečuje napadalcem pisanje v datotečni sistem kontejnerja. Če vaša aplikacija potrebuje pisanje začasnih datotek, namestite tmpfs volumen na to lokacijo.
4. Omogočite preslikavo imen prostorov uporabnikov
Preslikava imen prostorov uporabnikov preslika korenskega uporabnika kontejnerja na neprivilegiranega gostiteljskega uporabnika. To dodaja plast izolacije, saj tudi če korenski uporabnik kontejnerja izstopi, bo imel privilegije preslikanega uporabnika. Omogočite ga v /etc/docker/daemon.json z "userns-remap": "default". Zavedajte se, da to lahko zaplete dovoljenja za volumne. Za več podrobnosti glejte Obvladovanje Dockerjeve izolacije za varno in učinkovito spletno gostovanje.
5. Uporabite profile Seccomp in AppArmor/AppArmor
Seccomp omeji sistemske klice, ki jih lahko izvede kontejner. Docker zagotavlja privzeti profil seccomp, ki blokira nevarne sistemske klice. Ustvarite lahko tudi lastne profile. Podobno AppArmor (ali SELinux) zagotavlja obvezno nadzor dostopa. Uporabite AppArmor za omejitev vašega kontejnerja na minimalni nabor dovoljenih operacij. Varnostni profil lahko nastavite preko security_opt v Docker Compose.
6. Uporabite minimalne osnovne slike in skenirajte za ranljivosti
Izberite majhne slike, kot sta Alpine ali Distroless, ki imajo manjšo površino napada. Redno skenirajte slike z orodji, kot so Docker Scout, Trivy ali Clair. Vključite skeniranje v svoj cevovod CI/CD, da preprečite uvajanje ranljivih slik.
7. Omrežna segmentacija z mostičnimi omrežji po meri
Ustvarite ločena mostična omrežja za vsakega najemnika ali plast aplikacije. To omejuje promet med vzhodom in zahodom. V Docker Compose definirajte omrežja in izolirajte storitve. Uporabite internal: true, če storitev ne potrebuje izhodnega dostopa do interneta. Pravila požarnega zidu na gostitelju dodatno omejujejo promet med kontejnerji.
8. Omejite vire z cgroups
Nastavite omejitve CPU in pomnilnika v Docker Compose z uporabo deploy.resources.limits. To preprečuje, da bi ogrožen kontejner sprožil napad izčrpavanja virov. Poleg tega nastavite kernel_memory in memory_reservation za natančnejši nadzor.
Primer iz resničnega sveta: Gostovanje WordPressa za več najemnikov z Docker Compose
Razmislite o scenariju, kjer gostite več spletnih mest WordPress za različne stranke, vsako v svojem Dockerjevem kontejnerju. Nevarna nastavitev bi lahko izgledala takole:
version: '3'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- ./wp-content:/var/www/html/wp-content
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_ROOT_PASSWORD: somewordpress
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Ta nastavitev je ranljiva: kontejner WordPress deluje kot korenski uporabnik znotraj, ima vse zmožnosti (saj nobena ni zavrnjena), montira gostiteljsko mapo z zapisovalnim dostopom in ima neomejen omrežni dostop.
Zdaj jo utrdimo:
version: '3'
services:
wordpress:
image: wordpress:latest
user: www-data
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
read_only: true
tmpfs:
- /var/www/html/wp-content/plugins
security_opt:
- seccomp=seccomp-profile.json
- apparmor=wordpress-profile
networks:
- frontend
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wp-uploads:/var/www/html/wp-content/uploads
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
db:
image: mysql:5.7
user: mysql
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
networks:
- backend
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_ROOT_PASSWORD: somewordpress
volumes:
- db_data:/var/lib/mysql
deploy:
resources:
limits:
cpus: '0.25'
memory: 128M
networks:
frontend:
driver: bridge
internal: false
backend:
driver: bridge
internal: true
volumes:
wp-uploads:
db_data:
Ključne izboljšave:
- Oba kontejnerja delujeta kot neprivilegirana uporabnika (
www-datainmysql). - Vse zmožnosti zavrnjene, dodana samo
NET_BIND_SERVICE. - Datotečni sistem WordPress je samo za branje, razen za montažo tmpfs in volumen za nalaganje.
- Uporabljeni so profili Seccomp in AppArmor (morali bi zagotoviti lastne profile).
- Ločena omrežja izolirajo splet od podatkovne baze, pri čemer je omrežje podatkovne baze interno.
- Omejitve virov preprečujejo izčrpavanje virov.
Več o utrjevanju Dockerja za WordPress si oglejte v Docker za WordPress: Zakaj izolirani kontejnerji spremenijo vse.
Opozorila
- Preslikava imen prostorov uporabnikov: Čeprav je močna, pokvari montažo volumnov, ker ponovno preslikani gostiteljski UID ni enak kontejnerskemu UID. Morda boste morali vnaprej ustvariti mape s pravilnimi dovoljenji ali uporabiti Docker volumnove s podporo za preslikavo.
- Profili Seccomp/AppArmor: Profili po meri zahtevajo razumevanje vzorcev sistemskih klicev in dostopa do datotek vaše aplikacije. Preveč omejevalni profili lahko povzročijo napake v delovanju. Temeljito testirajte.
- Zmogljivost: Dodatne varnostne plasti, kot sta seccomp in AppArmor, imajo minimalno režijo, vendar lahko omejitve virov in datotečni sistemi samo za branje vplivajo na aplikacije z veliko pisanja.
- Zapletenost orkestracije: V okolju z več najemniki lahko upravljanje datotek Docker Compose na najemnika postane okorno. Razmislite o uporabi orodja za orkestracijo višje ravni, kot je Kubernetes, vendar to uvaja lastne varnostne pomisleke.
Zaključek
Izhod iz kontejnerja je resnična grožnja pri gostovanju Dockerja za več najemnikov, vendar je preprečljiv. Z razumevanjem mehanizmov izolacije in uporabo obrambe v globino – zavračanje zmožnosti, zagon kot neprivilegiran uporabnik, omogočanje imen prostorov uporabnikov, seccomp, AppArmor, omrežna segmentacija in redno skeniranje slik – lahko znatno zmanjšate tveganje. Ne pozabite, da privzete nastavitve Dockerja niso pripravljene za produkcijo za delovne obremenitve z več najemniki. Uvedite te korake danes, da zaščitite svoje najemnike in svojo infrastrukturo. Za celovit pregled najboljših praks za varnost Dockerja glejte Zavarujte svoje spletne aplikacije z Dockerjem: Praktični vodnik po izolaciji in najboljših praksah.
Sources (5)
- Docker and Container Isolation - Medium
- What is container isolation? Mechanisms, limitations, and secure runtimes | Blog - Northflank
- Container Isolation Explained for Kubernetes and Beyond - Edera
- Docker Security: 5 Risks and 12 Best Practices for Securing Your Containers - Tigera.io
- 9 Security Best Practices for Docker Containers - Kinsta®

