Container-Sicherheit: Ist die Isolierung absolut? (Docker vs. Rootless Podman) | INTROSERV

Container-Sicherheit: Ist die Isolierung absolut? (Docker vs. Rootless Podman)

by Nataliya Oteir
Container-Sicherheit: Ist die Isolierung absolut? (Docker vs. Rootless Podman)
star 5
0
Lesen Sie 12 min.

Grundlegende Einschränkungen der Container-Isolierung

Die Containerisierung hat sich zur dominierenden Methode für die Paketierung und Bereitstellung von Anwendungen in Cloud- und Microservice-Architekturen entwickelt. Mit Containern können Sie Code, Bibliotheken und Abhängigkeiten bündeln und so eine hohe Portabilität und betriebliche Effizienz gewährleisten.

Die massive Migration kritischer Arbeitslasten zu Containern macht jedoch die Widerstandsfähigkeit von Isolationsmechanismen zu einem grundlegenden Problem. Untersuchungen und Umfragen unter DevOps- und Sicherheitsteams zeigen immer wieder, dass die Sicherheit von Containern eines der größten Probleme darstellt: Schwachstellen im Kernel und in der Laufzeit sowie Konfigurationsfehler führen regelmäßig zu realen Isolationsverletzungen.

Die Schlüsselfrage lautet: Ist die Container-Isolierung absolut?

Die Antwort lautet nein, und der Grund dafür liegt in ihrer Architektur. In diesem Artikel werden wir dieser Frage auf den Grund gehen und die verfügbaren Maßnahmen zur Minderung von Schwachstellenrisiken untersuchen.

Container vs. Virtuelle Maschinen: der gemeinsame Kernel

Virtuelle Maschine (VM):

  • Jede VM führt ihren eigenen Betriebssystem-Kernel aus, der vollständig vom Host getrennt ist.

  • Die Isolierung wird durch einen Hypervisor (KVM, Xen, ESXi, usw.) erzwungen.

  • Ein Angriff muss in der Regel auf den Hypervisor abzielen, was die Angriffsvektoren erheblich einschränkt.

Container:

  • Ein Container ist ein Prozess, der mithilfe von Linux-Kernel-Primitiven (Namespaces, cgroups usw.) isoliert wird.

  • Ein Container enthält nur den Benutzerbereich (Bibliotheken, Laufzeit, Anwendung), teilt sich aber einen Kernel mit dem Host und anderen Containern.

  • Jede kritische Kernel-Schwachstelle wird automatisch zu einem potenziellen Angriffsvektor für alle Container auf dem Knoten.

Die architektonische Entscheidung für einen gemeinsam genutzten Kernel führt dazu, dass die Isolierung von Containern grundsätzlich nicht absolut ist: Die erfolgreiche Ausnutzung einer Kernel-Schwachstelle ermöglicht es einem Angreifer, die Grenzen eines beliebigen Namespaces zu überwinden.

Die Rolle von Namespaces und Cgroups bei der Schaffung von Isolation

Die Grundlage der Container-Isolierung in Linux bilden Namespaces und Cgroups.

  • Namespaces - Isolierung der Systemansicht: PID, Mount, Netzwerk, Benutzer, IPC, UTS, und andere. Prozesse "sehen" nur ihren eigenen Bereich: ihr Dateisystem, ihre PIDs, ihren Hostnamen und ihr Netzwerk.

  • Cgroups - Ressourcenkontrolle und -begrenzung: CPU, Speicher, E/A, Prozessanzahl usw.

Namespaces schaffen die Illusion eines separaten Systems, und Сgroups verhindern, dass ein Container die Ressourcen des Hosts in Anspruch nimmt. Es ist jedoch wichtig zu beachten, dass Namespaces ein Isolationsmechanismus sind, kein vollwertiger Sicherheitsmechanismus gegen die absichtliche Umgehung von Barrieren. Sie verhindern nicht die Ausnutzung von Kernel-Schwachstellen, lösen keine Probleme mit übermäßigen Root-Rechten oder privilegierten Containern, filtern keine Systemaufrufe und verwalten keine Zugriffsrichtlinien.

Daher sind Namespaces und Сgroups lediglich eine Basisschicht, die verstärkt werden muss:

  1. Syscall-Filterung (Seccomp)

  2. MAC-Richtlinien (AppArmor/SELinux)

  3. Fähigkeitseinschränkungen

  4. Idealerweise User Namespaces + rootless mode

