Blog

Echte multi-tenant isolatie bereiken in Docker

Het gedeelde kernelmodel van Docker brengt risico's met zich mee voor multi-tenant omgevingen. Deze gids biedt concrete stappen om de isolatie te versterken met behulp van user namespaces, seccomp, AppArmor, sandboxing-tools en best practices voor orchestration.

Samenvatting

Docker-containers delen de hostkernel, wat een veiligheidsprobleem kan zijn voor multi-tenant omgevingen waarin tenants elkaar mogelijk niet vertrouwen. Dit artikel legt de isolatiehiaten in standaard Docker-installaties uit en biedt concrete stappen om de isolatie te versterken met behulp van Linux namespaces, cgroups, user namespaces, seccomp, AppArmor en hardwarevirtualisatie. Je leert hoe je per-tenant Docker-daemons configureert, sandboxing-tools zoals gVisor of Firecracker gebruikt voor sterkere isolatie en orkestreert met Kubernetes voor multi-tenancy. We bespreken ook het selecteren van de juiste infrastructuurprovider die KVM-gebaseerde virtualisatie biedt voor een extra scheidingslaag. Aan het einde heb je een blauwdruk voor het uitvoeren van veilige multi-tenant workloads met Docker.

Bij het hosten van meerdere tenants op een enkele Docker-host is de standaard containerisolatie—gebaseerd op Linux namespaces en cgroups—vaak niet voldoende. Een containerontsnapping bij één tenant kan de hele host en alle andere containers in gevaar brengen. Dit probleem is vooral acuut bij shared hosting, SaaS-platforms of elk scenario waarin niet-vertrouwde code naast je eigen code draait. Het goede nieuws: je kunt meerdere isolatietechnieken stapelen om een geharde multi-tenant omgeving te bouwen. Deze gids doorloopt zes praktische stappen, van laaghangend fruit zoals user namespaces tot geavanceerde maatregelen zoals sandboxed runtimes en infrastructuurkeuzes.

Inzicht in de standaardisolatie van Docker

Docker gebruikt Linux namespaces om processen, netwerk, bestandssysteem en andere bronnen te isoleren. Cgroups beperken CPU, geheugen en I/O. Maar deze delen een enkele kernel—een kwetsbaarheid in de kernel kan alle containers beïnvloeden. Voor echte multi-tenancy, vooral met niet-vertrouwde tenants, heb je verdediging in de diepte nodig. Zoals besproken in Het ontwerpen van een multi-tenant Docker-architectuur: het kiezen van het juiste isolatieniveau, variëren isolatieniveaus van zwak (alleen namespace) tot sterk (hardware gevirtualiseerd). Laten we opbouwen vanaf het zwakste.

Stap 1: User Namespaces inschakelen

Standaard wordt root in een container toegewezen aan root op de host. Een containeruitbraak geeft volledige hosttoegang. User namespaces wijzen container root opnieuw toe aan een niet-root gebruiker buiten. Schakel het globaal in met dockerd --userns-remap=default of per container met --userns=host. Deze eenvoudige stap elimineert veel privilege-escalatieaanvallen. Test je applicaties: sommige die host-level privileges vereisen (bijv. het mounten van bestandssystemen) kunnen breken. Voor Drupal- of WordPress-sites is het meestal veilig.

Stap 2: Seccomp- en AppArmor-profielen toepassen

Seccomp beperkt de systeemaanroepen die een container kan doen. Docker wordt geleverd met een standaard seccomp-profiel dat gevaarlijke syscalls zoals mount en reboot blokkeert. Voor multi-tenant, verscherp het verder—blokkeer ongebruikelijke syscalls die ontsnappingstools gebruiken. Evenzo kan AppArmor containerprocessen beperken. Maak een aangepast AppArmor-profiel dat schrijftoegang tot kernelinterfaces weigert en bestandspaden beperkt. Beide worden ingesteld via --security-opt vlaggen. Combineer ze voor gelaagde verdediging.

Stap 3: Gebruik per-tenant Docker-daemons

