Warum sind Sie hier?
Sie möchten die richtige Antwort auf zwei Fragen zur Docker-Sicherheit wissen:
Ist Docker für den Produktionseinsatz sicher?
Jaund nein. Docker verwendet ein Sicherheitsmodell, das auf Namespaces und Ressourcenisolierung beruht und die Prozesse darin vor spezifischen Angriffen sicherer macht als die direkte Ausführung Ihrer Anwendungen auf einer Cloud-VM oder einem Bare-Metal-System. Trotz dieser Schicht gibt es immer noch viele Möglichkeiten für Angreifer, auf Ihren Container zuzugreifen und vertrauliche Informationen zu lesen, Denial-of-Service-Angriffe (DoS) auszuführen oder sogar Root-Zugriff auf das Host-System zu erhalten.
Wie kann ich die Sicherheit von Docker (auf eine nicht allzu schmerzhafte Weise) verbessern?
Wirführen Sie durch die häufigsten und schwerwiegendsten Docker-Schwachstellen und übergehen dabei die grundlegenden Empfehlungen, die Sie überall bei Google finden, wie die Verwendung offizieller Images und die Aktualisierung Ihres Hosts, und führen Sie stattdessen direkt zu neuen Docker-Optionen und Dockerfile-Zeilen, die Ihre neue Standard-Docker-Container-Bereitstellung weitaus sicherer machen.