Sicherheit von Container-Plattformen: Kritische Bedrohungen und Angriffsvektoren

Die Angriffsfläche einer Container-Plattform ist vielschichtig. Die folgenden Hauptangriffsflächen können identifiziert werden:

  • Laufzeit und Kernel (runc, containerd, CRI-O, Linux-Kernel).

  • Image-Lieferkette.

  • Container- und Orchestrator-Konfiguration.

  • Cloud und Infrastruktur (IAM, API, Speicher, Netzwerk).

Überblick über Angriffsvektoren und kritische Schwachstellen: Container Escape


Typische Vektoren in einer Container-Umgebung sind: Ausnutzung einer Sicherheitslücke im Linux-Kernel oder in der Container-Laufzeitumgebung, Verwendung unsicherer Images (veraltete Pakete, Exploit-Kits), Konfigurationsfehler in Kubernetes/Docker (übermäßige Berechtigungen, Einbindung des Host-Dateisystems, Host-Netzwerk-Stack) sowie Kompromittierung von Registry und CI/CD.

Es ist wichtig zu verstehen, dass eine Container-Flucht oft eine Kombination von Faktoren ist:

Kernel-/Laufzeitschwachstelle + mangelhafte Konfiguration (Ausführung als Root, --privilegiert, Einhängen des Host-Dateisystems, fehlende MAC/Seccomp).

Schwachstellen in der Lieferkette

Die Lieferkette für Container-Images ist eines der Hauptrisiken, da die Basis-Images aus öffentlichen Registern oft bekannte CVEs enthalten. Abhängigkeiten (pip/npm/gem/go-Module) werden transitorisch gezogen und sind nicht immer kontrolliert. Besonders gefährlich ist, dass Malware "schlafend" sein kann und sich erst zur Laufzeit manifestiert.

Daher sind die folgenden Best Practices in der Produktion obligatorisch:

  • Scannen von Bildern auf CVEs mit Tools wie Trivy, Clair, Grype usw.

  • Verwendung von richtlinienkonformen Registrierungen mit Durchsetzung, wie z. B. Harbor, Quay oder GHCR.

  • Signierung und Überprüfung von Images vor der Bereitstellung.

Konfigurationsfehler und privilegierte Container

Der häufigste Fehler, der Schwachstellen Tür und Tor öffnet, ist die Ausführung von Prozessen innerhalb des Containers als root! Wenn die Anwendung im Container mit Superuser-Rechten gestartet wird, erlangt der Angreifer bei einer Kompromittierung des Containers Root-Rechte innerhalb des Containers. Ein erfolgreicher Ausbruch außerhalb des Containers vereinfacht dann die Eskalation zum Host-Root erheblich.

Das Verbot, Anwendungen als Root zu starten und unprivilegierte UID/GID zu verwenden, ist die Grundregel einer angemessenen Absicherung.

Privilegierte Container, die das --privileged-Flag verwenden, deaktivieren praktisch wichtige Isolationsmechanismen, insbesondere einige Cgroups, AppArmor/SELinux und Seccomp-Einschränkungen. Dadurch erhält der Container direkten Zugriff auf Host-Geräte und Pseudo-Dateisysteme (/proc, /sys, /dev, etc.). Von einem privilegierten Container aus ist es einfach, Host-Festplatten einzuhängen und das Dateisystem und die Konfigurationen zu ändern.

Im Grunde ist ein privilegierter Container gleichbedeutend mit einer absichtlichen Ausweitung der Privilegien. Denken Sie daran, dass dies nur in seltenen, gut isolierten Szenarien akzeptabel ist, und schon gar nicht in einer mandantenfähigen Umgebung.

Es gibt auch "stille" Konfigurationsfehler, die die Container-Umgebung extrem angreifbar machen können, auch ohne die Verwendung des --privileged-Flags. Die gefährlichsten sind:

  • Das Einbinden von hostPath in sensible Host-Verzeichnisse, wie /etc oder /var/run/docker.sock.

  • Gewährung unnötiger Capabilities, z.B. CAP_SYS_ADMIN, die praktisch Root-Rechte auf dem Host gewährt.

  • Ungerechtfertigte Verwendung der Modi hostNetwork oder hostPID.

