Docker auf einem VPS: Die häufigsten Sicherheitsfehler, die Anfänger machen
Wenn du Docker zum ersten Mal auf einem VPS installierst, geht man leicht davon aus, dass Container wie sichere kleine Sandkästen funktionieren und der Host vor Schaden geschützt ist. In Wirklichkeit können ein paar gängige Abkürzungen, wie das Einbinden von `docker.sock`, die Verwendung von `--privileged` oder das Vertrauen in beliebige Images, Angreifern unbemerkt die Kontrolle über deinen gesamten Server verschaffen. Wenn du dich auf Standardeinstellungen und Vermutungen verlässt, machst du wahrscheinlich mindestens einen Fehler, der schwerwiegender ist, als du denkst.
Warum Docker auf einem VPS nicht so sicher ist, wie es scheint
Auch wenn sich Docker auf deinem VPS wie eine Sandbox anfühlt, ist seine Isolierung oft schwächer, als viele neue Nutzer annehmen, und diese Lücke kann relativ kleine Fehler zu einer vollständigen Kompromittierung des Servers führen.
Container teilen sich den Kernel des Hosts, daher bedeutet „Root im Container“ effektiv hohe Berechtigungen auf dem Host. Wenn du zusätzliche Funktionen hinzufügst, wie zum Beispiel die Verwendung von `--privileged` oder die Gewährung von `CAP_SYS_MODULE`, kann ein Container-Escape zur vollständigen Kontrolle über den VPS führen.
Zudem gibt es Aspekte in Bezug auf Daten und Netzwerke zu berücksichtigen.
Das spätere Entfernen von Geheimnissen in einem Dockerfile mindert das Risiko nicht vollständig, da frühere Image-Layer diese Geheimnisse möglicherweise noch enthalten und oft eingesehen oder wiederhergestellt werden können.
Was das Netzwerk betrifft, können die Standardeinstellungen von Docker und Tools wie Docker Compose Ports offenlegen und Bridge-Netzwerke auf eine Weise erstellen, die Dienste über das vom Betreiber beabsichtigte Maß hinaus zugänglich macht, insbesondere, wenn Firewall-Regeln oder veröffentlichte Ports nicht sorgfältig überprüft werden.
Wie „docker.sock“ und privilegierte Container deinen VPS gefährden
Um die Sicherheitsgrenzen der Docker-Isolation auf einem VPS zu verstehen, ist es wichtig, zwei häufige Probleme zu untersuchen: die Offenlegung von „docker.sock“ und das Ausführen von Containern mit der Option „--privileged“. Diese Risiken sind besonders relevant bei der Nutzung von Selbst Hosting Vaultwarden, da ein selbstverwalteter Passwortserver besondere Aufmerksamkeit hinsichtlich Container-Berechtigungen und Systemgrenzen erfordert.
Unter Linux kommuniziert die Docker-CLI über den Unix-Socket „docker.sock“ mit dem Docker-Daemon. Jeder Prozess, der auf diesen Socket zugreifen kann, kann Befehle an den Daemon senden, darunter das Starten neuer Container, das Einbinden von Host-Verzeichnissen und das Ändern von Container-Konfigurationen. In der Praxis entspricht diese Zugriffsebene Root-Rechten auf dem Host.
Eine häufige Fehlkonfiguration ist das Einbinden des Docker-Sockets in einen Container mit dem Befehl `-v /var/run/docker.sock:/var/run/docker.sock`. Code, der in diesem Container läuft, kann dann direkt mit dem Docker-Daemon interagieren. Dadurch kann er neue Container mit der Option `--privileged` oder mit weitreichenden Berechtigungen starten, die die Isolation schwächen. Diese Optionen können es einem Angreifer ermöglichen, aus dem Container zu entkommen und das Host-System zu beeinträchtigen. Aus diesem Grund solltest du den Zugriff auf `docker.sock` oder die Verwendung privilegierter Container vermeiden, es sei denn, die Workload ist absolut vertrauenswürdig und wird kontinuierlich überwacht.
Docker als Root innerhalb des Containers ausführen (und sicherere Alternativen)
Viele Nutzer gehen davon aus, dass es sicher ist, Dienste als Root innerhalb eines Containers auszuführen, doch auf einem VPS kann dies erhebliche Risiken mit sich bringen.
Container teilen sich den Host-Kernel, sodass ein kompromittierter Root-Prozess in einem Container in Verbindung mit erhöhten Berechtigungen die Wahrscheinlichkeit einer Kompromittierung auf Host-Ebene erhöhen kann.
Vermeide die Verwendung von „--privileged“ oder weitreichenden Fähigkeiten wie CAP_SYS_ADMIN oder CAP_SYS_MODULE, da diese die Isolation zwischen Container und Host erheblich schwächen.
Ein vorsichtigerer Ansatz besteht darin, im Image einen Nicht-Root-Benutzer anzulegen und USER <uid> anzugeben, damit der Hauptprozess nicht als Root läuft.
Wenn erweiterte Berechtigungen wirklich erforderlich sind, solltest du lieber nur die konkret benötigten Capabilities über --cap-add hinzufügen, anstatt weitreichende Privilegien zu gewähren.
Erwäge außerdem die Verwendung von User-Namespace-Remapping, damit Root innerhalb des Containers einem Benutzer ohne Privilegien auf dem Host zugeordnet wird, was die Auswirkungen eines potenziellen Sicherheitsverstoßes verringert.
Vertrauen in zufällige Docker-Hub-Images (und versteckte Layer)
Wenn du ein nicht vertrauenswürdiges Image von Docker Hub abrufst und es auf einem VPS ausführst, erlaubst du Code unbekannter Herkunft, sich mit Zugriff auf die Ressourcen und das Netzwerk dieses Hosts auszuführen. Dies umfasst alles, was in den zugrunde liegenden Layern des Images vorhanden ist, nicht nur das, was im endgültigen Dateisystem des Containers sichtbar ist.
Docker-Images sind als Stapel von Layern aufgebaut. Wenn ein Geheimnis (wie Anmeldedaten, Tokens oder Schlüssel) in einem frühen Layer hinzugefügt und später in einem nachfolgenden Layer „entfernt“ wird, existiert es dennoch im Image-Verlauf und kann durch Image-Inspektion oder durch Exportieren des Images abgerufen werden. Das Fehlen sichtbarer Geheimnisse in einem laufenden Container garantiert nicht, dass das Image selbst frei von sensiblen Daten oder bösartigen Artefakten ist.
Um das Risiko zu verringern, solltest du es vermeiden, Geheimnisse direkt in Images einzubetten. Bevorzuge minimale, gut gepflegte Basis-Images und fixiere sie anhand eines Content-Digests, anstatt dich auf veränderbare Tags wie „latest“ zu verlassen. Verwende nach Möglichkeit Images aus vertrauenswürdigen, überprüfbaren Quellen und überprüfe Dockerfiles oder Build-Konfigurationen, um zu verstehen, wie das Image aufgebaut ist.
Docker-Netzwerk, iptables und UFW auf deinem VPS
Obwohl Docker-Anwendungen scheinbar vom Host isoliert sind, interagiert sein Netzwerkmodell direkt mit der Firewall deines VPS.
Wenn du einen Port mit „-p“ in „docker run“ oder über „ports:“ in Docker Compose veröffentlichst, fügt Docker iptables-NAT-Regeln hinzu, sodass 0.0.0.0:<hostport> den Datenverkehr direkt in den Container weiterleitet – unabhängig davon, was UFW scheinbar zulässt.
Dadurch können Dienste über das Internet erreichbar sein, selbst wenn „ufw status“ nur SSH oder eine begrenzte Anzahl von Ports als zugelassen anzeigt.
Docker Compose erstellt in der Regel ein eigenes Bridge-Netzwerk für Dienste, sodass diese über Container-DNS-Namen kommunizieren können, ohne dass öffentliche Ports freigegeben werden müssen.
Es ist generell ratsam, die meisten Dienste in diesem internen Netzwerk zu belassen und nur die Ports zu veröffentlichen, die öffentlich erreichbar sein müssen.
Um zu überprüfen, welche Ports tatsächlich freigegeben sind, verlasse dich nicht ausschließlich auf die UFW-Ausgabe.
Überprüfe die tatsächlich geltenden iptables-Regeln und führe externe Port-Scans durch (zum Beispiel von einem anderen Host im Internet aus), um zu bestätigen, auf welche Dienste zugegriffen werden kann.
Docker-Ports direkt ins Internet freigeben
Das Veröffentlichen eines Container-Ports mit `-p 8080:80` oder über einen `ports:`-Eintrag in Docker Compose vereinfacht nicht nur den lokalen Zugriff; es macht diesen Port auf dem Host zugänglich, wodurch der Dienst möglicherweise direkt über das Internet erreichbar wird.
Docker konfiguriert iptables-Regeln automatisch, sodass Firewall-Einstellungen auf Host-Ebene, die scheinbar „nur SSH“ zulassen, dennoch den Zugriff auf diese veröffentlichten Container-Ports ermöglichen können.
Lokale Tests können diese Gefährdung verschleiern. Ein Dienst, der auf einem Entwicklungsrechner „einfach funktioniert“, kann möglicherweise auch extern über NAT- oder Cloud-Netzwerkregeln erreichbar sein.
Dockers internes DNS und die virtuellen Netzwerke steuern, wie Container miteinander kommunizieren, aber sie schränken nicht ein, wer einen Port erreichen kann, sobald dieser auf dem Host veröffentlicht wurde.
Um unnötige Sicherheitslücken zu vermeiden, veröffentliche nur die erforderlichen Ports und binde sie an 127.0.0.1, wenn sie ausschließlich für den lokalen Zugriff bestimmt sind.
Teste regelmäßig von einem anderen Netzwerk aus oder nutze Port-Scan-Tools, um zu überprüfen, welche Dienste von außerhalb des Hosts erreichbar sind.
Daten und Geheimnisse sicher mit Docker auf einem VPS speichern
Auf einem VPS, auf dem Docker läuft, ist der Umgang mit Daten und Geheimnissen genauso wichtig wie die Freigabe von Netzwerkdiensten.
Vermeide es, Geheimnisse in Images einzubetten; selbst wenn sie in späteren Layern entfernt werden, lassen sie sich oft aus dem Image-Verlauf oder den Layer-Dateien wiederherstellen. Stelle Geheimnisse stattdessen erst zur Laufzeit bereit, zum Beispiel über Umgebungsvariablen, eingebundene Geheimnisdateien oder ein spezielles System zur Verwaltung von Geheimnissen.
Stelle sicher, dass sensible Werte niemals in die Versionskontrolle übernommen werden.
Speichere Anwendungsdaten auf vom Host eingebundenen Volumes oder externen Speichern, damit die Daten auch nach einem Neustart des Containers oder einer Image-Aktualisierung erhalten bleiben. Das verringert das Risiko eines Datenverlusts, wenn Container neu erstellt werden.
Vermeide es, /var/run/docker.sock in Container einzubinden, da dies dem Container faktisch die volle Kontrolle über den Docker-Daemon und damit auch über das Host-System gewährt.
Führe Container mit den minimal erforderlichen Berechtigungen aus, verwende standardmäßig nicht privilegierte Benutzer und füge Fähigkeiten oder erweiterte Berechtigungen nur hinzu, wenn ein klarer, begründeter Bedarf besteht.
Fazit
Wenn du Docker auf einem VPS ausführst, verwaltest du eine echte Angriffsfläche, keine magische Isolation. Behandle Container wie nicht vertrauenswürdige Apps, die sich deinen Kernel teilen. Vermeide --privileged, binde docker.sock nicht ein und verzichte auf Root-Rechte, wann immer es geht. Sei wählerisch bei den Images, schränke Netzwerkzugriffe und exponierte Ports ein und halte geheime Daten aus den Layern fern. Wenn du dir diese Gewohnheiten jetzt aneignest, stärkst du die Sicherheit deines VPS, hältst Überraschungen auf ein Minimum und kannst die Vorteile von Docker tatsächlich sicher genießen.