Docker Security
Last updated
Lernen und üben Sie AWS-Hacking: HackTricks Training AWS Red Team Expert (ARTE) Lernen und üben Sie GCP-Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Verwenden Sie Trickest, um einfach Workflows zu erstellen und zu automatisieren, die von den weltweit fortschrittlichsten Community-Tools unterstützt werden. Heute Zugriff erhalten:
Die Docker-Engine verwendet die Namespaces und Cgroups des Linux-Kernels, um Container zu isolieren und bietet eine grundlegende Sicherheitsebene. Zusätzlicher Schutz wird durch das Abwerfen von Fähigkeiten, Seccomp und SELinux/AppArmor geboten, um die Containerisolierung zu verbessern. Ein Authentifizierungs-Plugin kann Benutzeraktionen weiter einschränken.
Die Docker-Engine kann entweder lokal über einen Unix-Socket oder remote über HTTP zugegriffen werden. Für den Remote-Zugriff ist es wichtig, HTTPS und TLS zu verwenden, um Vertraulichkeit, Integrität und Authentifizierung sicherzustellen.
Die Docker-Engine hört standardmäßig auf den Unix-Socket unter unix:///var/run/docker.sock
. Auf Ubuntu-Systemen sind die Startoptionen von Docker in /etc/default/docker
definiert. Um den Remote-Zugriff auf die Docker-API und den Client zu ermöglichen, öffnen Sie den Docker-Daemon über einen HTTP-Socket, indem Sie die folgenden Einstellungen hinzufügen:
Jedoch wird das Freigeben des Docker-Daemons über HTTP aufgrund von Sicherheitsbedenken nicht empfohlen. Es ist ratsam, Verbindungen mit HTTPS zu sichern. Es gibt zwei Hauptansätze zur Sicherung der Verbindung:
Der Client überprüft die Identität des Servers.
Sowohl der Client als auch der Server authentifizieren gegenseitig die Identität des anderen.
Zur Bestätigung der Identität eines Servers werden Zertifikate verwendet. Für detaillierte Beispiele beider Methoden siehe diesen Leitfaden.
Container-Images können in privaten oder öffentlichen Repositories gespeichert werden. Docker bietet mehrere Speicheroptionen für Container-Images:
Docker Hub: Ein öffentlicher Registrierungsdienst von Docker.
Docker Registry: Ein Open-Source-Projekt, das es Benutzern ermöglicht, ihr eigenes Register zu hosten.
Docker Trusted Registry: Das kommerzielle Registrierungsangebot von Docker mit benutzerbasierter Authentifizierung und Integration mit LDAP-Verzeichnisdiensten.
Container können Sicherheitslücken aufweisen, entweder aufgrund des Basisimages oder der auf dem Basisimage installierten Software. Docker arbeitet an einem Projekt namens Nautilus, das Sicherheitsscans von Containern durchführt und die Sicherheitslücken auflistet. Nautilus funktioniert, indem es jedes Container-Image-Layer mit dem Schwachstellen-Repository vergleicht, um Sicherheitslücken zu identifizieren.
Für weitere Informationen lesen Sie dies.
docker scan
Der Befehl docker scan
ermöglicht es Ihnen, vorhandene Docker-Images mithilfe des Bildnamens oder der ID zu scannen. Führen Sie beispielsweise den folgenden Befehl aus, um das Image hello-world zu scannen:
Die Signierung von Docker-Images gewährleistet die Sicherheit und Integrität von Images, die in Containern verwendet werden. Hier ist eine zusammengefasste Erklärung:
Um Docker Content Trust zu aktivieren, setzen Sie export DOCKER_CONTENT_TRUST=1
. Diese Funktion ist standardmäßig in Docker Version 1.10 und höher deaktiviert.
Mit dieser Funktion können nur signierte Images heruntergeladen werden. Das Initiieren des ersten Image-Push erfordert das Festlegen von Passphrasen für die Root- und Tagging-Schlüssel, wobei Docker auch Yubikey zur Verbesserung der Sicherheit unterstützt. Weitere Details finden Sie hier.
Der Versuch, ein nicht signiertes Image mit aktiviertem Content Trust herunterzuladen, führt zu einem Fehler "Keine Vertrauensdaten für latest".
Für Image-Pushes nach dem ersten fordert Docker die Passphrase des Repository-Schlüssels an, um das Image zu signieren.
Um Ihre privaten Schlüssel zu sichern, verwenden Sie den Befehl:
Beim Wechseln von Docker-Hosts ist es notwendig, die Root- und Repository-Schlüssel zu verschieben, um den Betrieb aufrechtzuerhalten.
Verwenden Sie Trickest, um einfach Workflows zu erstellen und zu automatisieren, die von den fortschrittlichsten Community-Tools der Welt unterstützt werden. Erhalten Sie noch heute Zugriff:
Namespaces sind ein Feature des Linux-Kernels, das Kernelressourcen partitioniert, sodass eine Gruppe von Prozessen einen Satz von Ressourcen sieht, während eine andere Gruppe von Prozessen einen anderen Satz von Ressourcen sieht. Das Feature funktioniert, indem für einen Satz von Ressourcen und Prozessen der gleiche Namespace vorhanden ist, aber diese Namespaces beziehen sich auf unterschiedliche Ressourcen. Ressourcen können in mehreren Bereichen existieren.
Docker verwendet die folgenden Linux-Kernel-Namespaces, um die Isolierung von Containern zu erreichen:
pid-Namespace
mount-Namespace
Netzwerk-Namespace
ipc-Namespace
UTS-Namespace
Für weitere Informationen zu den Namespaces siehe die folgende Seite:
NamespacesDas Linux-Kernel-Feature cgroups bietet die Möglichkeit, Ressourcen wie CPU, Speicher, IO, Netzwerkbandbreite unter einer Gruppe von Prozessen zu beschränken. Docker ermöglicht die Erstellung von Containern unter Verwendung des cgroup-Features, das eine Ressourcensteuerung für den spezifischen Container ermöglicht. Im Folgenden wird ein Container erstellt, dessen Benutzerspeicher auf 500m begrenzt ist, der Kernelspeicher auf 50m begrenzt ist, der CPU-Anteil auf 512, und das Blkioweight auf 400. Der CPU-Anteil ist ein Verhältnis, das die CPU-Nutzung des Containers steuert. Er hat einen Standardwert von 1024 und liegt zwischen 0 und 1024. Wenn drei Container den gleichen CPU-Anteil von 1024 haben, kann jeder Container bei CPU-Ressourcenkonflikten bis zu 33 % der CPU nutzen. blkio-weight ist ein Verhältnis, das die IO des Containers steuert. Es hat einen Standardwert von 500 und liegt zwischen 10 und 1000.
Um die cgroup eines Containers zu erhalten, können Sie Folgendes tun:
Für weitere Informationen siehe:
CGroupsBerechtigungen ermöglichen eine genauere Kontrolle über die Berechtigungen, die für den Root-Benutzer zugelassen werden können. Docker verwendet das Linux-Kernel-Berechtigungsmerkmal, um die Operationen zu begrenzen, die innerhalb eines Containers durchgeführt werden können, unabhängig vom Typ des Benutzers.
Wenn ein Docker-Container ausgeführt wird, verwirft der Prozess sensible Berechtigungen, die der Prozess verwenden könnte, um aus der Isolation auszubrechen. Dies soll sicherstellen, dass der Prozess keine sensiblen Aktionen ausführen und ausbrechen kann:
Linux CapabilitiesDies ist eine Sicherheitsfunktion, die es Docker ermöglicht, die Systemaufrufe zu begrenzen, die innerhalb des Containers verwendet werden können:
SeccompAppArmor ist eine Kernel-Erweiterung, um Container auf eine begrenzte Menge von Ressourcen mit pro-Programm-Profilen zu beschränken.:
AppArmorBeschriftungssystem: SELinux weist jedem Prozess und Dateisystemobjekt ein eindeutiges Label zu.
Richtliniendurchsetzung: Es setzt Sicherheitsrichtlinien durch, die definieren, welche Aktionen ein Prozesslabel auf anderen Labels im System ausführen kann.
Container-Prozesslabels: Wenn Container-Engines Containerprozesse initiieren, erhalten sie in der Regel ein eingeschränktes SELinux-Label, üblicherweise container_t
.
Dateibeschriftung innerhalb von Containern: Dateien innerhalb des Containers sind normalerweise als container_file_t
gekennzeichnet.
Richtlinienregeln: Die SELinux-Richtlinie stellt hauptsächlich sicher, dass Prozesse mit dem Label container_t
nur mit Dateien interagieren (lesen, schreiben, ausführen) können, die als container_file_t
gekennzeichnet sind.
Dieser Mechanismus stellt sicher, dass selbst wenn ein Prozess innerhalb eines Containers kompromittiert ist, er nur mit Objekten interagieren kann, die über die entsprechenden Labels verfügen, was das potenzielle Schadensausmaß solcher Kompromittierungen erheblich einschränkt.
SELinuxIn Docker spielt ein Autorisierungsplugin eine entscheidende Rolle für die Sicherheit, indem es entscheidet, ob Anfragen an den Docker-Daemon zugelassen oder blockiert werden sollen. Diese Entscheidung wird durch die Prüfung von zwei Schlüsselkontexten getroffen:
Authentifizierungskontext: Dies umfasst umfassende Informationen über den Benutzer, wie wer sie sind und wie sie sich authentifiziert haben.
Befehlskontext: Dies umfasst alle relevanten Daten, die mit der gestellten Anfrage zusammenhängen.
Diese Kontexte helfen sicherzustellen, dass nur legitime Anfragen von authentifizierten Benutzern verarbeitet werden, was die Sicherheit der Docker-Operationen erhöht.
AuthZ& AuthN - Docker Access Authorization PluginWenn Sie die Ressourcen, die ein Container verwenden kann, nicht ordnungsgemäß begrenzen, könnte ein kompromittierter Container den Host, auf dem er läuft, DoS-angreifen.
CPU-DoS
Bandbreiten-DoS
Auf der folgenden Seite können Sie lernen, was das --privileged
-Flag bedeutet:
Wenn Sie einen Container ausführen, in dem ein Angreifer Zugriff als Benutzer mit niedrigen Berechtigungen erhält. Wenn Sie eine falsch konfigurierte SUID-Binärdatei haben, kann der Angreifer sie missbrauchen und Berechtigungen innerhalb des Containers eskaliert, was es ihm ermöglichen könnte, daraus zu entkommen.
Das Ausführen des Containers mit der Option no-new-privileges
aktiviert wird diese Art von Berechtigungserweiterung verhindern.
Für weitere --security-opt
-Optionen siehe: https://docs.docker.com/engine/reference/run/#security-configuration
Es ist entscheidend, Geheimnisse nicht direkt in Docker-Images einzubetten oder Umgebungsvariablen zu verwenden, da diese Methoden Ihre sensiblen Informationen für jeden freigeben, der über Befehle wie docker inspect
oder exec
Zugriff auf den Container hat.
Docker-Volumes sind eine sicherere Alternative, die empfohlen wird, um auf sensible Informationen zuzugreifen. Sie können als temporäres Dateisystem im Speicher genutzt werden, um die Risiken im Zusammenhang mit docker inspect
und Logging zu mindern. Allerdings können Root-Benutzer und solche mit exec
-Zugriff auf den Container immer noch auf die Geheimnisse zugreifen.
Docker-Secrets bieten eine noch sicherere Methode zur Behandlung sensibler Informationen. Für Fälle, in denen während der Image-Build-Phase Geheimnisse erforderlich sind, bietet BuildKit eine effiziente Lösung mit Unterstützung für Buildzeit-Geheimnisse, die die Build-Geschwindigkeit verbessern und zusätzliche Funktionen bereitstellen.
Um BuildKit zu nutzen, kann es auf drei Arten aktiviert werden:
Über eine Umgebungsvariable: export DOCKER_BUILDKIT=1
Durch Voranstellen von Befehlen: DOCKER_BUILDKIT=1 docker build .
Durch Aktivierung als Standard in der Docker-Konfiguration: { "features": { "buildkit": true } }
, gefolgt von einem Neustart von Docker.
BuildKit ermöglicht die Verwendung von Buildzeit-Geheimnissen mit der --secret
-Option, um sicherzustellen, dass diese Geheimnisse nicht im Image-Build-Cache oder im endgültigen Image enthalten sind, unter Verwendung eines Befehls wie:
Für benötigte Geheimnisse in einem laufenden Container bieten Docker Compose und Kubernetes robuste Lösungen. Docker Compose verwendet einen secrets
-Schlüssel in der Service-Definition zur Spezifizierung von Geheimdateien, wie in einem docker-compose.yml
-Beispiel gezeigt:
Diese Konfiguration ermöglicht die Verwendung von Secrets beim Starten von Diensten mit Docker Compose.
In Kubernetes-Umgebungen werden Secrets nativ unterstützt und können mit Tools wie Helm-Secrets weiter verwaltet werden. Die rollenbasierte Zugriffskontrolle (RBAC) von Kubernetes verbessert die Sicherheit des Secret-Managements, ähnlich wie bei Docker Enterprise.
gVisor ist ein Anwendungskernel, der in Go geschrieben ist und einen erheblichen Teil der Linux-Systemoberfläche implementiert. Er enthält einen Open Container Initiative (OCI)-Laufzeitumgebung namens runsc
, die eine Isolierungsgrenze zwischen der Anwendung und dem Host-Kernel bereitstellt. Die runsc
-Laufzeitumgebung integriert sich mit Docker und Kubernetes und macht es einfach, Sandbox-Container auszuführen.
Kata Containers ist eine Open-Source-Community, die daran arbeitet, eine sichere Container-Laufzeitumgebung mit leichten virtuellen Maschinen zu erstellen, die sich wie Container anfühlen und verhalten, aber eine stärkere Workload-Isolierung unter Verwendung der Hardware-Virtualisierungstechnologie als zweite Verteidigungsebene bieten.
Verwenden Sie nicht das --privileged
-Flag oder binden Sie einen Docker-Socket innerhalb des Containers ein. Der Docker-Socket ermöglicht das Starten von Containern und ist daher ein einfacher Weg, um die volle Kontrolle über den Host zu übernehmen, beispielsweise durch das Ausführen eines anderen Containers mit dem --privileged
-Flag.
Führen Sie nicht als Root innerhalb des Containers aus. Verwenden Sie einen anderen Benutzer und Benutzernamensräume. Der Root im Container ist derselbe wie auf dem Host, es sei denn, er wird mit Benutzernamensräumen neu zugeordnet. Er wird nur leicht durch Linux-Namespaces, Fähigkeiten und cgroups eingeschränkt.
Verwerfen Sie alle Fähigkeiten (--cap-drop=all
) und aktivieren Sie nur die erforderlichen (--cap-add=...
). Viele Workloads benötigen keine Fähigkeiten, und das Hinzufügen erhöht den Umfang eines potenziellen Angriffs.
Verwenden Sie die Sicherheitsoption "no-new-privileges", um zu verhindern, dass Prozesse mehr Berechtigungen erlangen, beispielsweise durch suid-Binärdateien.
Begrenzen Sie die Ressourcen, die dem Container zur Verfügung stehen. Ressourcenbeschränkungen können die Maschine vor Denial-of-Service-Angriffen schützen.
Passen Sie Seccomp, AppArmor (oder SELinux)-Profile an, um die Aktionen und Systemaufrufe, die für den Container verfügbar sind, auf das erforderliche Minimum zu beschränken.
Verwenden Sie offizielle Docker-Images und verlangen Sie Signaturen oder erstellen Sie eigene Images basierend darauf. Vererben oder verwenden Sie keine mit Hintertüren versehenen Images. Speichern Sie auch Root-Schlüssel und Passphrasen an einem sicheren Ort. Docker plant, Schlüssel mit UCP zu verwalten.
Erstellen Sie regelmäßig Ihre Images neu, um Sicherheitspatches auf dem Host und den Images anzuwenden.
Verwalten Sie Ihre Secrets klug, damit es für den Angreifer schwierig ist, darauf zuzugreifen.
Wenn Sie den Docker-Daemon freigeben, verwenden Sie HTTPS mit Client- und Serverauthentifizierung.
Verwenden Sie in Ihrem Dockerfile COPY anstelle von ADD. ADD extrahiert automatisch komprimierte Dateien und kann Dateien von URLs kopieren. COPY verfügt nicht über diese Funktionen. Vermeiden Sie nach Möglichkeit die Verwendung von ADD, um nicht anfällig für Angriffe über Remote-URLs und Zip-Dateien zu sein.
Verwenden Sie getrennte Container für jeden Mikrodienst.
Fügen Sie kein ssh in den Container ein, "docker exec" kann verwendet werden, um eine SSH-Verbindung zum Container herzustellen.
Verwenden Sie kleinere Container-Images.
Wenn Sie innerhalb eines Docker-Containers sind oder Zugriff auf einen Benutzer in der Docker-Gruppe haben, könnten Sie versuchen, auszubrechen und Berechtigungen zu eskalieren:
Docker Breakout / Privilege EscalationWenn Sie Zugriff auf den Docker-Socket haben oder Zugriff auf einen Benutzer in der Docker-Gruppe haben, aber Ihre Aktionen durch ein Docker-Authentifizierungsplugin eingeschränkt sind, überprüfen Sie, ob Sie es umgehen können:
AuthZ& AuthN - Docker Access Authorization PluginDas Tool docker-bench-security ist ein Skript, das Dutzende gängiger Best Practices für das Bereitstellen von Docker-Containern in der Produktion überprüft. Die Tests sind alle automatisiert und basieren auf dem CIS Docker Benchmark v1.3.1. Sie müssen das Tool vom Host ausführen, auf dem Docker ausgeführt wird, oder von einem Container mit ausreichenden Berechtigungen. Erfahren Sie, wie Sie es in der README ausführen: https://github.com/docker/docker-bench-security.
Verwenden Sie Trickest, um mühelos Workflows zu erstellen und zu automatisieren, die von den weltweit fortschrittlichsten Community-Tools unterstützt werden. Erhalten Sie noch heute Zugriff:
Lerne und übe AWS-Hacking: HackTricks Training AWS Red Team Expert (ARTE) Lerne und übe GCP-Hacking: HackTricks Training GCP Red Team Expert (GRTE)