Blog

Echte Multi-Tenant-Isolation in Docker erreichen

Dockers gemeinsames Kernel-Modell birgt Risiken für Multi-Tenant-Umgebungen. Dieser Leitfaden bietet konkrete Schritte zur Stärkung der Isolation mithilfe von User Namespaces, Seccomp, AppArmor, Sandboxing-Tools und Orchestrierungs-Best Practices.

Zusammenfassung

Docker-Container teilen sich den Host-Kernel, was in Multi-Tenant-Umgebungen, in denen sich die Mandanten nicht unbedingt vertrauen, ein Sicherheitsrisiko darstellen kann. Dieser Artikel erklärt die Isolationslücken in Standard-Docker-Setups und bietet konkrete Schritte zur Stärkung der Isolation mithilfe von Linux-Namespaces, Cgroups, User Namespaces, Seccomp, AppArmor und Hardware-Virtualisierung. Sie erfahren, wie Sie mandantenspezifische Docker-Daemons konfigurieren, Sandboxing-Tools wie gVisor oder Firecracker für eine stärkere Isolation einsetzen und mit Kubernetes für Multi-Tenancy orchestrieren. Wir behandeln auch die Auswahl des richtigen Infrastrukturanbieters, der KVM-basierte Virtualisierung für eine zusätzliche Trennungsebene bietet. Am Ende haben Sie einen Bauplan für die Ausführung sicherer Multi-Tenant-Workloads mit Docker.

Wenn mehrere Mandanten auf einem einzelnen Docker-Host gehostet werden, reicht die standardmäßige Container-Isolation – basierend auf Linux-Namespaces und Cgroups – oft nicht aus. Ein Container-Ausbruch in einem Mandanten könnte den gesamten Host und alle anderen Container gefährden. Dieses Problem ist besonders akut in Shared Hosting, SaaS-Plattformen oder jedem Szenario, in dem nicht vertrauenswürdiger Code neben Ihrem eigenen läuft. Die gute Nachricht: Sie können mehrere Isolationstechniken stapeln, um eine gehärtete Multi-Tenant-Umgebung aufzubauen. Dieser Leitfaden führt durch sechs praktische Schritte, von einfachen Maßnahmen wie User Namespaces bis hin zu fortgeschrittenen Maßnahmen wie Sandbox-Laufzeiten und Infrastrukturentscheidungen.

Docker-Standardisolation verstehen

Docker verwendet Linux-Namespaces, um Prozesse, Netzwerk, Dateisystem und andere Ressourcen zu isolieren. Cgroups begrenzen CPU, Speicher und I/O. Aber diese teilen sich einen einzigen Kernel – eine Schwachstelle im Kernel kann alle Container betreffen. Für echte Multi-Tenancy, insbesondere mit nicht vertrauenswürdigen Mandanten, benötigen Sie eine gestaffelte Verteidigung. Wie in Entwurf einer Multi-Tenant-Docker-Architektur: Das richtige Isolationsniveau wählen erläutert, reichen die Isolationsstufen von schwach (nur Namespace) bis stark (hardwarevirtualisiert). Bauen wir vom Schwächsten auf.

Schritt 1: User Namespaces aktivieren

Standardmäßig wird root innerhalb eines Containers auf root auf dem Host abgebildet. Ein Container-Ausbruch gewährt vollen Host-Zugriff. User Namespaces bilden Container-root auf einen Nicht-root-Benutzer außerhalb ab. Aktivieren Sie es global mit dockerd --userns-remap=default oder pro Container mit --userns=host. Dieser einfache Schritt eliminiert viele Privilegieneskalationsangriffe. Testen Sie Ihre Anwendungen: Manche, die Host-Level-Privilegien erfordern (z. B. Mounten von Dateisystemen), könnten brechen. Für Drupal- oder WordPress-Seiten ist es normalerweise sicher.

Schritt 2: Seccomp- und AppArmor-Profile anwenden

Seccomp begrenzt die Systemaufrufe, die ein Container tätigen kann. Docker wird mit einem Standard-Seccomp-Profil ausgeliefert, das gefährliche Syscalls wie mount und reboot blockiert. Für Multi-Tenant verschärfen Sie es weiter – blockieren Sie ungewöhnliche Syscalls, die von Escape-Tools verwendet werden. Ähnlich kann AppArmor Container-Prozesse einschränken. Erstellen Sie ein benutzerdefiniertes AppArmor-Profil, das Schreibzugriff auf Kernel-Schnittstellen verweigert und Dateipfade einschränkt. Beide werden über --security-opt-Flags gesetzt. Kombinieren Sie sie für eine gestaffelte Verteidigung.

Schritt 3: Mandantenspezifische Docker-Daemons verwenden

