Sicher „eingedock(er)t“? Die legendäre Simplizität von Containern erkaufen sich viele Nutzer durch reihenweise Sicherheitsvorfälle. Zum Glück geht es auch anders. Praxiserprobte Tipps und Tricks zur sicheren „Containerisierung“ von Arbeitslasten verhelfen Docker in ruhige Gewässer.
Docker-Container „von der Stange“ sind eine Einladung zu Raubüberfällen. Zum Glück geht es auch anders: mit bewährten Best-Practices zum sicheren „Ein-Docken“ von Arbeitslasten.
Docker wirkt beinahe wie ein Magnet für Angriffe aus dem Cyberspace. Das Absichern einer Docker-Umgebung erfordert sowohl eine gehörige Dosis gesunden Menschenverstands als auch eine Menge administrativer Kleinarbeit.
Container unter Beschuss? Die Anatomie einer Attacke
Hacker zielen besonders gerne auf Docker-Server ab, die durch Konfigurationsfehler „glänzen“. Eine aktuelle Kampagne, die sich durch Crypto-Mining mit Hilfe der kompromittierten Systeme finanziert, haben Forscher von Trend Micro untersucht.
Die Angreifer missbrauchen die REST-API von Docker, um eigene Container auf einem verwundbaren Server einzurichten. Der betroffene Host bezieht ein bösartiges Docker-Image von Docker Hub und initialisiert damit einen neuen Container. Dieser macht dann den Rest von selbst mit Tools wie ZMap, Container-Escape-Skripten, Rootkits, Credential-Stealern und zu guter Letzt Coin-Minern.
Bei den Cyber-Dieben klingelt die Kasse, während sich die betroffene Organisation über die astronomische Rechnung für die eigene Cloud-Infrastruktur oder die ebenso hohe „an-den-Anschlag“-Auslastung der eigenen Hardware wundert.
„Das kann bei uns nie passieren“. Wirklich? Im Spätsommer 2021 haben Sicherheitsforscher fünf bösartige Docker-Container-Images auf Docker Hub entdeckt – Haare sträubend, wenn man die reelle Verbreitung der resultierenden Container ins Auge fasst. Die kompromittierten Images brachten es zusammen auf über 120.000 Pull-Anfragen (in Worten: ein hundert zwanzig tausend).
Was Hacker mit Docker so alles anstellen können, spottet jeder Beschreibung:
auf das Dateisystem des Docker-Hosts und gemountete Volumes zugreifen
das interne Netzwerk scannen
Anmeldeinformationen absahnen und andere Daten exfiltrieren
ein Botnet einrichten, Container „anwerben“ und Angriffe gegen Dritte mit maskierten IPs abfeuern
„Dienste“ für Phishing-Kampagnen und Malware hosten
und dergleichen anderes.
In totaler Verzweiflung sind einige Nutzer auf Alternativen wie mitlxc/podman ausgewichen. Doch so weit muss man gar nicht gehen. Docker lässt sich durchaus absichern – wenn man weiß, wie.
1. Den Socket des Docker-Daemons niemals offenlegen
Ein Daemon-Socket sollte niemals für Remote-Verbindungen verfügbar sein, außer beim Einsatz eines authentifizierungsfähigen HTTPS-Sockets.
Der Docker-Daemon-Socket ist ein Unix-Netzwerksocket für die Kommunikation mit der Docker-API. Der Eigentümer des Sockets ist standardmäßig der Superuser root. Greift ein anderer Linux-Nutzer auf den Socket zu, verschafft er sich die gleichen Berechtigungen wie der Superuser auf dem Host.
Es ist im Übrigen möglich, den Socket des Daemons an eine Netzwerkschnittstelle zu binden, um den Docker-Container für Fernzugriffe zugänglich zu machen. Diese viel zu offenherzige Option kann vor allem bei Containern in der Produktionsumgebung leicht nach hinten los gehen.
Docker-Images sollte man niemals mit einer Option wie -v initialisieren, also eben nicht mittels:
/var/run/docker.sock://var/run/docker.sock
Diese Option würde den Socket im resultierenden Container offenlegen. Cyber-Täter lassen sich bei so einem kardinalen Fehler nicht erst zwei Mal bitten.
2. Auf privilegierte Container verzichten
Privilegierte Container – also jene, die mit root-Rechten initialisiert wurden – zählen zu den größten Quellen allen Übels. Sie erlauben nämlich den Root-Zugriff auf alle Systemgeräte (devices) von einem Container heraus, können Linux-Sicherheitsmodule wie AppArmor und SELinux manipulieren. Sie können sogar den Kernel des Host-Systems dazu verleiten, eine neue Instanz der Docker-Plattform einzurichten, um Docker innerhalb von Docker auszuführen und sich so der Überwachung durch Sicherheitstools auf der Systemebene entziehen.
Ein Angreifer kann von einem solchen kompromittierten Container heraus seine Privilegien „hochschrauben“ und sich den root-Zugriff auf ganze Knoten und Cluster verschaffen.
Um zu überprüfen, ob ein Container im privilegierten Modus läuft, hilft der Befehl:
docker inspect --format =''[container_id]
Der Befehl gibt true zurück, wenn der Container privilegiert ist, oder eine Fehlermeldung aus. Wer keine Fehlermeldung bekommt, muss also die Ärmel hochkrempeln und die Konfiguration abdichten, sodass Docker im rootless-Modus läuft.
3. Docker im Rootless-Modus ausführen
Mit dem rootless-Modus bietet Docker eine Möglichkeit, Docker-Daemons und -Container als Nicht-Root-Benutzer auszuführen, um Schwachstellen der Container-Laufzeit und der Daemons zu entschärfen.
Im rootless-Modus laufen nämlich Docker-Daemons und -Container im Benutzernamensraum, ohne root-Rechte. Das steht im Kontrast zum userns-remap-Modus, bei dem der Daemon leichtsinnigerweise mit Root-Rechten läuft.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel IT-Medien GmbH, Max-Josef-Metzger-Straße 21, 86157 Augsburg, einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von Newslettern und Werbung nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung.
Um Container im rootless-Modus auszuführen, muss man Docker verwirrenderweise dennoch mit Root-Rechten des Host-Systems installieren. Es werden außerdem zusätzliche Module benötigt, und zwar unter anderem newuidmap und newgidmap aus dem Package uidmap sowie das Package dbus-user-session. Dann gelingt nämlich die Initialisierung des Daemons mittels:
systemctl --user start docker
und entsprechend:
systemctl --user enable docker
Das Ausführen des Docker-Daemons als systemweiten Dienstes im rootless-Modus wird nicht unterstützt.
Für den Docker-Client ist es erforderlich, entweder den Pfad zum Socket oder den CLI-Kontext zu spezifizieren, konkret also entweder:
Um das Schlimmste zu verhindern, empfiehlt es sich, die Zuweisung von Ressourcen der CPU und des Arbeitsspeichers zu Containern zu limitieren. Die Standardkonfiguration ist in diesem Punkt relativ leichtsinnig. Denn bereits ein einziger Container kann das RAM und die CPU des Hosts voll bis an den Anschlag auslasten.
Um die maximale Speichernutzung eines Containers zu begrenzen, fügen Sie dem Befehl
docker run
die Option --memory hinzu, zum Beispiel:
sudo docker run -it --memory="1g" dockerimage
Damit der Container nicht aus dem Speicher läuft, kommt der Parameter --memory-swap zum Einsatz:
sudo docker run -it --memory="1g" --memory-swap="2g" dockerimage
Beim Erreichen der Speicherbegrenzung schreibt der Container jetzt auf den lokalen Datenspeicher statt in den Arbeitsspeicher. Das führt zu einem Performance-Verlust der betreffenden Anwendung, beeinträchtigt jedoch nicht die Leistungsfähigkeit anderer Prozesse auf dem Host (es sei denn, sie müssen auch kräftig swappen, was ja natürlich nicht sein sollte; Swappen ist nicht der Sinn der Übung, sondern ein Workaround).
Der Parameter --cpu-shares beschränkt die zulässige „Teilhabe“ des Containers an den CPU-Zyklen des Hosts. Mit der Option --cpus lässt sich der Container auf die gewünschte Anzahl von CPU-Kernen beschränken.
Ressourcenkontingente helfen, die Auswirkungen einer Sicherheitsverletzung zu minimieren, und sei es nur, damit sich für die Angreifer das Crypto-Mining nicht rechnet, da sie andere Arbeitslasten nicht mehr verdrängen können.
5. Images nach Verwundbarkeiten und Secrets durchscannen
Docker-Images können sensible Zugangsinformationen, die sogenannten Secrets, beinhalten, und Verwundbarkeiten einschleusen.
Beim Scannen von zweitausend öffentlichen Images hat GitGuardian in sieben Prozent mindestens ein Secret ausfindig machen können. Diese Geheimnisse fanden ihren Weg in Container-Images durch ungeprüften Quellcode und gestapelte Images mit Supply-Chain-Lecks (Verwundbarkeiten aus Abhängigkeiten).
Container erben unter anderem auch die Fehlkonfigurationen, Malware und andere Probleme. Es empfiehlt sich, nur signierte Images zu verwenden und selbst diese nach Bedrohungen durchzuscannen, bevor sie mit der Initialisierung von Containern in die Produktionspipeline hineinfließen (Stichwort: shift left). Das minimiert die Angriffsfläche.
Einige der beliebtesten Verwundbarkeitsscanner sind quelloffen, darunter Anchore Engine, CoreOS/Clair, Vuls.io und OpenSCAP.
6. Container auf dem Host-System isolieren
Das Host-Betriebssystem sollte Container von Hacking-Eskapaden schützen und eine gegenseitige Beeinflussung der Prozesse verhindern. Linux-Features wie Namensräume (die Grundlage der Container-Isolation), SELinux (eine zusätzliche Sicherheitsebene in der Red Hat-Familie) oder AppArmor (eine Kernel-Erweiterung in Debian-Derivaten), Cgroups (ein Kontrollmechanismus der Ressourcennutzung), Linux-Capabilities (prozessspezifische Berechtigungen) und seccomp (Secure Computing Mode des Linux-Kernels kann Systemaufrufe unterbinden) zählen zu den bewährtesten Tools des Host-Betriebssystems. Sie können Docker-Container auf einem Host in ihre Schranken weisen.
7. Container im Netzwerk abschotten
Damit Docker-Container über die Netzwerkschnittstellen des Hosts mit der Außenwelt kommunizieren können, muss eine Netzwerkschicht vermitteln. Alle Docker-Hosts verfügen hierzu über die unsichere Standard-Bridge. Wer für neue Container nicht explizit ein anderes Netzwerk vorschreibt, verbinden sich diese automatisch eben mit der Standard-Bridge. Das ist suboptimal, um nicht zu sagen leichtsinnig.
Container sollten nur dann eine Verbindung zueinander herstellen können, wenn sich das auf Grund ihrer Aufgabe nicht vermeiden lässt. Sicherheitskritische Container sind ohne direkten Zugang zu öffentlichen Netzwerken besser aufgehoben, als wenn sie mit dem Internet „plaudern“ können.
Docker-Nutzern sei empfohlen, eigene Bridge-Netzwerke einzurichten. Die ist erforderlich, um die Kommunikation der Container untereinander in den Griff zu bekommen, und um die automatische DNS-Auflösung von Containernamen zu IP-Adressen zu aktivieren. Der Nutzer kann beliebig viele Netzwerke anlegen und konkret spezifizieren, mit welchen Netzwerken sich jeder Container verbinden darf (falls überhaupt).
Für unterschiedliche Nutzungsszenarien hat Docker unterschiedliche eigene Netzwerktreiber, darunter: Bridge, Overlay, ipvlan und Macvlan.
Implementierungsbeispiel für den Netzwerkmodus IPvlan 802.1q trunk L2 zur Umsetzung von abgesicherten Kreditkartentransaktionen in Docker.
(Bild: Docker)
Eine Bridge verbindet Standalone-Container. Der Overlay-Netzwerktreiber erstellt ein verteiltes Netzwerk zwischen mehreren Docker-Hosts, oberhalb der hostspezifischen Netzwerke, zur Bereitstellung von Swarm-Diensten. Ein ipvlan-Netzwerk gibt dem Nutzer die ultimative Kontrolle über IPv4- und IPv6-Adressen. Der Macvlan-Treiber ruft ein per-Host-konfiguriertes Netzwerk mit nur lokaler Reichweite ins Leben.
Zusätzliche Netzwerk-Plugins zur Integration von Docker mit spezialisierten Netzwerk-Stacks sind auch von Drittanbietern verfügbar. Der Nutzer kann im Übrigen auch eigene Plug-Ins erstellen.
8. Containern Schreibzugriffe entziehen
Ein einfacher und wirksamer Sicherheitstrick besteht darin, Container mit einem schreibgeschützten Dateisystem zu initialisieren, zum Beispiel mit Docker CLI:
docker run --read-only [image-name]
Nach dem Neustart des Dienstes ist das Dateisystem des Containers nur für Lesezugriffe zugänglich.
Einige Anwendungen kommen jedoch ohne Schreibzugriffe nicht aus. Um Fehlfunktionen zu verhindern, kann man Docker mit dem Parameter tmpfs einen isolierten Speicherort für Schreibzugriffe bereitstellen, zum Beispiel:
docker run --read-only --tmpfs /run/nginx --tmpfs /run/lock [image]
Dieser Ansatz kann böswillige Aktivitäten wie das Einschleusen von Malware in den Container oder das Abändern der Konfiguration verhindern, ohne dass sich die betroffene Anwendung „beschweren“ kann.
Im Gegensatz zu Volumes und Bind-Mounts lassen sich tmpfs-Mounts nicht für andere Container freigeben.
9. Aktualisieren, aktualisieren, aktualisieren...
Doch alles bringt nichts, wenn die Software mit den verfügbaren Aktualisierungen für Zero-Day-Exploits nicht Schritt hält. Das gilt sowohl für die Docker-Engine als auch das zugrundeliegende Host-Betriebssystem.
Fazit
Docker-Container „von der Stange“ sind eine Einladung zu Raubüberfällen. Zum Glück geht es auch anders: mit bewährten Best-Practices zum sicheren „Ein-Docken“ von Arbeitslasten.
Über die Autoren: Anna Kobylinska und Filipe Pereira Martins arbeiten für McKinley Denali Inc. (USA).