Warum sind Sie hier?
Sie möchten die echte Antwort auf zwei Fragen zur Docker-Sicherheit wissen:
Ist Docker sicher für den Produktionseinsatz?
Ja und nein. Docker verwendet ein Sicherheitsmodell, das auf Namespaces und Ressourcenisolierung basiert, wodurch die darin enthaltenen Prozesse vor spezifischen Angriffen sicherer sind, als wenn Sie Ihre Anwendungen direkt von einer Cloud-VM oder einem Bare-Metal-System ausführen. Trotz dieser Schicht gibt es immer noch viele Möglichkeiten für Angreifer, auf Ihren Container zuzugreifen, wodurch sie vertrauliche Informationen lesen, Denial-of-Service (DoS)-Angriffe durchführen oder sogar Root-Zugriff auf das Host-System erlangen können.
Wie kann ich meine Docker-Sicherheit verbessern (auf nicht allzu schmerzhafte Weise)?
Wir führen Sie durch die häufigsten und schwerwiegendsten Docker-Schwachstellen und überspringen dabei die grundlegenden Empfehlungen, die Sie überall bei Google finden, wie die Verwendung offizieller Images und die Aktualisierung Ihres Hosts. Stattdessen zeigen wir Ihnen direkt neue Docker-Optionen und Dockerfile-Zeilen, die Ihre neue Standard-Docker-Container-Bereitstellung sicherer denn je machen werden.