Diese scheinbar unbedeutenden Einstellungen können es einem Angreifer ermöglichen, dem Container zu entkommen und die Kontrolle über den Kernel oder das gesamte Host-System zu erlangen.

Architektur-Vergleich: Docker vs. Podman

Die architektonischen Unterschiede zwischen Docker und Podman wirken sich direkt auf das Bedrohungsmodell aus. Docker stellt mit seinem hochprivilegierten Daemon das Hauptrisiko dar: ein einziger Fehlerpunkt.

Docker und Rootful-Modus

In der klassischen oder Standard-Docker-Architektur kommuniziert die Docker-Befehlszeilenschnittstelle (CLI) mit dem Dockerd-Daemon über den Socket /var/run/docker.sock oder TCP. Der dockerd-Daemon läuft als Root-Benutzer und führt die wichtigsten Operationen aus:

  • Erstellen/Löschen von Containern

  • Erstellen von Images

  • Verwalten von Netzwerken/Volumes

  • Interaktion mit Registrierungen

Daraus folgt, dass ein direkter Zugriff auf die Docker-API fast einem vollständigen Root-Zugriff auf den Host gleichkommt, der es einem Angreifer ermöglicht, das Dateisystem zu mounten, privilegierte Container zu starten usw. In diesem Szenario wird der Daemon zu einem Single Point of Failure - wenn er kompromittiert wird, erhält der Angreifer Zugriff auf den Host.

Daher erfordert Docker eine strenge Zugriffskontrolle auf den Socket, die obligatorische Aktivierung von MAC und Seccomp und die Einschränkung von Capabilities. Entscheidend ist, dass die Anzahl der Benutzer und Dienste mit Zugriff auf die Docker-API minimiert wird.

Daemonloser Podman: der native Linux-Ansatz

Podman wurde von Red Hat und der Community als eine sicherere, "native" Linux-Alternative entwickelt. Es wurde ursprünglich mit einer daemonlosen Architektur konzipiert, d. h. es gibt keinen persistenten, zentralisierten Daemon. Stattdessen sind die Container Kindprozesse des Benutzers, der den Befehl ausgeführt hat. Die Grundlage ist eine tiefe Integration mit systemd, wo Einheiten und Dienste direkt erstellt werden.

Dadurch wird der Single Point of Failure des Root-Daemons eliminiert und eine bessere Übereinstimmung mit dem traditionellen Unix-Modell erreicht: "Wer den Prozess gestartet hat, dem gehört er".

Rootloser Modus: User Namespaces als wichtigste Sicherheitsbarriere

Der Rootless-Modus ist im Grunde die logische Antwort auf die grundlegende Gefahr: "Was, wenn der Container ausbricht?"

Die Rolle von User Namespaces und Schadensbegrenzung

User Namespaces isolieren UID/GID und ermöglichen ein UID-Remapping. Wenn zum Beispiel ein Prozess innerhalb eines Containers die UID 0 (root) hat, wird derselbe Prozess einer unprivilegierten UID aus dem subuid/subgid-Bereich auf dem Host zugeordnet.

Selbst wenn ein Angreifer innerhalb des Containers Root-Rechte hat und es ihm gelingt, eine Laufzeit-/Kernel-Schwachstelle auszunutzen, um auf die Host-Ebene zu gelangen, arbeitet er daher weiterhin als unprivilegierter Benutzer auf dem Host.

Viele Ausnutzungsketten, einschließlich runc-escape, werden dadurch unterbrochen oder haben eine deutlich geringere Wirkung. Dies liegt daran, dass der Angreifer keine Root-Binärdateien/Konfigurationen überschreiben kann, keine Dateisysteme mounten oder Geräte ohne Capabilities verwalten kann und MAC-Richtlinien auch auf dem Host weiter funktionieren.

Rootless Podman: Beschränkungen und der Netzwerkstapel

Podman wurde von Anfang an mit dem Schwerpunkt auf wurzellosen Operationen entwickelt. Container werden von einem unprivilegierten Benutzer erstellt und verwaltet, Benutzernamensräume sind standardmäßig aktiviert, und SELinux/AppArmor und Cgroups werden so weit wie möglich ohne Root-Zugriff verwendet.