Die Ausführung eines einzigen Docker-Daemons für alle Mandanten ist riskant – jeder Container-Ausbruch könnte auf den Daemon-Socket zugreifen. Isolieren Sie Daemons pro Mandant mit Docker-in-Docker (DinD) oder Remote-Daemon-Endpunkten. Starten Sie beispielsweise einen Docker-Daemon innerhalb eines Containers mit --privileged (das schwächt jedoch die Isolation). Ein besserer Ansatz: Führen Sie separate Daemons auf separaten VMs aus oder verwenden Sie die experimentelle --group-Funktion von Docker mit User Namespaces. Für die Orchestrierung ist die Kubernetes-Namespace-basierte Isolation praktischer, wie in Verteidigung gegen Container-Ausbruch: Ein praktischer Leitfaden zur Docker-Isolation für Multi-Tenant-Hosting beschrieben.

Schritt 4: Sandbox-Laufzeiten in Betracht ziehen

Wenn der Linux-Kernel selbst nicht vertrauenswürdig ist, verwenden Sie eine Sandbox-Laufzeit, die eine leichte VM-Schicht hinzufügt. gVisor (runsc) fängt Syscalls ab und implementiert seinen eigenen Kernel, während Firecracker Micro-VMs mit Hardware-Virtualisierung verwendet. Beide integrieren sich über containerd-Laufzeiten in Docker. Fügen Sie beispielsweise "runtimes": {"runsc": {}} zur Docker-Daemon-Konfiguration hinzu und führen Sie Container mit --runtime=runsc aus. Der Leistungsaufwand beträgt 5–15 %, aber die Isolation ist deutlich stärker. Ideal für sicherheitskritische Multi-Tenant-Setups.

Schritt 5: Mit Kubernetes und Sicherheitsrichtlinien orchestreren

Kubernetes bietet native Multi-Tenancy durch Namespaces, Pod-Sicherheitsstandards und NetworkPolicies. Definieren Sie mandantenspezifische Namespaces mit Ressourcenkontingenten und erzwingen Sie eingeschränkte Pod-Sicherheitskontexte (alle Capabilities entfernen, schreibgeschütztes Root-Dateisystem). Admission Controller wie OPA/Gatekeeper können Fehlkonfigurationen blockieren. Wenn Sie viele Mandanten verwalten, automatisiert Kubernetes die Durchsetzung der Isolation. Für die produktionsreife Orchestrierung siehe Jenseits von Docker Compose: Orchestrierung produktionsreifer containerisierter Anwendungen.

Schritt 6: Den richtigen Hosting-Anbieter wählen

Der Hypervisor Ihres Infrastrukturanbieters ist entscheidend. Docker auf Shared Hosting (OpenVZ) bietet schwache Isolation – ein Mandant kann andere Prozesse sehen. Bevorzugen Sie Anbieter, die KVM oder VMware verwenden, da diese Hardware-Level-Trennung bieten. Anbieter wie DigitalOcean, Kamatera oder AWS bieten KVM-basierte VPS mit dedizierten Ressourcen. Bei Bare-Metal stellen Sie sicher, dass die BIOS-Virtualisierung für verschachtelte Container aktiviert ist. Ein Anbieter, der Mandanten auf Hypervisor-Ebene isoliert, ergänzt Ihre Container-Isolation. Wie in Meisterhaftes Docker-Isolation für sicheres und effizientes Webhosting ausgeführt, sollte auch das Host-Betriebssystem mit minimaler Angriffsfläche gehärtet sein.

Einschränkungen und Abwägungen

Jede zusätzliche Schicht erhöht die Komplexität und Kosten der Leistung. User Namespaces können Host-Mount-Volumes beeinträchtigen. Seccomp-Profile müssen pro Anwendung abgestimmt werden. Sandbox-Laufzeiten wie gVisor unterstützen nicht alle Syscalls – Ihre App könnte nicht funktionieren. Mandantenspezifische Docker-Daemons erhöhen den Speicher-Overhead. Wählen Sie die Isolationsebene, die Ihrem Bedrohungsmodell entspricht: Für vertrauenswürdige Mandanten reichen Standard-Namespaces; für öffentliche SaaS investieren Sie in Laufzeit-Sandboxes und Kubernetes-Richtlinien. Testen Sie gründlich vor der Produktion.

Fazit

Echte Multi-Tenant-Isolation in Docker ist durch die Kombination mehrerer Kernel-Funktionen, Laufzeit-Sandboxes und Orchestrierungssteuerungen erreichbar. Beginnen Sie mit User Namespaces und Seccomp, dann steigen Sie auf mandantenspezifische Daemons oder Sandbox-Laufzeiten um. Für große Umgebungen bietet Kubernetes richtlinienbasierte Isolation. Kombinieren Sie dies immer mit einem Hypervisor-getrennten Host eines renommierten Anbieters. Keine einzelne Technik ist undurchdringlich, aber ihre Kombination ergibt eine robuste Verteidigung. Ihre Mandanten werden es Ihnen danken – und auch Ihr Sicherheitsaudit.

Sources (5)