Container Escape Prävention: Checkliste gegen Ausbruch
AI generated
FROM
RUN
Docker · Container Escape · Isolation · Kernel Security
Container Escape Prävention: Checkliste gegen Ausbruch
von der geteilten Kernel-Grenze zur gehärteten Isolation

Ein Container ist keine virtuelle Maschine, sondern ein isolierter Prozess, der sich denselben Kernel mit dem Host teilt. Container Escape Prävention bedeutet, genau diese Grenze konsequent zu härten: keine unnötigen Privilegien, keine gemounteten Sockets, aktive Seccomp- und AppArmor-Profile und ein aktueller Kernel, damit ein kompromittierter Container niemals zum Sprungbrett auf den Host wird.

20 Min. Lesezeit Privileged Mode · Seccomp · Capabilities · Kernel-Isolation Docker · Linux Namespaces · cgroups

1. Was ein Container Escape technisch bedeutet

Ein Container Escape bezeichnet den Moment, in dem ein Angreifer die Isolationsgrenze eines Containers durchbricht und Zugriff auf den Host-Kernel oder andere Container auf demselben Host erlangt. Anders als bei einer virtuellen Maschine, die durch einen echten Hypervisor mit eigener Kernel-Instanz getrennt ist, teilen sich alle Docker-Container denselben Host-Kernel. Diese architektonische Entscheidung macht Container leichtgewichtig und schnell, bedeutet aber auch, dass jede Schwachstelle in dieser gemeinsamen Kernel-Grenze ein potenzieller Weg für einen Container Escape ist.

Container Escape Prävention ist daher keine einzelne Maßnahme, sondern eine Kombination aus mehreren unabhängigen Verteidigungsschichten: eingeschränkte Capabilities, aktive Syscall-Filter, User-Namespace-Isolation und ein aktueller, gepatchter Kernel. Fällt eine dieser Schichten aus, sollen die anderen den Ausbruch trotzdem verhindern. Die folgenden Abschnitte gehen jeden relevanten Angriffsvektor einzeln durch und zeigen, mit welcher konkreten Konfiguration er sich schließen lässt.

2. Privilegierte Container als häufigster Angriffsvektor

Der mit Abstand häufigste Weg zu einem Container Escape in der Praxis ist ein Container, der mit dem Flag `--privileged` gestartet wurde. Dieses Flag deaktiviert praktisch alle Isolationsmechanismen: Der Container erhält Zugriff auf alle Host-Gerätedateien unter `/dev`, alle Linux-Capabilities und kann sogar neue Kernel-Module laden. Ein Angreifer, der Code-Ausführung in einem privilegierten Container erreicht, hat damit faktisch bereits Root-Zugriff auf den Host.

In der Praxis wird `--privileged` oft aus Bequemlichkeit gesetzt, etwa um einem Build-Container Zugriff auf Docker-in-Docker zu geben, oder weil eine Fehlermeldung durch das Flag verschwindet, ohne dass die eigentliche Ursache verstanden wurde. Container Escape Prävention beginnt daher mit einer einfachen Regel: `--privileged` sollte in produktiven Umgebungen praktisch nie verwendet werden, und jeder verbleibende Fall gehört explizit dokumentiert und begründet.


#!/usr/bin/env bash
# Detect privileged containers across a Docker host
set -euo pipefail

for cid in $(docker ps -q); do
  privileged=$(docker inspect "$cid" | jq -r '.[0].HostConfig.Privileged')
  if [[ "$privileged" == "true" ]]; then
    name=$(docker inspect "$cid" | jq -r '.[0].Name')
    echo "[CRITICAL] Privileged container running: $name ($cid)"
  fi
done

3. Linux-Capabilities gezielt einschränken

Auch ohne `--privileged` startet ein Docker-Container standardmäßig mit einem Satz von rund vierzehn Linux-Capabilities, darunter `CAP_NET_RAW` für Raw-Sockets und `CAP_SYS_CHROOT` für Chroot-Operationen. Viele dieser Capabilities werden von der eigentlichen Anwendung im Container nie benötigt, erweitern aber die Angriffsfläche für einen Container Escape, falls ein Angreifer Code-Ausführung im Container erreicht.