Dieses Schema birgt jedoch einige Nachteile. Wenn ein Container ohne Root-Zugriff innerhalb des subuid/subgid-Bereichs arbeitet, sind Zuordnungsfehler möglich, wenn das Image Dateien mit UID/GID-Werten enthält, die außerhalb dieses Bereichs liegen.

Ein weiterer indirekter Nachteil ist, dass ein unprivilegierter Benutzer keine freie Konfiguration von Netzwerk-Namespaces vornehmen kann. Seit Anfang 2025 verwendet Podman die Stack-Pasta für den Benutzerbereich als Ersatz für slirp4netns. Dieses Plugin arbeitet vollständig im Userspace, bietet aber dank der Tap-Schnittstelle und dem Zero-Copy-Splice eine nahezu native Netzwerkleistung. Dennoch sind Leistungseinbußen möglich und definitiv garantiert, wenn Benutzer weiterhin slirp4netns verwenden.

Rootless Docker: Implementierung und Anforderungen

Docker unterstützt auch einen vollwertigen Rootless-Modus, bei dem der Dockerd-Daemon und die Container innerhalb eines Benutzernamensraums ohne die Privilegien des Root-Benutzers des Hosts gestartet werden. Dies ist ein wichtiger Unterschied zur älteren userns-remap-Funktion, bei der der Daemon selbst privilegiert blieb.

Vom Sicherheitsstandpunkt aus betrachtet, garantiert dies, dass ein Verstoß gegen den Container nicht zu einer automatischen Eskalation auf die Ebene des Root-Benutzers des Hosts führt. Im Falle eines erfolgreichen Angriffs auf dockerd im Rootless-Modus wird nur auf die Ressourcen des unprivilegierten Benutzers zugegriffen, nicht auf das gesamte System.

Die Wahl zwischen dem Rootful- und dem Rootless-Modus ist in erster Linie eine Abwägung zwischen der Maximierung der Leistung und der maximalen Begrenzung des potenziellen Schadens im Falle eines Angriffs.

Schlussfolgerungen und Empfehlungen zur Härtung

Die Analyse bestätigt, dass die Isolierung von Containern aufgrund ihrer Architektur nicht absolut ist. Da Container den Kernel des Hostsystems gemeinsam nutzen, können Schwachstellen auf der Kernel- oder Laufzeitebene per Definition über Namensräume hinweg "sehen" und so die erwarteten Sicherheitsgrenzen verletzen.

In der Praxis sind die meisten erfolgreichen Angriffe mit einer Kombination aus einer bekannten Schwachstelle (Kernel/runc) und einer schwachen Konfiguration (root, --privileged, hostPath) verbunden.

Ein zuverlässiges Container-Sicherheitsmodell muss als mehrschichtiges System aufgebaut sein:

Schicht 1 - Segmentierung: (Namespaces, cgroups)

Schicht 2 - Policies und Filterung: (Seccomp, MAC, Fähigkeiten)

Schicht 3 - Architektonische Privilegienbeschränkung: (über rootless mode und User Namespaces)

Checkliste: Host-Härtung für Docker- und Podman-Container

  • Rootless als Standard

Betrachten Sie Podman oder Docker im Rootless-Modus als Standardmodell für interne und mandantenfähige Workloads.

  • Kernel-Härtung und Patching

Aktualisieren Sie den Kernel umgehend (Dirty COW, Dirty Pipe und ähnliche CVEs sind fast immer bereits durch Patches abgedeckt). Verwenden Sie Distributionen mit einer guten Sicherheitspatch-Historie (RHEL, OpenSUSE, Ubuntu LTS, usw.).

  • Einsatz spezialisierter, unveränderlicher Betriebssysteme

Um die Sicherheit der Containerumgebung zu erhöhen, sollten Sie unveränderliche Betriebssysteme wie openSUSE MicroOS oder Flatcar Linux verwenden. Ihr Root-Dateisystem ist standardmäßig schreibgeschützt, was die Angriffsfläche erheblich reduziert. Der Schlüsselmechanismus sind atomare Aktualisierungen: Es wird ein neues Betriebssystem-Image erstellt, und die Aktualisierung wird entweder vollständig angewendet oder vollständig zurückgenommen, wodurch eine Beschädigung des Systems verhindert und die Wiederherstellung beschleunigt wird.

  • Prinzip des geringsten Privilegs