Het uitvoeren van een enkele Docker-daemon voor alle tenants is riskant—elke containerontsnapping heeft toegang tot de daemon-socket. Isoleer daemons per tenant met behulp van Docker-in-Docker (DinD) of externe daemon-eindpunten. Lanceer bijvoorbeeld een Docker-daemon in een container met --privileged (maar dat verzwakt isolatie). Een betere aanpak: voer aparte daemons uit op aparte VM's of gebruik Docker's experimentele --group functie met user namespaces. Voor orchestration is op Kubernetes namespace gebaseerde isolatie praktischer, zoals besproken in Verdedigen tegen containerontsnapping: een praktische gids voor Docker-isolatie voor multi-tenant hosting.

Stap 4: Overweeg sandboxed runtimes

Wanneer de Linux-kernel zelf niet vertrouwd wordt, gebruik dan een sandboxed runtime die een lichtgewicht VM-laag toevoegt. gVisor (runsc) onderschept syscalls en implementeert zijn eigen kernel, terwijl Firecracker micro-VM's gebruikt met hardwarevirtualisatie. Beide integreren met Docker via containerd-runtimes. Voeg bijvoorbeeld "runtimes": {"runsc": {}} toe aan de Docker-daemonconfiguratie en voer containers uit met --runtime=runsc. Prestatieoverhead is 5–15% maar isolatie is aanzienlijk sterker. Ideaal voor beveiligingsgevoelige multi-tenant opstellingen.

Stap 5: Orchestreer met Kubernetes en beveiligingsbeleid

Kubernetes biedt native multi-tenancy via namespaces, Pod Security Standards en NetworkPolicies. Definieer per-tenant namespaces met resourcequota's en handhaaf beperkte pod-beveiligingscontexten (alle capabilities laten vallen, read-only root filesysteem). Admission controllers zoals OPA/Gatekeeper kunnen verkeerde configuraties blokkeren. Als je veel tenants beheert, automatiseert Kubernetes isolatiehandhaving. Voor orchestration op productieschaal, raadpleeg Verder dan Docker Compose: het orkestreren van productieredy containerized applicaties.

Stap 6: Kies de juiste hostingprovider

De hypervisor van je infrastructuurprovider is belangrijk. Docker op shared hosting (OpenVZ) biedt zwakke isolatie—één tenant kan andere processen zien. Geef de voorkeur aan providers die KVM of VMware gebruiken, die hardwareniveau scheiding bieden. Providers zoals DigitalOcean, Kamatera of AWS bieden KVM-gebaseerde VPS met dedicated resources. Voor bare-metal, zorg ervoor dat virtualisatie op BIOS-niveau is ingeschakeld voor geneste containers. Een provider die tenants isoleert op de hypervisorlaag vult je containerisolatie aan. Zoals beschreven in Docker-isolatie beheersen voor veilig en efficiënt webhosting, moet het host-OS ook worden gehard met een minimaal aanvalsoppervlak.

Kanttekeningen en afwegingen

Elke extra laag voegt complexiteit en prestatiekosten toe. User namespaces kunnen host-mount volumes breken. Seccomp-profielen vereisen afstemming per applicatie. Sandboxed runtimes zoals gVisor ondersteunen niet alle syscalls—je app werkt mogelijk niet. Per-tenant Docker-daemons verhogen het geheugengebruik. Kies het isolatieniveau dat past bij je bedreigingsmodel: voor vertrouwde tenants kunnen standaard namespaces voldoen; voor publieke SaaS, investeer in runtime sandboxes en Kubernetes-beleid. Test grondig voor productie.

Conclusie

Echte multi-tenant isolatie in Docker is haalbaar door meerdere kernelfuncties, runtime sandboxes en orchestration-controles te stapelen. Begin met user namespaces en seccomp, ga dan over naar per-tenant daemons of sandboxed runtimes. Voor grootschalige implementaties biedt Kubernetes beleidsgestuurde isolatie. Combineer altijd met een op hypervisor-niveau gescheiden host van een gerenommeerde provider. Geen enkele techniek is onfeilbaar, maar door ze te combineren creëer je een robuuste verdediging. Je tenants zullen je bedanken—en je beveiligingsaudit ook.

Sources (5)