Die „No-BS“-Docker-Sicherheits-Checkliste
Dateisysteme in Containern schreibgeschützt machen
Was gewinnen Sie?
Sie verhindern, dass ein Angreifer die Laufzeitumgebung Ihres Docker-Containers bearbeitet, was es ihm ermöglichen könnte, nützliche Informationen über Ihre Infrastruktur zu sammeln, Benutzerdaten zu erfassen oder direkt einen DoS- oder Ransomware-Angriff durchzuführen.
Wie richtet man es ein?
Sie haben zwei Optionen: entweder zur Laufzeit oder innerhalb Ihrer Docker Compose-Konfiguration.
Zur Laufzeit: docker run --read-only your-app:v1.0.1
In Ihrer Docker-Compose-Datei:
services:
webapp:
image: your-app:v1.0.1read_only: true
...Rechteausweitung sperren
Was gewinnen Sie?
Sie verhindern, dass Ihr Docker-Container – oder ein Angreifer, der sich darin zu schaffen macht – neue Privilegien, selbst auf Root-Ebene, mit setuid oder setgid aktivieren kann. Mit permissiverem Zugriff auf Ihren Container könnte ein Angreifer Anmeldeinformationen in Form von Passwörtern oder Schlüsseln zu verbundenen Teilen Ihrer Bereitstellung, wie einer Datenbank, erhalten.
Wie richtet man es ein?
Noch einmal, zur Laufzeit oder innerhalb Ihrer Docker Compose-Konfiguration.
Zur Laufzeit: docker run --security-opt=no-new-privileges your-app:v1.0.1
In Ihrer Docker-Compose-Datei:
services:
webapp:
image: your-app:v1.0.1
security_opt:
- no-new-privileges:true
...Ihre Container-zu-Container-Netzwerke isolieren
Was gewinnen Sie?
Standardmäßig lässt Docker alle Container über das docker0-Netzwerk kommunizieren, was einem Angreifer ermöglichen könnte, sich lateral von einem kompromittierten Container zu einem anderen zu bewegen. Wenn Sie diskrete Dienste haben A und B in Containern Y und Z, und da sie nicht direkt kommunizieren müssen, bietet die Isolation ihrer Netzwerke dasselbe EndBenutzererlebnis und verhindert gleichzeitig laterale Bewegungen für eine verbesserte Docker-Sicherheit.
Wie richtet man es ein?
Sie können Docker-Netzwerke zur Laufzeit oder in Ihrer Docker Compose-Konfiguration angeben. Zuerst müssen Sie jedoch das Netzwerk erstellen:
docker network create your-isolated-networkZur Laufzeit fügen Sie die --network Optionn: docker run --network your-isolated-network your-app:v1.0.1
Oder die entsprechende Option in Ihrer Docker Compose-Datei:
services:
webapp:
image: your-app:v1.0.1
networks:
- your-isolated-network
...Einen geeigneten Nicht-Root-Benutzer festlegen
Was gewinnen Sie?
Der StandardBenutzer innerhalb eines Containers ist root, mit einer UID von 0. Durch die Angabe eines separaten Benutzers verhindern Sie, dass ein Angreifer seine Privilegien auf einen anderen Benutzer eskaliert, der ohne Einschränkungen agieren kann, wie z.B. Root, was alle anderen Docker-Sicherheitsmaßnahmen, die Sie mühsam implementiert haben, außer Kraft setzen würde.
Wie richtet man es ein?
Erstellen Sie Ihren Benutzer während des Build-Prozesses oder zur Laufzeit. Zur Laufzeit können Sie den Benutzer entweder zum ersten Mal erstellen oder den Benutzer bereits beim Build festgelegt.
Während des Build-Prozesses, in Ihrem Dockerfile:
...
RUN groupadd -r your-user
RUN useradd -r -g your-user your-user
USER myuser
...Zur Laufzeit: docker run -u your-user your-app:v1.0.1
Herabsetzen von Linux-Kernel-Capabilities
Was gewinnen Sie?
Standardmäßig dürfen Docker-Container einen eingeschränkten Satz von Linux-Kernel-Capabilities verwenden. Man könnte meinen, die Entwickler bei Docker hätten diesen eingeschränkten Satz so konzipiert, dass er vollständig sicher ist, doch viele Capabilities existieren aus Gründen der Kompatibilität und Einfachheit. Standard-Container können beispielsweise willkürlich Dateibesitzrechte ändern, ihr Root-Verzeichnis wechseln, Prozess-UIDs manipulieren und Sockets lesen. Durch das Entfernen einiger oder aller dieser Capabilities minimieren Sie die Anzahl der Angriffsvektoren.
Wie richtet man es ein?
Sie können Capabilities zur Laufzeit entfernen und neue setzen. Zum Beispiel könnten Sie alle Kernel-Capabilities entfernen und Ihrem Container nur die Berechtigung geben, den Besitz bestehender Dateien zu ändern.
docker run --cap-drop ALL --cap-add CHOWN your-app:v1.0.1Oder für Docker Compose:
services:
webapp:
image: your-app:v1.0.1
cap_drop:
- ALL
cap_add:
- CHOWN
...Verhindert Fork-Bomben
Was gewinnen Sie?
Fork-Bomben sind eine Art von DoS-Angriff, der einen bestehenden Prozess unendlich repliziert. Zuerst reduzieren sie die Leistung und beschränken Ressourcen, was unweigerlich die Kosten erhöht und letztendlich Ihre Container oder das Host-System zum Absturz bringen kann. Sobald eine Fork-Bombe gestartet wurde, gibt es keine Möglichkeit, sie zu stoppen, außer den Container oder den Host neu zu starten.
Wie richtet man es ein?
Zur Laufzeit können Sie die Anzahl der Prozesse (PIDs) begrenzen, die Ihr Container erstellen kann.
docker run --pids-limit 99 your-app:v1.0.1Oder mit Docker Compose:
services:
webapp:
image: your-app:v1.0.1
deploy
limits:
pids: 99Verbessern Sie die Docker-Sicherheit durch Überwachung Ihrer Open-Source-Abhängigkeiten
Was gewinnen Sie?
Die Anwendungen, die Sie für die Bereitstellung mit Docker Containerisiert haben, haben wahrscheinlich einen breiten Abhängigkeitsbaum.
Wie richtet man es ein?
Der direkteste Weg ist mit Aikidos Open-Source-Scan von Softwareabhängigkeiten. Unsere kontinuierliche Überwachung scannt Projekte, die in mehr als einem Dutzend Sprachen geschrieben sind, basierend auf dem Vorhandensein von Lockfiles in Ihrer Anwendung und liefert einen sofortigen Überblick über Schwachstellen und Malware. Mit automatischem Triaging, das False Positives herausfiltert, gibt Ihnen Aikido sofort umsetzbare Empfehlungen zur Behebung von Problemen an die Hand… und das nicht erst, nachdem Sie ein Dutzend anderer Referenzdokumente und GitHub-Issues gelesen haben.
Bei Aikido schätzen wir etablierte Open-Source-Projekte wie Trivy, Syft und Grype. Wir wissen aber auch aus Erfahrung, dass ihre isolierte Nutzung keine besonders gute Developer Experience bietet. Unter der Haube erweitert Aikido diese Projekte mit Benutzerdefinierten Regeln, um Lücken zu schließen und Sicherheitslücken aufzudecken, die sonst unentdeckt blieben. Im Gegensatz zur Aneinanderreihung verschiedener Open-Source-Tools befreit Aikido Sie davon, ein Scanning-Skript zu erstellen oder einen Benutzerdefinierten Job in Ihrer CI/CD-Pipeline einzurichten.