Der wirksamste Ansatz ist, mit `--cap-drop=ALL` sämtliche Standard-Capabilities zu entfernen und anschließend nur die tatsächlich benötigten mit `--cap-add` gezielt wieder hinzuzufügen. Ein Webserver, der nur auf Port 8080 lauscht, benötigt zum Beispiel keine einzige der Standard-Capabilities. Diese Positivliste reduziert die Angriffsfläche für Container Escape Prävention drastisch, ohne die Funktionalität der Anwendung einzuschränken.


#!/usr/bin/env bash
# Run a container with all capabilities dropped, adding back only what is needed
set -euo pipefail

docker run -d \
  --name shop-api \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --security-opt=no-new-privileges:true \
  --read-only \
  --tmpfs /tmp \
  myregistry.example.com/shop-api:1.4.2

4. Der gemountete Docker-Socket als direkter Ausbruchsweg

Ein Container, der mit `-v /var/run/docker.sock:/var/run/docker.sock` gestartet wird, erhält vollen Zugriff auf die Docker-API des Hosts. Aus Sicht der Kernel-Isolation ist das kein technischer Container Escape, aber praktisch gleichbedeutend: Der Container kann einen neuen, privilegierten Container starten, der wiederum das gesamte Host-Dateisystem mountet, und damit effektiv beliebigen Code auf dem Host ausführen. Dieser Weg wird in der Praxis regelmäßig für CI-Runner mit Docker-in-Docker-Anforderungen genutzt, oft ohne das Risiko vollständig zu verstehen.

Statt den Docker-Socket zu mounten, sollte für Docker-in-Docker-Anwendungsfälle entweder ein isolierter DinD-Container mit eigenem Daemon oder ein rootless Docker-Setup verwendet werden, das den Schaden bei einer Kompromittierung auf den nicht-privilegierten Benutzerkontext begrenzt. Für Container Escape Prävention gilt hier: Der gemountete Docker-Socket sollte als Äquivalent zu vollem Root-Zugriff auf den Host behandelt werden, nicht als bequeme Abkürzung.

5. Seccomp und AppArmor als Syscall-Filter

Seccomp-Profile filtern, welche Systemaufrufe ein Container überhaupt ausführen darf, unabhängig von Capabilities. Das Standard-Seccomp-Profil von Docker blockiert bereits rund 44 potenziell gefährliche Syscalls, darunter `mount`, `reboot` und `ptrace`, die für die meisten Anwendungen irrelevant sind, aber häufig in Container Escape-Exploits verwendet werden. Ein Angreifer, der zwar Code-Ausführung im Container erreicht, aber durch Seccomp am Aufruf des benötigten Syscalls gehindert wird, kann den geplanten Ausbruch nicht durchführen.

AppArmor beziehungsweise SELinux ergänzen Seccomp um eine dateisystembezogene Zugriffskontrolle: Selbst wenn ein Syscall erlaubt ist, kann das Profil den Zugriff auf bestimmte Pfade wie `/proc/sys` oder `/sys/kernel` explizit verweigern. Docker aktiviert auf den meisten Distributionen automatisch ein Standard-AppArmor-Profil, das aber häufig durch `--security-opt apparmor=unconfined` versehentlich deaktiviert wird, oft als Workaround für eine andere, unverstandene Fehlermeldung.


#!/usr/bin/env bash
# Verify that Seccomp and AppArmor are active for a running container
set -euo pipefail

docker inspect shop-api | jq -r '.[0].HostConfig.SecurityOpt'
# Expected output should NOT contain "seccomp=unconfined" or "apparmor=unconfined"

# Custom seccomp profile: only allow a minimal syscall set for a simple web app
docker run -d \
  --name shop-api \
  --security-opt seccomp=./profiles/web-app-seccomp.json \
  myregistry.example.com/shop-api:1.4.2

6. Kernel-Exploits und die Grenzen der Isolation

Selbst mit korrekt konfigurierten Capabilities, Seccomp und AppArmor bleibt ein Restrisiko bestehen: Eine unbekannte oder ungepatchte Kernel-Schwachstelle kann die gesamte Isolation umgehen, unabhängig von jeder Container-Konfiguration. Bekannte CVEs wie Dirty COW oder Dirty Pipe zeigten, dass ein lokaler Kernel-Exploit aus einem eigentlich unprivilegierten Container heraus vollen Root-Zugriff auf den Host verschaffen kann. Für Container Escape Prävention bedeutet das: Ein aktueller, regelmäßig gepatchter Kernel ist keine optionale Zusatzmaßnahme, sondern eine notwendige Grundlage.