Verwenden Sie niemals das --privileged Flag in der Produktion, außer in hochspezialisierten, isolierten Umgebungen. Vermeiden Sie es, Anwendungen innerhalb von Containern als Root-Benutzer auszuführen, und verwenden Sie ein schreibgeschütztes Dateisystem, den minimalen Satz von Capabilities und strenge Seccomp-Profile.

  • MAC-Richtlinien und Seccomp

Aktivieren und konfigurieren Sie SELinux\AppArmor für Container. Verwenden Sie Seccomp-Profile, idealerweise benutzerdefinierte Profile, die auf den tatsächlichen Systemaufrufen der Anwendung basieren, nicht nur auf den Docker-Standardwerten.

  • Sicherheit der Lieferkette

Implementieren Sie das Scannen von Container-Images. Beschränken Sie die Quellen von Basis-Images auf offizielle oder interne Registrierungen und aktivieren Sie die Signierung und Überprüfung von Images vor der Bereitstellung.

  • Laufzeitüberwachung

Setzen Sie Tools zur Erkennung von Anomalien und Container-IDS/EDR (Falco, Sysdig Secure oder Aqua Security) ein, die Container-Fluchtversuche erkennen und die Ausführung bösartiger Befehle überwachen können. Verfolgen Sie atypischen Netzwerkverkehr, unerwartete Systemaufrufe und den Zugriff auf sensible Dateien.

Die Zukunft der Isolation: Kata-Container, gVisor und Micro-VMs

Der Rootless-Modus verringert das Risiko einer vollständigen Kompromittierung des Hosts erheblich, aber er löst nicht alle Probleme, da Abhängigkeiten vom Host-Kernel bestehen bleiben und einige Angriffsklassen nicht ausgeschlossen werden können.

Daher werden hybride Ansätze für kritische Workloads immer beliebter:

  • Kata-Container: Jeder Pod oder Container wird innerhalb einer leichtgewichtigen Mikro-VM mit einem separaten Kernel gestartet, wodurch die Vorteile von VMs und Containern kombiniert werden.
  • gVisor: Ein in Go geschriebener Sandbox-Kernel, der als Zwischenschicht zwischen der Anwendung und dem echten Linux-Kernel fungiert.

Diese Lösungen verringern die Abhängigkeit vom gemeinsam genutzten Kernel und bringen uns näher an das VM-Isolationsmodell heran, während die deklarative Natur und der Komfort von Container-Orchestratoren erhalten bleiben.

Setzen Sie die Empfehlungen aus diesem Beitrag bei Ihrer nächsten Bereitstellung in echte Sicherheit um.

Bestellen Sie einen VPS oder einen Dedicated Server und beginnen Sie noch heute mit dem Aufbau einer sicheren Container-Plattform.

Zur Konfigurationsauswahl wechseln


Neue Beiträge:

Docker vs. Podman: Ein vollständiger Leitfaden zur daemonlosen Containerisierung

Neue Stellen

VAT

  • Other

    Other

    0%
  • austria

    Austria

    20%
  • Belgium

    Belgium

    21%
  • Bulgaria

    Bulgaria

    20%
  • Croatia

    Croatia

    25%
  • Cyprus

    Cyprus

    19%
  • Czech Republic

    Czech Republic

    21%
  • Denmark

    Denmark

    25%
  • Estonia

    Estonia

    22%
  • France

    France

    20%
  • Finland

    Finland

    24%
  • Germany

    Germany

    19%
  • Greece

    Greece

    24%
  • Hungary

    Hungary

    27%
  • Ireland

    Ireland

    23%
  • Italy

    Italy

    22%
  • Latvia

    Latvia

    21%
  • Lithuania

    Lithuania

    21%
  • Luxembourg

    Luxembourg

    17%
  • Malta

    Malta

    18%
  • Netherlands

    Netherlands

    21%
  • Poland

    Poland

    23%
  • Portugal

    Portugal

    23%
  • Romania

    Romania

    19%
  • Slovakia

    Slovakia

    20%
  • Slovenia

    Slovenia

    %
  • Spain

    Spain

    21%
  • Sweden

    Sweden

    25%
  • USA

    USA

    0%
european
states
  • Other
  • canada
  • poland
  • european-union
  • france
  • germany
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria
  • austria