Verwenden Sie nur vertrauenswürdige Images für die Docker-Sicherheit
Was gewinnen Sie?
Docker Content Trust (DCT) ist ein System zum Signieren und Validieren des Inhalts und der Integrität der offiziellen Images, die Sie aus Docker Registries wie Docker Hub ziehen. Das Ziehen nur von Images, die vom Autor signiert wurden, gibt Ihnen mehr Sicherheit, dass sie nicht manipuliert wurden, um Schwachstellen in Ihrem Deployment zu erzeugen.
Wie richtet man es ein?
Der einfachste Weg ist, die Umgebungsvariable in Ihrer Shell zu setzen, was Sie oder andere daran hindert, mit nicht vertrauenswürdigen Images zu arbeiten.
export DOCKER_CONTENT_TRUST=1
docker run ...Oder Sie können die Umgebungsvariable jedes Mal setzen, wenn Sie Docker ausführen:
DOCKER_CONTENT_TRUST=1 docker run …End-of-Life (EOL) Runtimes aktualisieren
Was gewinnen Sie?
Eine gängige Empfehlung für die Containersicherheit von Docker ist es, Images und Abhängigkeiten an eine bestimmte Version zu binden, anstatt aktuellste. Theoretisch verhindert dies, dass Sie unwissentlich neue Images verwenden, selbst solche, die manipuliert wurden und neue Schwachstellen einführen.
Wie richtet man es ein?
Es gibt Open-Source-Projekte, die Ihnen helfen, EOLs zu entdecken und sich optimal vorzubereiten. Das Projekt endoflife.date (GitHub-Repository) verfolgt über 300 Produkte, indem es Daten aus mehreren Quellen aggregiert und über eine öffentliche API zur Verfügung stellt. Mit endoflife.date und ähnlichen Projekten haben Sie mehrere Optionen:
- Überprüfen Sie das Projekt manuell auf Updates für Abhängigkeiten, von denen Ihre Anwendungen abhängen, und erstellen Sie Tickets oder Issues für erforderliche Updates.
- Schreiben Sie ein Skript (Bash, Python usw.), um die EOL-Daten von Abhängigkeiten von der API abzurufen und führen Sie es regelmäßig aus, wie einen Cron-Job.
- Integrieren Sie die öffentliche API oder das Benutzerdefinierte Skript in Ihre CI-Plattform, um Builds fehlschlagen zu lassen, die ein Projekt verwenden, das sich dem EOL nähert oder es erreicht hat.
Als Entwickelnde verstehen wir, dass Ihre Zeit wertvoll und oft begrenzt ist. Hier kann Aikido ein Gefühl der Sicherheit vermitteln – unsere EOL-Scanning-Funktion verfolgt Ihren Code und Ihre Container und priorisiert Runtimes mit der größten Auswirkung und Exposition, wie Node.js oder einen Nginx-Webserver. Wie gewohnt automatisieren wir nicht nur die Informationssammlung, sondern liefern auch Alerts mit angemessener Schwere, um Sie zu informieren und nicht zu überfordern.