Da diese Klasse von Schwachstellen prinzipiell nicht durch Container-Konfiguration allein verhindert werden kann, gehört zu einer vollständigen Container Escape-Strategie auch ein zeitnaher Patch-Prozess für den Host-Kernel, idealerweise automatisiert über unattended Upgrades oder ein kontrolliertes Patch-Management mit klarer Frist zwischen CVE-Veröffentlichung und Rollout auf produktiven Hosts.

7. User-Namespaces: Root im Container ist nicht Root auf dem Host

Ohne User-Namespace-Remapping ist Root innerhalb eines Containers identisch mit UID 0 auf dem Host. Gelingt trotz aller anderen Schutzmaßnahmen ein Container Escape, landet der Angreifer direkt mit vollen Root-Rechten auf dem Host-System. User-Namespace-Remapping mappt die Container-UID 0 auf eine nicht-privilegierte, hohe UID auf dem Host, sodass selbst ein erfolgreicher Ausbruch nur die Rechte eines gewöhnlichen, unprivilegierten Benutzers mitbringt.

Der Nachteil von User-Namespace-Remapping ist eine gewisse Komplexität bei Bind-Mounts und Dateiberechtigungen, weil UIDs innerhalb und außerhalb des Containers nicht mehr übereinstimmen. Für Container Escape Prävention in besonders sensiblen Umgebungen wiegt dieser Konfigurationsaufwand jedoch den Sicherheitsgewinn deutlich auf, weil diese eine Maßnahme den Schadensradius eines erfolgreichen Ausbruchs drastisch reduziert.


{
  "userns-remap": "default"
}

#!/usr/bin/env bash
# Verify user namespace remapping is active after enabling it in daemon.json
set -euo pipefail

systemctl restart docker
docker info | grep -i "userns"

# Container UID 0 now maps to a high, unprivileged host UID
docker run --rm alpine id
ps -o pid,user,cmd -C alpine 2>/dev/null || true

8. Ausbruchsversuche erkennen, wenn Prävention versagt

Keine Präventionsmaßnahme bietet hundertprozentige Sicherheit, weshalb Container Escape Prävention um eine Erkennungsebene ergänzt werden sollte. Laufzeit-Bedrohungserkennung mit Falco beobachtet Syscalls direkt im Kernel und erkennt typische Vorstufen eines Ausbruchsversuchs: unerwartete Mount-Operationen, Zugriffe auf `/proc/sys` oder Versuche, Kernel-Module zu laden. Diese Verhaltensmuster treten typischerweise auf, bevor ein Container Escape tatsächlich erfolgreich ist, und bieten damit ein Zeitfenster für eine Reaktion.

Docker Bench Security ergänzt diese Laufzeit-Sicht um eine statische Prüfung der Host- und Daemon-Konfiguration und deckt auf, ob grundlegende Schutzmaßnahmen wie User-Namespace-Remapping oder aktive Seccomp-Profile überhaupt vorhanden sind. Die Kombination aus beiden Werkzeugen deckt sowohl die präventive Konfigurationsebene als auch die laufende Überwachung ab, statt sich allein auf eine einzige Schutzschicht zu verlassen.

9. Die vollständige Checkliste im Vergleich

Die folgende Tabelle fasst die wichtigsten Maßnahmen für Container Escape Prävention mit ihrem jeweiligen Schutzumfang zusammen.

Maßnahme Schützt vor Aufwand Priorität
Kein --privileged Vollständige Deaktivierung der Isolation Gering Höchste
--cap-drop=ALL Missbrauch unnötiger Capabilities Gering bis mittel Sehr hoch
Kein Docker-Socket-Mount Faktischen Root-Zugriff über die API Gering Höchste
Seccomp/AppArmor aktiv Gefährliche Syscalls und Pfadzugriffe Gering (Standard aktiv) Hoch
User-Namespace-Remapping Volle Root-Rechte nach erfolgreichem Ausbruch Mittel Hoch
Aktueller Kernel Unbekannte Kernel-Exploits Mittel (Prozess) Hoch, dauerhaft

