Blog
Apărarea împotriva evadării din containere: Un ghid practic pentru izolarea Docker în găzduirea multi-tenant
Aflați cum să securizați containerele Docker împotriva vulnerabilităților de evadare și a eșecurilor de izolare în medii multi-tenant, cu pași concreți și exemple.

Rezumat
Containerele Docker partajează kernelul gazdă, făcând izolația critică—în special în găzduirea multi-tenant, unde o singură evadare din container poate compromite toți chiriașii. Mulți dezvoltatori presupun că containerele sunt mașini virtuale perfect izolate, dar realitatea este diferită. Acest articol explică caracteristicile kernelului Linux din spatele izolației Docker (spații de nume, cgroups) și vectorii de atac care le amenință. Veți învăța pași practici pentru a vă întări configurația Docker: limitarea privilegiilor, utilizarea unui runtime securizat, scanarea imaginilor și implementarea segmentării rețelei. Urmând un exemplu din lumea reală al unui furnizor de găzduire multi-tenant WordPress, veți vedea cum să aplicați aceste apărări. De asemenea, acoperim avertismente precum compromisurile de performanță și utilizarea seccomp/AppArmor. Scopul este de a vă oferi o strategie robustă de izolare care previne evadarea din containere și menține chiriașii în siguranță.
Introducere
Dacă operați o platformă de găzduire multi-tenant—fie că este vorba de găzduire WordPress partajată, o aplicație SaaS sau un serviciu de mediu de dezvoltare—evadarea din container este scenariul de coșmar. O vulnerabilitate în kernel sau o configurare greșită poate permite unui chiriaș să iasă din containerul său și să acceseze datele altor chiriași sau chiar gazda. Izolarea Docker se bazează pe caracteristici ale kernelului Linux precum spațiile de nume (namespaces) și cgroups, dar configurațiile implicite sunt adesea insuficiente pentru o securitate robustă. Acest articol vă va ghida prin vectorii de atac și vă va oferi pași acționabili pentru a bloca containerele Docker, ilustrați cu un exemplu real de găzduire multi-tenant WordPress. Pentru o privire mai largă asupra orchestrației în producție, consultați ghidul nostru despre Orchestrarea aplicațiilor containerizate pregătite pentru producție.
Înțelegerea Izolării Docker
Containerele Docker utilizează spațiile de nume Linux (namespaces) pentru a oferi izolare la nivel de proces: spațiile de nume PID izolează arborii de procese, spațiile de nume de rețea separă interfețele de rețea, spațiile de nume de montare izolează montările sistemului de fișiere, iar spațiile de nume de utilizator permit maparea utilizatorului root al containerului la un utilizator gazdă ne-privilegiat. Grupurile de control (cgroups) limitează utilizarea resurselor precum CPU, memoria și I/O pe disc. Aceste caracteristici creează împreună un „sandbox” în jurul fiecărui container. Cu toate acestea, spre deosebire de o mașină virtuală care rulează un kernel separat, containerele partajează kernelul gazdă. Aceasta înseamnă că o vulnerabilitate în kernel (de ex., CVE-2022-0492) poate fi exploatată pentru a ieși din izolarea spațiului de nume al containerului. În plus, configurările greșite, cum ar fi rularea containerelor ca root în interiorul containerului, acordarea tuturor capabilităților containerului sau neabandonarea capabilităților Linux inutile, pot lărgi suprafața de atac.
Vectori de Atac
Vectorii comuni de atac includ:
- Exploatări ale kernelului: Exploatarea unui bug în kernelul gazdă pentru a obține acces la gazdă.
- Containere privilegiate: Rularea cu
--privilegedacordă toate capabilitățile și ocolește majoritatea izolării. - Abuz de capabilități: Chiar și fără modul complet privilegiat, un container cu capabilități periculoase precum
CAP_SYS_ADMINsauCAP_NET_ADMINpoate monta sisteme de fișiere sau manipula setările de rețea. - Practici nesigure ale imaginilor: Utilizarea imaginilor de bază cu vulnerabilități cunoscute sau includerea de instrumente inutile precum compilatoare sau interpretoare de shell.
- Spații de nume de montare partajate: Montarea directoarelor gazdă în containere poate permite evadarea dacă nu sunt doar în mod read-only.
Pași Practici de Securitate
1. Rulați Containerele ca Utilizator Non-Root
Implicit, Docker rulează containerele ca root în interiorul containerului. Dacă un atacator obține acces root în interiorul containerului, are mai multă influență. Creați un utilizator în Dockerfile și utilizați directiva USER. De asemenea, evitați utilizarea flag-ului --user în Docker Compose pentru a mapa la un utilizator gazdă arbitrar, dacă este posibil.
2. Renunțați la Toate Capabilitățile și Adăugați Doar Cele Necesare
Capabilitățile Linux descompun privilegiile superutilizatorului în unități mai mici. În Docker Compose, utilizați cap_drop: ALL apoi cap_add doar cele necesare (de ex., NET_BIND_SERVICE). Evitați capabilitățile periculoase precum SYS_ADMIN, NET_ADMIN, SYS_PTRACE.
3. Utilizați Sistemul de Fișiere Root Read-Only
Setați read_only: true în definiția containerului. Acest lucru împiedică atacatorii să scrie în sistemul de fișiere al containerului. Dacă aplicația dvs. trebuie să scrie fișiere temporare, montați un volum tmpfs în acea locație.
4. Activați Remaparea Spațiului de Nume al Utilizatorilor
Remaparea spațiului de nume al utilizatorilor mapează utilizatorul root al containerului la un utilizator gazdă non-root. Aceasta adaugă un strat de izolare, deoarece chiar dacă un root al containerului evadează, acesta va avea privilegiile utilizatorului remapat. Activați-o în /etc/docker/daemon.json cu "userns-remap": "default". Fiți conștienți că acest lucru poate complica permisiunile volumelor. Pentru mai multe detalii, consultați Stăpânirea Izolării Docker pentru Găzduire Web Securizată și Eficientă.
5. Aplicați Profiluri Seccomp și AppArmor/AppArmor
Seccomp restricționează apelurile de sistem pe care un container le poate face. Docker oferă un profil seccomp implicit care blochează apelurile de sistem periculoase. Puteți, de asemenea, să creați profiluri personalizate. Similar, AppArmor (sau SELinux) oferă control de acces obligatoriu. Utilizați AppArmor pentru a limita containerul la un set minim de operațiuni permise. Profilul de securitate poate fi setat prin security_opt în Docker Compose.
6. Utilizați Imagini de Bază Minime și Scanați pentru Vulnerabilități
Alegeți imagini mici precum Alpine sau Distroless, care au o suprafață de atac mai mică. Scanați periodic imaginile cu instrumente precum Docker Scout, Trivy sau Clair. Integrați scanarea în pipeline-ul dvs. CI/CD pentru a preveni implementarea imaginilor vulnerabile.
7. Segmentarea Rețelei cu Rețele Bridge Personalizate
Creați rețele bridge separate pentru fiecare chiriaș sau nivel de aplicație. Aceasta limitează traficul est-vest. În Docker Compose, definiți rețele și izolați serviciile. Utilizați internal: true dacă un serviciu nu are nevoie de acces la Internet. Regulile de firewall pe gazdă restricționează în continuare traficul inter-container.
8. Limitați Resursele cu Cgroups
Setați limitele de CPU și memorie în Docker Compose utilizând deploy.resources.limits. Aceasta previne ca un container compromis să lanseze un atac de epuizare a resurselor. În plus, setați kernel_memory și memory_reservation pentru un control mai fin.
Exemplu din Lumea Reală: Găzduire Multi-Tenant WordPress cu Docker Compose
Considerați un scenariu în care găzduiți mai multe site-uri WordPress pentru clienți diferiți, fiecare în propriul container Docker. O configurație nesecurizată ar putea arăta astfel:
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:
Această configurație este vulnerabilă: containerul WordPress rulează ca root în interior, are toate capabilitățile (deoarece nu sunt renunțate), montează un director gazdă cu acces la scriere și are acces neîngrădit la rețea.
Acum să o întărim:
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:
Îmbunătățiri cheie:
- Ambele containere rulează ca utilizatori non-root (
www-datașimysql). - Toate capabilitățile sunt renunțate, doar
NET_BIND_SERVICEeste adăugată. - Sistemul de fișiere WordPress este read-only, cu excepția unui montaj tmpfs și a unui volum de încărcări.
- Sunt aplicate profiluri Seccomp și AppArmor (ar trebui să furnizați profiluri personalizate).
- Rețele separate izolează web-ul de baza de date, cu rețeaua bazei de date internă.
- Limitele de resurse previn epuizarea resurselor.
Pentru mai multe informații despre întărirea specifică WordPress cu Docker, consultați Docker pentru WordPress: De ce containerele izolate schimbă totul.
Avertismente
- Remaparea Spațiului de Nume al Utilizatorilor: Deși puternică, aceasta perturbă montarea volumelor deoarece UID-ul gazdă remapat nu este același cu UID-ul containerului. S-ar putea să fie necesar să creați în prealabil directoare cu permisiunile corecte sau să utilizați volume Docker cu suport pentru remapare.
- Profiluri Seccomp/AppArmor: Profilurile personalizate necesită înțelegerea apelurilor de sistem și a modelelor de acces la fișiere ale aplicației dvs. Profilurile excesiv de restrictive pot perturba funcționalitatea. Testați temeinic.
- Performanță: Straturile suplimentare de securitate precum seccomp și AppArmor au un impact minim, dar limitele de resurse și sistemele de fișiere read-only pot afecta aplicațiile cu scrieri intensive.
- Complexitatea Orchestrației: Într-un mediu multi-tenant, gestionarea fișierelor Docker Compose per chiriaș poate deveni dificilă. Luați în considerare utilizarea unui instrument de orchestrație de nivel superior precum Kubernetes, dar acesta introduce propriile considerații de securitate.
Concluzie
Evadarea din container este o amenințare reală în găzduirea multi-tenant Docker, dar poate fi prevenită. Prin înțelegerea mecanismelor de izolare și aplicarea apărării în profunzime—renunțarea la capabilități, rularea ca non-root, activarea spațiilor de nume ale utilizatorilor, seccomp, AppArmor, segmentarea rețelei și scanarea periodică a imaginilor—puteți reduce dramatic riscul. Amintiți-vă că setările implicite ale Docker nu sunt pregătite pentru producție pentru sarcini de lucru multi-tenant. Implementați acești pași astăzi pentru a vă proteja chiriașii și infrastructura. Pentru o prezentare generală cuprinzătoare a celor mai bune practici de securitate Docker, consultați Securizarea aplicațiilor dvs. web cu Docker: Un ghid practic pentru izolare și cele mai bune practici.
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®