Ressourcennutzung von Containern begrenzen
Was gewinnen Sie?
Standardmäßig haben Container keine Ressourcenbeschränkungen und nutzen so viel Speicher oder CPU, wie der Scheduler des Hosts zulässt. Die Begrenzung der Ressourcennutzung eines bestimmten Containers kann die Auswirkungen eines DoS-Angriffs minimieren. Anstatt Ihren Container oder Ihr Host-System aufgrund einer Out-of-Memory-Exception zum Absturz zu bringen, wirkt sich der laufende DoS-Angriff „nur“ negativ auf die EndBenutzererfahrung aus.
Wie richtet man es ein?
Zur Laufzeit können Sie die --memory und --cpus Option, um Limits für die Speicher- bzw. CPU-Nutzung festzulegen. Die Speicheroption akzeptiert Zahlen mit „g“ für Gigabyte und „m“ für Megabyte, während die CPU-Option die Begrenzung der dedizierten CPUs widerspiegelt, die für den Container und seine Prozesse verfügbar sind.
docker run --memory="1g" --cpus="2" your-app:v1.0.1Dies funktioniert auch mit Docker Compose:
services:
webapp:
image: your-app:v1.0.1
deploy:
limits:
cpus: '2'
memory: 1G
...Ihre finalen Befehls- und Compose-Optionen für Docker-Sicherheit
Inzwischen haben Sie sicherlich einige Docker-Sicherheitstipps und die dazugehörigen CLI-Optionen oder Konfigurationen gesehen, was bedeutet, dass Sie entweder sehr gespannt sind, diese umzusetzen, oder überfordert damit, wie Sie alles zusammenfügen sollen. Im Folgenden haben wir alle Empfehlungen in einem einzigen Befehls- oder Konfigurations-Template zusammengefasst, das Ihnen hilft, sofort sicherere Docker-Container bereitzustellen.
Offensichtlich möchten Sie einige der Optionen ändern – wie den Namen des Nicht-Root-Benutzers, Kernel-Fähigkeiten, Ressourcenlimits – basierend auf den Anforderungen Ihrer Anwendung.
export DOCKER_CONTENT_TRUST=1
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
... # OTHER OPTIONS GO HERE
your-app:v1.0.1Sie möchten vielleicht sogar einen drun-Alias mit der Shell Ihres Hosts erstellen, den Sie aufrufen können, ohne sich all diese Details merken zu müssen.
function drun {
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
$1 \
$2
}Führen Sie dann Ihren Alias wie folgt aus, mit Ihren Optionen und dem Image-Namen: drun -it your-app:v1.0.1
Wenn Sie ein Docker-Compose-Benutzer sind, können Sie all dieselben Optionen in ein neues Docker-Compose-Basistemplate übernehmen, das Sie zukünftig verwenden können:
services:
webapp:
image: your-app:v1.0.1
read_only: true
security_opt:
- no-new-privileges:true
networks:
- your-isolated-network
cap_drop:
- ALL
cap_add:
- CHOWN
deploy:
limits:
pids: 9
cpus: '2'
memory: 1G
... # OTHER OPTIONS GO HEREBonus: Docker mit rootless Containern ausführen
Wenn Sie Docker auf einem System installieren, arbeitet dessen Daemon mit Root-Berechtigungen. Selbst wenn Sie alle oben genannten Optionen aktivieren und die Privilegienerhöhung innerhalb eines Docker-Containers verhindern, verfügt der Rest der Container-Runtime auf Ihrem Host-System immer noch über Root-Berechtigungen. Das erweitert unweigerlich Ihre Angriffsfläche.
Die Lösung sind rootless Container, die von einem unprivilegierten Benutzer erstellt und verwaltet werden können. Der Verzicht auf Root-Rechte führt zu deutlich weniger Sicherheitsproblemen für Ihr Host-System.
Wir würden Ihnen gerne helfen, rootless Container mit einer einzigen Option oder einem Befehl zu nutzen, aber es ist leider nicht so einfach. Detaillierte Anweisungen finden Sie auf der Website für Rootless Container, einschließlich einer Anleitung für Docker.
Wie geht es weiter mit Ihrer Docker-Sicherheit?
Wenn Sie aus dieser Erfahrung etwas gelernt haben, dann, dass Containersicherheit ein langfristiges Unterfangen ist. Es gibt immer weitere Hardening-Checklisten und Deep-Dive-Artikel darüber, wie Sie Ihre Container in Docker oder dessen älterem und oft missverstandenem Cousin, Kubernetes, absichern können. Sie können unmöglich eine fehlerfreie Containersicherheit anstreben – stattdessen wird es sich langfristig auszahlen, in Ihrem vollen Entwicklungsplan Zeit für Sicherheit zu schaffen und dann inkrementelle Verbesserungen basierend auf Auswirkungen und Schweregrad vorzunehmen.
Um Sie dabei zu unterstützen, diesen kontinuierlichen Prozess zu maximieren und Fixes zu priorisieren, die Ihre Anwendungssicherheit maßgeblich verbessern, gibt es Aikido. Wir haben gerade eine Series A-Finanzierungsrunde über 17 Millionen US-Dollar für unsere „No-BS“-Developer-Security-Plattform abgeschlossen und würden uns freuen, Sie bei uns begrüßen zu dürfen.