Die No-BS-Checkliste für Docker-Sicherheit
Containereigene Dateisysteme schreibgeschützt machen
Was haben Sie davon?
Sie verhindern, dass ein Angreifer die Laufzeitumgebung Ihres Docker-Containers bearbeitet, wodurch er nützliche Informationen über Ihre Infrastruktur sammeln, Benutzerdaten erfassen oder direkt einen DOS- oder Ransomware-Angriff durchführen könnte.
Wie stellt man sie ein?
Sie haben zwei Möglichkeiten, 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:
Dienstleistungen:
webapp:
image: your-app:v1.0.1read_only: true
...
Privilegienerweiterung sperren
Was haben Sie davon?
Mit setuid oder setgid verhindern Sie, dass Ihr Docker-Container - oder ein Angreifer, der sich in diesem Container zu schaffen macht - neue Privilegien, sogar auf Root-Ebene, aktiviert. Mit einem freizügigeren Zugriff auf Ihren Container könnte ein Angreifer auf Anmeldeinformationen in Form von Passwörtern oder Schlüsseln zu verbundenen Teilen Ihrer Bereitstellung, wie einer Datenbank, zugreifen.
Wie stellt man sie ein?
Wiederum 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:
Dienstleistungen:
webapp:
image: your-app:v1.0.1
security_opt:
- no-new-privileges:true
...
Isolieren Sie Ihre Container-zu-Container-Netzwerke
Was haben Sie davon?
Standardmäßig lässt Docker alle Container über das Netzwerk docker0 kommunizieren, was es einem Angreifer ermöglichen könnte, seitlich von einem kompromittierten Container zu einem anderen zu gelangen. Wenn Sie diskrete Dienste haben A
und B
in Behältern Y
und Z
Die Isolierung ihrer Netzwerke sorgt für die gleiche Erfahrung für den Endbenutzer und verhindert gleichzeitig seitliche Bewegungen für eine bessere Docker-Sicherheit.
Wie stellt man sie ein?
Sie können Docker-Netzwerke zur Laufzeit oder innerhalb Ihrer Docker Compose-Konfiguration angeben. Zunächst müssen Sie jedoch das Netzwerk erstellen:
docker network create your-isolated-network
Fügen Sie zur Laufzeit die --netz optio
n: docker run --network your-isolated-network your-app:v1.0.1
Oder die entsprechende Option in Ihrer Docker Compose-Datei:
Dienstleistungen:
webapp:
image: your-app:v1.0.1
networks:
- Ihr-isoliertes-Netz
...
Einrichten eines geeigneten Nicht-Root-Benutzers
Was haben Sie davon?
Der Standardbenutzer innerhalb eines Containers ist Wurzel
mit einer uid von 0
. Durch die Angabe eines bestimmten Benutzers verhindern Sie, dass ein Angreifer seine Privilegien auf einen anderen Benutzer ausdehnt, der ohne Einschränkungen Aktionen durchführen kann, wie z. B. root, was alle anderen Docker-Sicherheitsmaßnahmen außer Kraft setzen würde, für die Sie hart gearbeitet haben.
Wie stellt man sie ein?
Erstellen Sie Ihren Benutzer während des Build-Prozesses oder zur Laufzeit. Zur Laufzeit können Sie den Benutzer entweder zum ersten Mal anlegen oder die BENUTZER
die Sie bereits bei der Erstellung eingestellt haben.
Während des Erstellungsprozesses, in Ihrem Dockerdatei
:
...
RUN groupadd -r Ihr-Benutzer
RUN useradd -r -g Ihr-Benutzer Ihr-Benutzer
BENUTZER meinBenutzer
...
Zur Laufzeit: docker run -u ihr-benutzer ihre-app:v1.0.1
Linux-Kernel-Fähigkeiten fallen lassen
Was haben Sie davon?
Standardmäßig dürfen Docker-Container eine begrenzte Anzahl von Linux-Kernel-Funktionen verwenden. Man könnte meinen, dass die Leute von Docker diesen eingeschränkten Satz geschaffen haben, um vollkommen sicher zu sein, aber viele Fähigkeiten sind aus Kompatibilitäts- und Vereinfachungsgründen vorhanden. So können Standardcontainer beispielsweise willkürlich die Eigentümerschaft an Dateien ändern, ihr Stammverzeichnis wechseln, Prozess-UIDs manipulieren und Sockets lesen. Durch den Verzicht auf einige oder alle dieser Funktionen wird die Anzahl der Angriffsvektoren minimiert.
Wie stellt man sie ein?
Sie können Fähigkeiten aufheben und neue zur Laufzeit festlegen. Sie könnten zum Beispiel alle Kernel-Fähigkeiten weglassen und Ihrem Container nur die Fähigkeit zugestehen, den Besitz von bestehenden Dateien zu ändern.
docker run --cap-drop ALL --cap-add CHOWN your-app:v1.0.1
Oder für Docker Compose:
Dienstleistungen:
webapp:
image: your-app:v1.0.1
cap_drop:
- ALL
cap_add:
- CHOWN
...
Verhindern von Gabelbomben
Was haben Sie davon?
Forkbomben sind eine Art DoS-Angriff, bei dem ein bestehender Prozess unendlich oft repliziert wird. Zunächst verringern sie die Leistung und schränken die Ressourcen ein, was unweigerlich die Kosten in die Höhe treibt und schließlich zum Absturz Ihrer Container oder des Hostsystems führen kann. Sobald eine Fork-Bombe gestartet ist, gibt es keine andere Möglichkeit, sie zu stoppen, als den Container oder den Host neu zu starten.
Wie stellt man sie ein?
Zur Laufzeit können Sie die Anzahl der Prozesse (PIDs) begrenzen, die Ihr Container erstellen kann.
docker run --pids-limit 99 ihre-anwendung:v1.0.1
Oder mit Docker Compose:
Dienstleistungen:
webapp:
image: your-app:v1.0.1
deploy
Grenzen:
pids: 99
Verbessern Sie die Docker-Sicherheit durch Überwachung Ihrer Open-Source-Abhängigkeiten
Was haben Sie davon?
Die Anwendungen, die Sie für die Bereitstellung mit Docker containerisiert haben, verfügen wahrscheinlich über einen umfangreichen Baum von Abhängigkeiten.
Wie stellt man sie ein?
Der "nicht-BS"-mäßigste Weg ist das Open-Source-Abhängigkeitsscanning von Aikido. Unsere kontinuierliche Überwachung scannt Projekte, die in mehr als einem Dutzend Sprachen geschrieben wurden, basierend auf dem Vorhandensein von Lockfiles innerhalb Ihrer Anwendung und liefert einen sofortigen Überblick über Schwachstellen und Malware. Mit der automatischen Triagierung, die falsch-positive Ergebnisse herausfiltert, gibt Aikido Ihnen Ratschläge zur Behebung von Schwachstellen, mit denen Sie sofort arbeiten können... und nicht erst, nachdem Sie ein Dutzend anderer Referenzdokumente und GitHub-Probleme gelesen haben.
Bei Aikido lieben wir etablierte Open-Source-Projekte wie Trivy, Syft und Grype. Wir wissen aber auch aus Erfahrung, dass die isolierte Nutzung dieser Projekte keine besonders gute Erfahrung für Entwickler ist. Unter der Haube erweitert Aikido diese Projekte mit benutzerdefinierten Regeln, um Lücken zu schließen und Sicherheitslücken aufzudecken, die Sie sonst nicht finden könnten. Anders als bei der Verkettung verschiedener Open-Source-Tools müssen Sie mit Aikido kein Scanning-Skript erstellen oder einen benutzerdefinierten Job in Ihrem CI/CD erstellen.