Keine dieser Maßnahmen ersetzt eine andere. Container Escape Prävention ist wirksam als Summe unabhängiger Schichten: Selbst wenn eine Schicht versagt, etwa durch einen unbekannten Kernel-Exploit, verhindern die verbleibenden Schichten wie User-Namespace-Remapping und eingeschränkte Capabilities, dass ein Ausbruch zu vollem Root-Zugriff auf dem Host führt.

Mironsoft

Container Escape Prävention und Isolations-Härtung

Ist eure Container-Isolation wirklich so stark, wie ihr denkt?

Wir prüfen eure produktiven Container auf privilegierte Modi, unnötige Capabilities und gemountete Sockets, härten Seccomp- und Namespace-Konfiguration und schließen die häufigsten Ausbruchswege systematisch.

Escape-Audit

Systematische Prüfung auf privilegierte Container und riskante Mounts

Isolations-Härtung

Capabilities, Seccomp und User-Namespace-Remapping produktionsreif konfigurieren

Erkennung

Falco-basierte Erkennung von Ausbruchsversuchen als zusätzliche Schicht aufbauen

10. Zusammenfassung

Container Escape Prävention ist keine einzelne Konfigurationsoption, sondern eine Summe unabhängiger Verteidigungsschichten. Der Verzicht auf `--privileged`, eingeschränkte Capabilities über `--cap-drop=ALL`, ein niemals gemounteter Docker-Socket, aktive Seccomp- und AppArmor-Profile sowie User-Namespace-Remapping schließen zusammen die häufigsten dokumentierten Angriffsvektoren für einen erfolgreichen Ausbruch aus dem Container.

Ein Restrisiko durch unbekannte Kernel-Schwachstellen bleibt trotz aller Konfiguration bestehen, weshalb ein aktueller, gepatchter Kernel und eine ergänzende Laufzeit-Bedrohungserkennung mit Falco Teil jeder vollständigen Container Escape Prävention-Strategie sein sollten. Wer alle Schichten dieser Checkliste konsequent umsetzt, reduziert den Schadensradius eines erfolgreichen Angriffs drastisch, selbst wenn eine einzelne Schutzmaßnahme im Ernstfall versagt.

Container Escape Prävention — Das Wichtigste auf einen Blick

Häufigster Vektor

Privilegierte Container mit --privileged deaktivieren praktisch die gesamte Isolation.

Capabilities

--cap-drop=ALL plus gezieltes --cap-add reduziert die Angriffsfläche drastisch.

Isolation

Seccomp, AppArmor und User-Namespace-Remapping bilden mehrere unabhängige Schutzschichten.

Restrisiko

Unbekannte Kernel-Exploits erfordern zeitnahes Patchen und ergänzende Laufzeit-Erkennung mit Falco.

11. FAQ: Container Escape Prävention

1Was ist ein Container Escape?
Der Durchbruch der Isolationsgrenze eines Containers mit Zugriff auf Host-Kernel oder andere Container.
2Warum ist --privileged gefährlich?
Deaktiviert praktisch alle Isolationsmechanismen, entspricht faktisch Root-Zugriff auf den Host.
3Wie Capabilities einschränken?
Mit --cap-drop=ALL alles entfernen, nur benötigte Capabilities gezielt mit --cap-add zurückgeben.
4Warum ist der Docker-Socket riskant?
Erlaubt das Starten neuer privilegierter Container und damit effektiv Code-Ausführung auf dem Host.
5Was macht Seccomp?
Filtert erlaubte Systemaufrufe, blockiert im Standardprofil bereits rund 44 gefährliche Syscalls.
6Verhindert User-Namespace-Remapping alles?
Nein, reduziert aber den Schaden drastisch durch Mapping auf eine unprivilegierte Host-UID.
7Reicht das gegen Kernel-Exploits?
Nein, unbekannte Kernel-Schwachstellen können alles umgehen, ein aktueller Kernel ist unverzichtbar.
8Wie Ausbruchsversuche erkennen?
Mit Falco, das verdächtige Syscalls wie Mount-Operationen oder Modul-Ladeversuche erkennt.
9Ist Docker Bench Security relevant?
Ja, prüft statisch, ob Schutzmaßnahmen wie Namespace-Remapping und Seccomp konfiguriert sind.
10Reicht eine einzelne Maßnahme?
Nein, Prävention wirkt als Summe unabhängiger Schichten, keine Maßnahme ersetzt die andere.