Docker Security
Last updated
Lernen & üben Sie AWS-Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lernen & ü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 fortschrittlichsten Community-Tools der Welt unterstützt werden. Zugang heute erhalten:
Der Docker-Engine verwendet die Namespaces und Cgroups des Linux-Kernels, um Container zu isolieren und bietet eine grundlegende Sicherheitsebene. Zusätzlicher Schutz wird durch Capabilities-Dropping, Seccomp und SELinux/AppArmor bereitgestellt, was die Container-Isolierung verbessert. Ein Auth-Plugin kann die Benutzeraktionen weiter einschränken.
Der 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.
Der Docker-Engine hört standardmäßig auf dem 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, exponieren Sie den Docker-Daemon über einen HTTP-Socket, indem Sie die folgenden Einstellungen hinzufügen:
Allerdings wird empfohlen, den Docker-Daemon über HTTP aufgrund von Sicherheitsbedenken nicht freizugeben. Es ist ratsam, Verbindungen mit HTTPS abzusichern. 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 ihre Identität.
Zertifikate werden verwendet, um die Identität eines Servers zu bestätigen. Für detaillierte Beispiele beider Methoden siehe diese Anleitung.
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 Registry zu hosten.
Docker Trusted Registry: Das kommerzielle Registrierungsangebot von Docker, das rollenbasierte Benutzerauthentifizierung und Integration mit LDAP-Verzeichnisdiensten bietet.
Container können Sicherheitsanfälligkeiten aufweisen, entweder aufgrund des Basis-Images oder aufgrund der auf dem Basis-Image installierten Software. Docker arbeitet an einem Projekt namens Nautilus, das Sicherheitsprüfungen von Containern durchführt und die Anfälligkeiten auflistet. Nautilus funktioniert, indem es jede Container-Image-Schicht mit einem Anfälligkeitsrepository vergleicht, um Sicherheitslücken zu identifizieren.
Für mehr Informationen lesen Sie dies.
docker scan
Der docker scan
Befehl ermöglicht es Ihnen, vorhandene Docker-Images mit dem Bildnamen oder der ID zu scannen. Führen Sie beispielsweise den folgenden Befehl aus, um das hello-world-Image zu scannen:
Docker-Image-Signierung gewährleistet die Sicherheit und Integrität von Bildern, die in Containern verwendet werden. Hier ist eine kurze Erklärung:
Um Docker Content Trust zu aktivieren, setze export DOCKER_CONTENT_TRUST=1
. Diese Funktion ist standardmäßig in Docker-Version 1.10 und höher deaktiviert.
Mit dieser aktivierten Funktion können nur signierte Bilder heruntergeladen werden. Der erste Bild-Upload erfordert die Festlegung von Passphrasen für die Root- und Tagging-Schlüssel, wobei Docker auch Yubikey für verbesserte Sicherheit unterstützt. Weitere Details sind hier zu finden.
Der Versuch, ein unsigniertes Bild mit aktiviertem Content Trust herunterzuladen, führt zu einem "No trust data for latest"-Fehler.
Für Bild-Uploads nach dem ersten Mal fragt Docker nach der Passphrase des Repository-Schlüssels, um das Bild zu signieren.
Um deine privaten Schlüssel zu sichern, verwende den Befehl:
Wenn Sie Docker-Hosts wechseln, 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. Zugang heute erhalten:
Namespaces sind ein Feature des Linux-Kernels, das Kernel-Ressourcen partitioniert, sodass eine Gruppe von Prozessen eine Gruppe von Ressourcen sieht, während eine andere Gruppe von Prozessen eine andere Gruppe von Ressourcen sieht. Das Feature funktioniert, indem es denselben Namespace für eine Gruppe von Ressourcen und Prozessen hat, aber diese Namespaces auf unterschiedliche Ressourcen verweisen. Ressourcen können in mehreren Räumen existieren.
Docker nutzt die folgenden Linux-Kernel-Namespaces, um die Container-Isolierung zu erreichen:
pid namespace
mount namespace
network namespace
ipc namespace
UTS namespace
Für weitere Informationen über die Namespaces besuchen Sie die folgende Seite:
NamespacesDie Linux-Kernel-Funktion 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 der cgroup-Funktion, die eine Ressourcensteuerung für den spezifischen Container ermöglicht. Nachfolgend ein Container, dessen Benutzerspeichermenge auf 500m, der Kernel-Speicher auf 50m, der CPU-Anteil auf 512 und der blkio-weight auf 400 begrenzt ist. Der CPU-Anteil ist ein Verhältnis, das die CPU-Nutzung des Containers steuert. Er hat einen Standardwert von 1024 und einen Bereich zwischen 0 und 1024. Wenn drei Container denselben CPU-Anteil von 1024 haben, kann jeder Container bis zu 33 % der CPU im Falle von CPU-Ressourcenkonflikten nutzen. blkio-weight ist ein Verhältnis, das das IO des Containers steuert. Es hat einen Standardwert von 500 und einen Bereich zwischen 10 und 1000.
Um die cgroup eines Containers zu erhalten, können Sie Folgendes tun:
Für weitere Informationen siehe:
CGroupsFähigkeiten ermöglichen eine genauere Kontrolle über die Fähigkeiten, die für den Root-Benutzer erlaubt sein können. Docker verwendet die Fähigkeit-Funktion des Linux-Kernels, um die Operationen zu begrenzen, die innerhalb eines Containers durchgeführt werden können, unabhängig von der Art des Benutzers.
Wenn ein Docker-Container ausgeführt wird, verliert der Prozess sensible Fähigkeiten, die der Prozess nutzen könnte, um aus der Isolation zu entkommen. Dies versucht sicherzustellen, dass der Prozess keine sensiblen Aktionen ausführen und entkommen kann:
Linux CapabilitiesDies ist eine Sicherheitsfunktion, die es Docker ermöglicht, die Syscalls zu begrenzen, die innerhalb des Containers verwendet werden können:
SeccompAppArmor ist eine Kernel-Erweiterung, um Container auf eine begrenzte Menge von Ressourcen mit programmbezogenen Profilen zu beschränken.:
AppArmorKennzeichnungssystem: SELinux weist jedem Prozess und jedem Dateisystemobjekt ein einzigartiges Label zu.
Durchsetzung von Richtlinien: Es setzt Sicherheitsrichtlinien durch, die definieren, welche Aktionen ein Prozesslabel auf anderen Labels im System ausführen kann.
Containerprozess-Labels: Wenn Container-Engines Containerprozesse initiieren, wird ihnen typischerweise ein eingeschränktes SELinux-Label, häufig container_t
, zugewiesen.
Dateikennzeichnung innerhalb von Containern: Dateien innerhalb des Containers werden 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), die als container_file_t
gekennzeichnet sind.
Dieser Mechanismus stellt sicher, dass selbst wenn ein Prozess innerhalb eines Containers kompromittiert wird, er auf die Interaktion mit Objekten beschränkt ist, die die entsprechenden Labels haben, was den potenziellen Schaden durch solche Kompromittierungen erheblich begrenzt.
SELinuxIn Docker spielt ein Autorisierungs-Plugin eine entscheidende Rolle für die Sicherheit, indem es entscheidet, ob Anfragen an den Docker-Daemon erlaubt oder blockiert werden. Diese Entscheidung wird getroffen, indem zwei wichtige Kontexte untersucht werden:
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 nutzen kann, nicht ordnungsgemäß begrenzen, könnte ein kompromittierter Container den Host, auf dem er läuft, DoS.
CPU DoS
Bandbreiten-DoS
Auf der folgenden Seite können Sie lernen, was der --privileged
-Flag impliziert:
Wenn Sie einen Container ausführen, in dem ein Angreifer es schafft, als Benutzer mit niedrigen Rechten Zugriff zu erhalten. Wenn Sie eine fehlerhaft konfigurierte SUID-Binärdatei haben, kann der Angreifer diese missbrauchen und die Privilegien innerhalb des Containers eskalieren. Dies könnte ihm ermöglichen, aus ihm zu entkommen.
Das Ausführen des Containers mit der aktivierten no-new-privileges
-Option wird diese Art der Privilegieneskalation 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, der Zugriff auf den Container hat, durch Befehle wie docker inspect
oder exec
offenlegen.
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, wodurch die Risiken im Zusammenhang mit docker inspect
und Protokollierung gemindert werden. Allerdings könnten Root-Benutzer und solche mit exec
-Zugriff auf den Container weiterhin auf die Geheimnisse zugreifen.
Docker-Secrets bieten eine noch sicherere Methode zur Handhabung sensibler Informationen. Für Instanzen, die während der Bildbauphase Geheimnisse benötigen, bietet BuildKit eine effiziente Lösung mit Unterstützung für Geheimnisse zur Bauzeit, die die Baugeschwindigkeit erhöht und zusätzliche Funktionen bereitstellt.
Um BuildKit zu nutzen, kann es auf drei Arten aktiviert werden:
Durch eine Umgebungsvariable: export DOCKER_BUILDKIT=1
Durch das Voranstellen von Befehlen: DOCKER_BUILDKIT=1 docker build .
Durch die standardmäßige Aktivierung in der Docker-Konfiguration: { "features": { "buildkit": true } }
, gefolgt von einem Docker-Neustart.
BuildKit ermöglicht die Verwendung von Geheimnissen zur Bauzeit mit der Option --secret
, um sicherzustellen, dass diese Geheimnisse nicht im Image-Bau-Cache oder im endgültigen Image enthalten sind, indem ein Befehl wie folgt verwendet wird:
Für Geheimnisse, die in einem laufenden Container benötigt werden, bieten Docker Compose und Kubernetes robuste Lösungen. Docker Compose verwendet einen secrets
-Schlüssel in der Dienstdefinition, um Geheimnisdateien anzugeben, wie im folgenden Beispiel einer docker-compose.yml
:
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 rollenbasierten Zugriffskontrollen (RBAC) von Kubernetes verbessern die Sicherheit des Secret-Managements, ähnlich wie bei Docker Enterprise.
gVisor ist ein Anwendungs-Kernel, der in Go geschrieben ist und einen wesentlichen Teil der Linux-Systemoberfläche implementiert. Er umfasst eine Open Container Initiative (OCI) Runtime namens runsc
, die eine Isolationsgrenze zwischen der Anwendung und dem Host-Kernel bereitstellt. Die runsc
Runtime integriert sich mit Docker und Kubernetes, was es einfach macht, sandboxed Container auszuführen.
Kata Containers ist eine Open-Source-Community, die daran arbeitet, eine sichere Container-Runtime mit leichten virtuellen Maschinen zu erstellen, die sich anfühlen und funktionieren wie Container, aber stärkere Arbeitslastisolierung durch Hardware-Virtualisierung Technologie als zweite Verteidigungsebene bieten.
Verwenden Sie nicht das --privileged
Flag oder mounten Sie einen Docker-Socket innerhalb des Containers. Der Docker-Socket ermöglicht das Erstellen von Containern, sodass es eine einfache Möglichkeit ist, die vollständige Kontrolle über den Host zu übernehmen, indem beispielsweise ein anderer Container mit dem --privileged
Flag ausgeführt wird.
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 umgeschrieben. Er ist nur leicht eingeschränkt durch hauptsächlich Linux-Namensräume, Fähigkeiten und cgroups.
Entfernen Sie alle Fähigkeiten (--cap-drop=all
) und aktivieren Sie nur die, die erforderlich sind (--cap-add=...
). Viele Arbeitslasten 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 Privilegien erlangen, beispielsweise durch SUID-Binärdateien.
Begrenzen Sie die Ressourcen, die dem Container zur Verfügung stehen. Ressourcenlimits können die Maschine vor Denial-of-Service-Angriffen schützen.
Verwenden Sie offizielle Docker-Images und verlangen Sie Signaturen oder erstellen Sie Ihre eigenen basierend auf ihnen. Erben oder verwenden Sie keine backdoored Images. Bewahren Sie auch Root-Schlüssel und Passwörter an einem sicheren Ort auf. Docker plant, Schlüssel mit UCP zu verwalten.
Bauen Sie regelmäßig Ihre Images neu, um Sicherheitspatches auf den Host und die Images anzuwenden.
Verwalten Sie Ihre Secrets weise, damit es für den Angreifer schwierig ist, darauf zuzugreifen.
Wenn Sie den Docker-Daemon exponieren, verwenden Sie HTTPS mit Client- und Serverauthentifizierung.
In Ihrem Dockerfile, bevorzugen Sie COPY anstelle von ADD. ADD extrahiert automatisch gezippte Dateien und kann Dateien von URLs kopieren. COPY hat diese Fähigkeiten nicht. Vermeiden Sie wann immer möglich die Verwendung von ADD, damit Sie nicht anfällig für Angriffe über Remote-URLs und Zip-Dateien sind.
Haben Sie getrennte Container für jeden Mikro-service.
Setzen Sie ssh nicht in den Container, „docker exec“ kann verwendet werden, um sich in den Container einzuloggen.
Haben 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, zu entkommen und Privilegien 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-Auth-Plugin eingeschränkt werden, überprüfen Sie, ob Sie es umgehen können:
AuthZ& AuthN - Docker Access Authorization PluginDas Tool docker-bench-security ist ein Skript, das Dutzende von gängigen Best Practices zur Bereitstellung 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, der Docker ausführt, oder von einem Container mit ausreichenden Berechtigungen. Finden Sie heraus, wie Sie es im README ausführen: https://github.com/docker/docker-bench-security.
Verwenden Sie Trickest, um Workflows einfach zu erstellen und zu automatisieren, die von den fortschrittlichsten Community-Tools der Welt unterstützt werden. Erhalten Sie heute Zugang:
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)