Nur vertrauenswürdige Images für Docker-Sicherheit verwenden
Was haben Sie davon?
Docker Content Trust (DCT) ist ein System zum Signieren und Überprüfen des Inhalts und der Integrität der offiziellen Images, die Sie aus Docker-Registries wie Docker Hub beziehen. Wenn Sie nur vom Autor signierte Images abrufen, können Sie sich darauf verlassen, dass diese nicht manipuliert wurden, um Schwachstellen in Ihrer Bereitstellung zu schaffen.
Wie stellt man sie ein?
Am einfachsten ist es, die Umgebungsvariable in Ihrer Shell zu setzen, die verhindert, dass Sie oder andere Personen mit nicht vertrauenswürdigen Images arbeiten können.
exportDOCKER_CONTENT_TRUST=1
docker run ...
Oder Sie können die Umgebungsvariable bei jeder Ausführung von Docker setzen:
DOCKER_CONTENT_TRUST=1 docker run ...
Aktualisieren von End-of-Life-Laufzeiten (EOL)
Was haben Sie davon?
Eine gängige Empfehlung für die Sicherheit von Docker-Containern besteht darin, Images und Abhängigkeiten an eine bestimmte Version zu binden, anstatt neueste
. Theoretisch verhindert dies, dass Sie unwissentlich neue Bilder verwenden, auch solche, die manipuliert wurden und neue Schwachstellen aufweisen.
Wie stellt man sie ein?
Es gibt einige Open-Source-Projekte, die Ihnen helfen, EOLs zu entdecken und sich bestmöglich vorzubereiten. Das Projekt endoflife.date(GitHub-Repository) verfolgt mehr als 300 Produkte, indem es Daten aus verschiedenen Quellen sammelt und über eine öffentliche API zur Verfügung stellt. Mit endoflife.date und ähnlichen Projekten haben Sie mehrere Möglichkeiten:
- Überprüfen Sie das Projekt manuell auf Updates für Abhängigkeiten, auf die Ihre Anwendungen angewiesen sind, und erstellen Sie Tickets oder Probleme für erforderliche Updates.
- Schreiben Sie ein Skript (Bash, Python usw.), um die EOL-Daten von Abhängigkeiten aus der API zu erhalten, 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 dieses erreicht hat.
Als Entwickler verstehen wir, dass Ihre Zeit wertvoll und oft begrenzt ist. Hier kann Aikido ein Gefühl der Sicherheit vermitteln - unsere EOL-Scan-Funktion verfolgt Ihren Code und Ihre Container und priorisiert die Laufzeiten mit den größten Auswirkungen und der größten Gefährdung, wie Node.js oder einen Nginx-Webserver. Wie üblich automatisieren wir nicht nur das Sammeln von Informationen, sondern liefern auch Warnungen mit angemessenem Schweregrad, um Sie zu informieren und nicht zu überfordern.

