Blog
Verdedigen tegen Container Escape: Een Praktische Gids voor Docker-isolatie voor Multi-Tenant Hosting
Leer hoe u Docker-containers beveiligt tegen escape-kwetsbaarheden en isolatiefouten in multi-tenant omgevingen met concrete stappen en voorbeelden.

Samenvatting
Docker-containers delen de host-kernel, waardoor isolatie cruciaal is—vooral in multi-tenant hosting waar een enkele container escape alle tenants kan compromitteren. Veel ontwikkelaars gaan ervan uit dat containers perfect geïsoleerde virtuele machines zijn, maar de realiteit is anders. Dit artikel legt de Linux-kernelfuncties achter Docker-isolatie (namespaces, cgroups) en de aanvalsvectoren die deze bedreigen uit. U leert praktische stappen om uw Docker-setup te versterken: privileges beperken, een veilige runtime gebruiken, images scannen en netwerksegmentatie implementeren. Door een real-world voorbeeld van een multi-tenant WordPress-hostingprovider te volgen, ziet u hoe u deze verdedigingen toepast. We behandelen ook kanttekeningen zoals prestatieafwegingen en het gebruik van seccomp/AppArmor. Het doel is om u een robuuste isolatiestrategie te geven die container escapes voorkomt en uw tenants veilig houdt.
Introductie
Als u een multi-tenant hostingplatform runt—of het nu gedeelde WordPress-hosting is, een SaaS-applicatie of een dev-omgevingsservice—is container escape het nachtmerriescenario. Een kwetsbaarheid in de kernel of een verkeerde configuratie kan een tenant ertoe aanzetten om uit hun container te breken en toegang te krijgen tot de gegevens van andere tenants of de host zelf. Docker's isolatie is afhankelijk van Linux-kernelfuncties zoals namespaces en cgroups, maar out-of-the-box configuraties zijn vaak onvoldoende voor robuuste beveiliging. Dit artikel leidt u door de aanvalsvectoren en biedt bruikbare stappen om uw Docker-containers te vergrendelen, geïllustreerd met een real-world multi-tenant WordPress-voorbeeld. Voor een breder overzicht van productie-orkestratie, zie onze gids over Orchestrating Production-Ready Containerized Applications.
Docker-isolatie Begrijpen
Docker-containers gebruiken Linux-namespaces om procesniveau-isolatie te bieden: PID-namespaces isoleren processen, netwerk-namespaces scheiden netwerkinterfaces, mount-namespaces isoleren bestandssysteem-mounts en gebruikers-namespaces maken het mogelijk om de container-root toe te wijzen aan een niet-geprivilegieerde hostgebruiker. Control groups (cgroups) beperken het gebruik van bronnen zoals CPU, geheugen en schijf-I/O. Deze functies creëren samen een "sandbox" rond elke container. Echter, in tegenstelling tot een virtuele machine die een aparte kernel draait, delen containers de host-kernel. Dit betekent dat een kwetsbaarheid in de kernel (bijv. CVE-2022-0492) kan worden uitgebuit om uit de namespace-isolatie van de container te breken. Bovendien kunnen verkeerde configuraties zoals het draaien van containers als root binnen de container, het geven van alle capabilities aan de container, of het niet laten vallen van onnodige Linux-capabilities het aanvalsoppervlak vergroten.
Aanvalsvectoren
Veelvoorkomende aanvalsvectoren zijn:
- Kernel-exploits: Het uitbuiten van een bug in de host-kernel om toegang tot de host te krijgen.
- Geprivilegieerde containers: Draaien met
--privilegedverleent alle capabilities en omzeilt de meeste isolatie. - Capability-misbruik: Zelfs zonder volledige geprivilegieerde modus kan een container met gevaarlijke capabilities zoals
CAP_SYS_ADMINofCAP_NET_ADMINbestandssystemen mounten of netwerkinstellingen manipuleren. - Onveilige image-praktijken: Het gebruik van basisimages met bekende kwetsbaarheden of het opnemen van onnodige tools zoals compilers of shell-interpreters.
- Gedeelde mount-namespaces: Het mounten van host-directories in containers kan ontsnapping mogelijk maken als ze niet read-only zijn.
Praktische Beveiligingsstappen
1. Containers Draaien als Niet-Root Gebruiker
Standaard draait Docker containers als root binnen de container. Als een aanvaller root binnen de container verkrijgt, hebben ze meer invloed. Maak een gebruiker aan in uw Dockerfile en gebruik de USER-richtlijn. Vermijd ook het gebruik van de --user-vlag in Docker Compose om toe te wijzen aan een willekeurige hostgebruiker indien mogelijk.
2. Alle Capabilities Laten Vallen en Alleen Nodige Toevoegen
Linux-capabilities breken superuser-privileges op in kleinere eenheden. Gebruik in Docker Compose cap_drop: ALL en voeg vervolgens alleen de benodigde cap_add toe (bijv. NET_BIND_SERVICE). Vermijd gevaarlijke capabilities zoals SYS_ADMIN, NET_ADMIN, SYS_PTRACE.
3. Read-Only Root Bestandssysteem Gebruiken
Stel read_only: true in uw containerdefinitie in. Dit voorkomt dat aanvallers naar het bestandssysteem van de container schrijven. Als uw app tijdelijke bestanden moet schrijven, mount dan een tmpfs-volume op die locatie.
4. User Namespace Remapping Inschakelen
User namespace remapping wijst de root-gebruiker van de container toe aan een niet-geprivilegieerde hostgebruiker. Dit voegt een isolatielaag toe, want zelfs als een container root ontsnapt, hebben ze de privileges van de opnieuw toegewezen gebruiker. Schakel dit in /etc/docker/daemon.json in met "userns-remap": "default". Houd er rekening mee dat dit volume-permissies kan compliceren. Voor meer details, zie Mastering Docker Isolation for Secure and Efficient Web Hosting.
5. Seccomp en AppArmor/AppArmor Profielen Toepassen
Seccomp beperkt de systeemaanroepen die een container kan maken. Docker biedt een standaard seccomp-profiel dat gevaarlijke syscalls blokkeert. U kunt ook aangepaste profielen maken. Op dezelfde manier biedt AppArmor (of SELinux) verplichte toegangscontrole. Gebruik AppArmor om uw container te beperken tot een minimale set toegestane bewerkingen. Het beveiligingsprofiel kan worden ingesteld via security_opt in Docker Compose.
6. Minimale Basisimages Gebruiken en Scannen op Kwetsbaarheden
Kies kleine images zoals Alpine of Distroless die een kleiner aanvalsoppervlak hebben. Scan regelmatig images met tools zoals Docker Scout, Trivy of Clair. Integreer scannen in uw CI/CD-pipeline om te voorkomen dat kwetsbare images worden geïmplementeerd.
7. Netwerksegmentatie met Aangepaste Bridge-netwerken
Maak aparte bridge-netwerken voor elke tenant of applicatietier. Dit beperkt het oost-west verkeer. Definieer in Docker Compose netwerken en isoleer services. Gebruik internal: true als een service geen uitgaand internetverkeer nodig heeft. Firewallregels op de host beperken verder het verkeer tussen containers.
8. Resources Beperken met Cgroups
Stel CPU- en geheugenlimieten in Docker Compose in met deploy.resources.limits. Dit voorkomt dat een gecompromitteerde container een aanval met uitputting van bronnen lanceert. Stel bovendien kernel_memory en memory_reservation in voor fijnere controle.
Real-World Voorbeeld: Multi-Tenant WordPress Hosting met Docker Compose
Beschouw een scenario waarin u meerdere WordPress-sites voor verschillende klanten host, elk in zijn eigen Docker-container. Een onveilige opstelling zou er als volgt uit kunnen zien:
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:
Deze opstelling is kwetsbaar: de WordPress-container draait als root binnenin, heeft alle capabilities (aangezien er geen zijn gedropt), mount een hostdirectory met schrijftoegang en heeft onbeperkte netwerktoegang.
Laten we het nu versterken:
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:
Belangrijke verbeteringen:
- Beide containers draaien als niet-root gebruikers (
www-dataenmysql). - Alle capabilities gedropt, alleen
NET_BIND_SERVICEtoegevoegd. - WordPress-bestandssysteem is read-only, behalve een tmpfs-mount en een uploads-volume.
- Seccomp- en AppArmor-profielen zijn toegepast (u zou aangepaste profielen moeten leveren).
- Aparte netwerken isoleren web van database, met het database-netwerk intern.
- Resource-limieten voorkomen uitputting van bronnen.
Voor meer informatie over WordPress-specifieke Docker-versterking, zie Docker for WordPress: Why Isolated Containers Change Everything.
Kanttekeningen
- User Namespace Remapping: Hoewel krachtig, breekt het volume-mounting omdat de opnieuw toegewezen host UID niet hetzelfde is als de container UID. Mogelijk moet u directories vooraf aanmaken met de juiste permissies of Docker-volumes gebruiken met remapping-ondersteuning.
- Seccomp/AppArmor Profielen: Aangepaste profielen vereisen begrip van de systeemaanroep- en bestandsaccess-patronen van uw applicatie. Te restrictieve profielen kunnen functionaliteit breken. Test grondig.
- Prestaties: Extra beveiligingslagen zoals seccomp en AppArmor hebben minimale overhead, maar resource-limieten en read-only bestandssystemen kunnen schrijftoepassingen met veel schrijven beïnvloeden.
- Orchestratie Complexiteit: In een multi-tenant omgeving kan het beheren van per-tenant Docker Compose-bestanden onhandelbaar worden. Overweeg een hoger niveau orchestratietool zoals Kubernetes te gebruiken, maar dat brengt zijn eigen beveiligingsoverwegingen met zich mee.
Conclusie
Container escape is een reële dreiging in multi-tenant Docker-hosting, maar het is te voorkomen. Door de isolatiemechanismen te begrijpen en defense-in-depth toe te passen—capabilities laten vallen, draaien als niet-root, user namespaces inschakelen, seccomp, AppArmor, netwerksegmentatie en regelmatige image-scanning—kunt u het risico drastisch verminderen. Onthoud dat de standaardinstellingen van Docker niet productieklaar zijn voor multi-tenant workloads. Implementeer deze stappen vandaag nog om uw tenants en uw infrastructuur te beschermen. Voor een uitgebreid overzicht van Docker-beveiligingsbest practices, raadpleeg Securing Your Web Applications with Docker: A Practical Guide to Isolation and Best Practices.
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®