Begrenzung der Nutzung von Container-Ressourcen
Was haben Sie davon?
Standardmäßig haben Container keine Ressourcenbeschränkungen und verwenden so viel Speicher oder CPU wie der Scheduler des Hosts. Die Beschränkung der Ressourcennutzung eines bestimmten Containers kann die Auswirkungen eines DoS-Angriffs minimieren. Anstatt den Container oder das Hostsystem aufgrund einer "Out of Memory"-Ausnahme zum Absturz zu bringen, wird der laufende DoS-Angriff "nur" die Erfahrung des Endbenutzers negativ beeinflussen.
Wie stellt man sie ein?
Zur Laufzeit können Sie mit der --Speicher
und --cpus
um Grenzen für die Speicher- bzw. CPU-Nutzung festzulegen. Die Speicheroption nimmt Zahlen mit g für Gigabyte und m für Megabyte an, während die CPU-Option die Grenze der dedizierten CPUs widerspiegelt, die für den Container und seine Prozesse verfügbar sind.
docker run --memory="1g" --cpus="2" ihre-app:v1.0.1
Dies funktioniert auch mit Docker Compose:
Dienstleistungen:
webapp:
image: your-app:v1.0.1
deploy:
Grenzen:
cpus: '2'
speicher: 1G
...
Ihr letzter Befehl und die Compose-Optionen für die Docker-Sicherheit
Inzwischen haben Sie eine ganze Reihe von Docker-Sicherheitstipps und die dazugehörigen CLI-Optionen oder Konfigurationen kennengelernt. Das bedeutet, dass Sie entweder ganz aufgeregt sind, sie zu implementieren, oder dass Sie überfordert sind, wenn Sie wissen wollen, wie Sie das alles zusammensetzen sollen. Im Folgenden haben wir alle Empfehlungen in einem einzigen Befehl oder einer einzigen Konfigurationsvorlage zusammengefasst, die Ihnen helfen wird, sofort mit der Bereitstellung sicherer Docker-Container zu beginnen.
Natürlich werden Sie einige der Optionen - wie den Nicht-Root-Benutzernamen, die Kernel-Fähigkeiten und die Ressourcenbeschränkungen - je nach den Anforderungen Ihrer Anwendung ändern wollen.
exportDOCKER_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=Ihr-Benutzer \
... # ANDERE OPTIONEN SIND HIER ZU FINDEN
deine-app:v1.0.1
Vielleicht möchten Sie sogar einen drun-Alias mit der Shell Ihres Hosts erstellen, den Sie aufrufen können, ohne sich all diese Details merken zu müssen.
Funktion 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=Ihr-Benutzer \
$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 Freund von Docker Compose sind, können Sie all diese Optionen in eine neue Basisvorlage für Docker Compose integrieren, mit der Sie in Zukunft arbeiten können:
Dienstleistungen:
webapp:
image: your-app:v1.0.1
read_only: true
security_opt:
- no-new-privileges:true
networks:
- Ihr-isoliertes-Netz
cap_drop:
- ALL
cap_add:
- CHOWN
einsetzen:
Grenzen:
pids: 9
cpus: '2'
Speicher: 1G
... # ANDERE OPTIONEN SIND HIER ZU FINDEN
Bonus: Docker mit Rootless-Containern betreiben
Wenn Sie Docker auf einem beliebigen System installieren, arbeitet sein Daemon mit Root-Rechten. Selbst wenn Sie alle oben genannten Optionen aktivieren und eine Ausweitung der Berechtigungen innerhalb eines Docker-Containers verhindern, hat der Rest der Container-Laufzeitumgebung auf Ihrem Host-System immer noch Root-Rechte. Das vergrößert unweigerlich Ihre Angriffsfläche.
Die Lösung sind Container ohne Root-Rechte, die ein unprivilegierter Benutzer erstellen und verwalten kann. Ohne Root-Rechte gibt es weitaus weniger Sicherheitsprobleme für Ihr Host-System.
Wir wünschten, wir könnten Ihnen bei der Verwendung von Rootless-Containern mit einer einzigen Option oder einem einzigen Befehl helfen, aber so einfach ist es nicht. Ausführliche Anleitungen finden Sie auf der Rootless Containers-Website, einschließlich einer Anleitung für Docker.
Was kommt als nächstes für Ihre Docker-Sicherheit?
Wenn Sie aus dieser Erfahrung etwas gelernt haben, dann, dass Containersicherheit eine langwierige Angelegenheit ist. Es gibt immer mehr Checklisten und tiefgehende Artikel über die Absicherung von Containern in Docker oder seinem älteren und oft missverstandenen Cousin Kubernetes zu lesen. Sie können unmöglich eine fehlerfreie Containersicherheit anstreben - wenn Sie sich in Ihrem vollen Entwicklungsplan Zeit für die Sicherheit nehmen und dann schrittweise Verbesserungen auf der Grundlage der Auswirkungen und des Schweregrads vornehmen, werden Sie mit der Zeit viel erreichen.
Aikido hilft Ihnen dabei, diesen kontinuierlichen Prozess zu optimieren und Korrekturen zu priorisieren, die die Sicherheit Ihrer Anwendungen deutlich verbessern. Wir haben gerade eine 17-Millionen-Dollar-Serie A für unsere "No-BS"-Entwickler-Sicherheitsplattform erhalten und würden uns freuen, wenn Sie sich uns anschließen.