OWASP Docker Security Sheet: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(22 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 13: Zeile 13:
 
Außerdem teilen sich Container (im Gegensatz zu virtuellen Maschinen) den Kernel mit dem Host, daher treffen Kernel-Exploits, die innerhalb des Containers ausgeführt werden, direkt auf den Host-Kernel. Zum Beispiel führt ein Exploit zur Ausweitung von Kernel-Privilegien ( wie Dirty COW ), der in einem gut isolierten Container ausgeführt wird, zu Root-Zugriff auf einen Host.
 
Außerdem teilen sich Container (im Gegensatz zu virtuellen Maschinen) den Kernel mit dem Host, daher treffen Kernel-Exploits, die innerhalb des Containers ausgeführt werden, direkt auf den Host-Kernel. Zum Beispiel führt ein Exploit zur Ausweitung von Kernel-Privilegien ( wie Dirty COW ), der in einem gut isolierten Container ausgeführt wird, zu Root-Zugriff auf einen Host.
  
==REGEL #1 – Den Docker-Daemon-Socket nicht freigeben (auch nicht für die Container)==
+
==REGEL 1 – Den Docker-Daemon-Socket nicht freigeben (auch nicht für die Container)==
 
Docker-Socket /var/run/docker.sock ist der UNIX-Socket, auf den Docker lauscht. Dies ist der primäre Einstiegspunkt für die Docker-API. Der Besitzer dieses Sockets ist root. Jemandem Zugriff darauf zu gewähren, entspricht dem uneingeschränkten Root-Zugriff auf Ihren Host.
 
Docker-Socket /var/run/docker.sock ist der UNIX-Socket, auf den Docker lauscht. Dies ist der primäre Einstiegspunkt für die Docker-API. Der Besitzer dieses Sockets ist root. Jemandem Zugriff darauf zu gewähren, entspricht dem uneingeschränkten Root-Zugriff auf Ihren Host.
  
Aktivieren Sie den TCP- Docker-Daemon-Socket nicht. Wenn Sie einen Docker-Daemon mit -H tcp://0.0.0.0:XXXoder ähnlichem ausführen, stellen Sie unverschlüsselten und nicht authentifizierten direkten Zugriff auf den Docker-Daemon bereit. Wenn Sie dies wirklich, wirklich tun müssen, sollten Sie es sichern. Überprüfen Sie anhand der offiziellen Docker-Dokumentation, wie das geht .
+
Aktivieren Sie den TCP- Docker-Daemon-Socket nicht. Wenn Sie einen Docker-Daemon mit '''-H tcp://0.0.0.0:XXX''' oder ähnlichem ausführen, stellen Sie unverschlüsselten und nicht authentifizierten direkten Zugriff auf den Docker-Daemon bereit. Wenn Sie dies wirklich, wirklich tun müssen, sollten Sie es sichern. Überprüfen Sie anhand der offiziellen Docker-Dokumentation, wie das geht .
  
 
Machen Sie /var/run/docker.sock nicht für andere Container verfügbar . Wenn Sie Ihr Docker-Image mit -v /var/run/docker.sock://var/run/docker.sockoder ähnlichem ausführen , sollten Sie es ändern. Denken Sie daran, dass das Mounten des Sockets schreibgeschützt keine Lösung ist, sondern nur die Ausnutzung erschwert. Äquivalent in der docker-compose-Datei ist etwa so:
 
Machen Sie /var/run/docker.sock nicht für andere Container verfügbar . Wenn Sie Ihr Docker-Image mit -v /var/run/docker.sock://var/run/docker.sockoder ähnlichem ausführen , sollten Sie es ändern. Denken Sie daran, dass das Mounten des Sockets schreibgeschützt keine Lösung ist, sondern nur die Ausnutzung erschwert. Äquivalent in der docker-compose-Datei ist etwa so:
  
 
+
<syntaxhighlight lang="json">
 
volumes:
 
volumes:
 
- "/var/run/docker.sock:/var/run/docker.sock"
 
- "/var/run/docker.sock:/var/run/docker.sock"
==REGEL #2 – Legen Sie einen Benutzer fest==
+
</syntaxhighlight>
 +
 
 +
==REGEL 2 – Legen Sie einen Benutzer fest==
 
Die Konfiguration des Containers für die Verwendung eines nicht privilegierten Benutzers ist der beste Weg, um Angriffe auf eine Rechteausweitung zu verhindern. Dies kann auf drei verschiedene Arten wie folgt erreicht werden:
 
Die Konfiguration des Containers für die Verwendung eines nicht privilegierten Benutzers ist der beste Weg, um Angriffe auf eine Rechteausweitung zu verhindern. Dies kann auf drei verschiedene Arten wie folgt erreicht werden:
  
Während der Laufzeit mit -uOption des docker runBefehls zB:
+
Während der Laufzeit mit -u Option des docker run Befehls zB:
  
docker run -u 4000 alpine
+
*docker run -u 4000 alpine
 
Während der Bauzeit. Einfach Benutzer in Dockerfile hinzufügen und verwenden. Beispielsweise:
 
Während der Bauzeit. Einfach Benutzer in Dockerfile hinzufügen und verwenden. Beispielsweise:
 
+
<syntaxhighlight>
 
FROM alpine
 
FROM alpine
 
RUN groupadd -r myuser && useradd -r -g myuser myuser
 
RUN groupadd -r myuser && useradd -r -g myuser myuser
 
<HERE DO WHAT YOU HAVE TO DO AS A ROOT USER LIKE INSTALLING PACKAGES ETC.>
 
<HERE DO WHAT YOU HAVE TO DO AS A ROOT USER LIKE INSTALLING PACKAGES ETC.>
 
USER myuser
 
USER myuser
 +
</syntaxhighlight>
 
Aktivieren Sie die Unterstützung von Benutzernamensräumen ( --userns-remap=default) im Docker-Daemon
 
Aktivieren Sie die Unterstützung von Benutzernamensräumen ( --userns-remap=default) im Docker-Daemon
 
Weitere Informationen zu diesem Thema finden Sie in der offiziellen Docker-Dokumentation
 
Weitere Informationen zu diesem Thema finden Sie in der offiziellen Docker-Dokumentation
Zeile 40: Zeile 43:
 
In Kubernetes kann dies im Sicherheitskontext mithilfe eines runAsNonRootFelds konfiguriert werden , z. B.:
 
In Kubernetes kann dies im Sicherheitskontext mithilfe eines runAsNonRootFelds konfiguriert werden , z. B.:
  
 
+
<syntaxhighlight>
 
kind: ...
 
kind: ...
 
apiVersion: ...
 
apiVersion: ...
Zeile 54: Zeile 57:
 
           runAsNonRoot: true
 
           runAsNonRoot: true
 
           ...
 
           ...
 +
</syntaxhighlight>
 +
 
Als Kubernetes-Cluster-Administrator können Sie es mithilfe von Pod-Sicherheitsrichtlinien konfigurieren .
 
Als Kubernetes-Cluster-Administrator können Sie es mithilfe von Pod-Sicherheitsrichtlinien konfigurieren .
  
==REGEL #3 – Beschränken Sie die Fähigkeiten (Gewähre nur bestimmte Fähigkeiten, die von einem Container benötigt werden)==
+
==REGEL 3 – Beschränken Sie die Fähigkeiten (Gewähre nur bestimmte Fähigkeiten, die von einem Container benötigt werden)==
Die Linux-Kernel-Fähigkeiten sind eine Reihe von Privilegien, die von Privilegierten verwendet werden können. Docker wird standardmäßig nur mit einer Teilmenge der Funktionen ausgeführt. Sie können es ändern und einige Funktionen löschen (mit --cap-drop), um Ihre Docker-Container zu härten, oder --cap-addbei Bedarf einige Funktionen hinzufügen (mit ). Denken Sie daran, keine Container mit dem --privilegedFlag auszuführen - dies fügt dem Container ALLE Linux-Kernel-Funktionen hinzu.
+
Die Linux-Kernel-Fähigkeiten sind eine Reihe von Privilegien, die von Privilegierten verwendet werden können. Docker wird standardmäßig nur mit einer Teilmenge der Funktionen ausgeführt. Sie können es ändern und einige Funktionen löschen (mit '''--cap-drop'''), um Ihre Docker-Container zu härten, oder '''--cap-add''' bei Bedarf einige Funktionen hinzufügen (mit ). Denken Sie daran, keine Container mit dem '''--privileged''' Flag auszuführen - dies fügt dem Container ALLE Linux-Kernel-Funktionen hinzu.
  
 
Die sicherste Einrichtung besteht darin, alle Funktionen zu löschen --cap-drop allund dann nur die erforderlichen hinzuzufügen. Beispielsweise:
 
Die sicherste Einrichtung besteht darin, alle Funktionen zu löschen --cap-drop allund dann nur die erforderlichen hinzuzufügen. Beispielsweise:
  
 +
*docker run --cap-drop all --cap-add CHOWN alpine
 +
Und denken Sie daran: Führen Sie keine Container mit dem Flag '''--privileged''' aus !!!
  
docker run --cap-drop all --cap-add CHOWN alpine
+
In Kubernetes kann dies im Sicherheitskontext mit einem capabilities Feld konfiguriert werden , z. B.:
Und denken Sie daran: Führen Sie keine Container mit dem Flag --privileged aus !!!
 
 
 
In Kubernetes kann dies im Sicherheitskontext mit einem capabilitiesFeld konfiguriert werden , z. B.:
 
 
 
  
 +
<syntaxhighlight>
 
kind: ...
 
kind: ...
 
apiVersion: ...
 
apiVersion: ...
Zeile 85: Zeile 89:
 
               - CHOWN
 
               - CHOWN
 
           ...
 
           ...
 +
</syntaxhighlight>
 +
 
Als Kubernetes-Cluster-Administrator können Sie es mithilfe von Pod-Sicherheitsrichtlinien konfigurieren .
 
Als Kubernetes-Cluster-Administrator können Sie es mithilfe von Pod-Sicherheitsrichtlinien konfigurieren .
  
==REGEL #4 – Füge das Flag „no-new-privileges“ hinzu==
+
==REGEL 4 – Füge das Flag „no-new-privileges“ hinzu==
Führen Sie Ihre Docker-Images immer mit --security-opt=no-new-privilegesaus, um zu verhindern, dass Berechtigungen setuidoder setgidBinärdateien eskalieren .
+
Führen Sie Ihre Docker-Images immer mit --security-opt=no-new-privilegesaus, um zu verhindern, dass Berechtigungen setuid oder setgid Binärdateien eskalieren.
  
 
In Kubernetes kann dies im Sicherheitskontext mithilfe eines allowPrivilegeEscalationFelds konfiguriert werden , z. B.:
 
In Kubernetes kann dies im Sicherheitskontext mithilfe eines allowPrivilegeEscalationFelds konfiguriert werden , z. B.:
  
 
+
<syntaxhighlight>
 
kind: ...
 
kind: ...
 
apiVersion: ...
 
apiVersion: ...
Zeile 106: Zeile 112:
 
           allowPrivilegeEscalation: false
 
           allowPrivilegeEscalation: false
 
           ...
 
           ...
 +
</syntaxhighlight>
 +
 
Als Kubernetes-Cluster-Administrator können Sie die Kubernetes-Dokumentation zur Konfiguration mit Pod-Sicherheitsrichtlinien verwenden .
 
Als Kubernetes-Cluster-Administrator können Sie die Kubernetes-Dokumentation zur Konfiguration mit Pod-Sicherheitsrichtlinien verwenden .
  
==REGEL #5 – Deaktivieren der Kommunikation zwischen Containern (--icc=false)==
+
==REGEL 5 – Deaktivieren der Kommunikation zwischen Containern (--icc=false)==
Standardmäßig inter-Behälter - Kommunikation (ICC) ist aktiviert - es bedeutet , dass alle Behälter miteinander (unter Verwendung sprechen können docker0überbrückte Netzwerk ). Dies kann deaktiviert werden, indem der Docker-Daemon mit --icc=falseFlag ausgeführt wird. Wenn icc deaktiviert ist (icc=false), muss mit der Option --link=CONTAINER_NAME_or_ID:ALIAS mitgeteilt werden, welche Container kommunizieren können. Weitere Informationen finden Sie in der Docker-Dokumentation - Containerkommunikation
+
Standardmäßig Inter-Container-Kommunikation (ICC) ist aktiviert - es bedeutet , dass alle Container miteinander (unter Verwendung sprechen können docker0 überbrückte Netzwerk ). Dies kann deaktiviert werden, indem der Docker-Daemon mit --icc=falseFlag ausgeführt wird. Wenn icc deaktiviert ist (icc=false), muss mit der Option --link=CONTAINER_NAME_or_ID:ALIAS mitgeteilt werden, welche Container kommunizieren können. Weitere Informationen finden Sie in der Docker-Dokumentation - Containerkommunikation
  
 
In Kubernetes können Netzwerkrichtlinien dafür verwendet werden.
 
In Kubernetes können Netzwerkrichtlinien dafür verwendet werden.
  
==REGEL #6 – Linux-Sicherheitsmodul verwenden (seccomp, AppArmor oder SELinux)==
+
==REGEL 6 – Linux-Sicherheitsmodul verwenden (seccomp, AppArmor oder SELinux)==
 
Deaktivieren Sie zunächst nicht das Standardsicherheitsprofil!
 
Deaktivieren Sie zunächst nicht das Standardsicherheitsprofil!
  
Zeile 120: Zeile 128:
 
Anweisungen dazu in Kubernetes finden Sie in der Dokumentation zum Sicherheitskontext und in der Kubernetes-API-Dokumentation
 
Anweisungen dazu in Kubernetes finden Sie in der Dokumentation zum Sicherheitskontext und in der Kubernetes-API-Dokumentation
  
==REGEL #7 – Ressourcen begrenzen (Speicher, CPU, Dateideskriptoren, Prozesse, Neustarts)==
+
==REGEL 7 – Ressourcen begrenzen (Speicher, CPU, Dateideskriptoren, Prozesse, Neustarts)==
 
Der beste Weg, um DoS-Angriffe zu vermeiden, besteht darin, die Ressourcen zu begrenzen. Sie können Speicher , CPU , maximale Anzahl von Neustarts ( --restart=on-failure:<number_of_restarts>), maximale Anzahl von Dateideskriptoren ( --ulimit nofile=<number>) und maximale Anzahl von Prozessen ( --ulimit nproc=<number>) begrenzen .
 
Der beste Weg, um DoS-Angriffe zu vermeiden, besteht darin, die Ressourcen zu begrenzen. Sie können Speicher , CPU , maximale Anzahl von Neustarts ( --restart=on-failure:<number_of_restarts>), maximale Anzahl von Dateideskriptoren ( --ulimit nofile=<number>) und maximale Anzahl von Prozessen ( --ulimit nproc=<number>) begrenzen .
  
Zeile 127: Zeile 135:
 
Sie können dies auch in Kubernetes tun: Zuweisen von Speicherressourcen zu Containern und Pods , Zuweisen von CPU-Ressourcen zu Containern und Pods und Zuweisen von erweiterten Ressourcen zu einem Container
 
Sie können dies auch in Kubernetes tun: Zuweisen von Speicherressourcen zu Containern und Pods , Zuweisen von CPU-Ressourcen zu Containern und Pods und Zuweisen von erweiterten Ressourcen zu einem Container
  
==REGEL #8 - Dateisystem und Volumes auf schreibgeschützt setzen==
+
==REGEL 8 - Dateisystem und Volumes auf schreibgeschützt setzen==
Führen Sie Container mit einem schreibgeschützten Dateisystem mit --read-onlyFlag aus. Beispielsweise:
+
Führen Sie Container mit einem schreibgeschützten Dateisystem mit '''--read-only''' Flag aus. Beispielsweise:
  
  
docker run --read-only alpine sh -c 'echo "whatever" > /tmp'
+
*docker run --read-only alpine sh -c 'echo "whatever" > /tmp'
Wenn eine Anwendung in einem Container vorübergehend etwas speichern muss, kombinieren Sie --read-onlyFlag mit --tmpfswie folgt:
+
Wenn eine Anwendung in einem Container vorübergehend etwas speichern muss, kombinieren Sie '''--read-only''' Flag mit '''--tmpfs''' wie folgt:
  
  
docker run --read-only --tmpfs /tmp alpine sh -c 'echo "whatever" > /tmp/file'
+
*docker run --read-only --tmpfs /tmp alpine sh -c 'echo "whatever" > /tmp/file'
 
Äquivalent in der docker-compose-Datei ist:
 
Äquivalent in der docker-compose-Datei ist:
  
 
+
<syntaxhighlight>
 
version: "3"
 
version: "3"
 
services:
 
services:
Zeile 144: Zeile 152:
 
     image: alpine
 
     image: alpine
 
     read_only: true
 
     read_only: true
 +
</syntaxhighlight>
 +
 
Äquivalent in Kubernetes im Sicherheitskontext ist:
 
Äquivalent in Kubernetes im Sicherheitskontext ist:
  
 
+
<syntaxhighlight>
 
kind: ...
 
kind: ...
 
apiVersion: ...
 
apiVersion: ...
Zeile 160: Zeile 170:
 
           readOnlyRootFilesystem: true
 
           readOnlyRootFilesystem: true
 
           ...
 
           ...
Wenn das Volume nur zum Lesen gemountet ist, mounten Sie es außerdem schreibgeschützt. Dies kann durch Anhängen :roan Folgendes erfolgen -v:
+
</syntaxhighlight>
  
 +
Wenn das Volume nur zum Lesen gemountet ist, mounten Sie es außerdem schreibgeschützt. Dies kann durch Anhängen ''':ro''' an Folgendes erfolgen '''-v:'''
  
docker run -v volume-name:/path/in/container:ro alpine
+
 
 +
*docker run -v volume-name:/path/in/container:ro alpine
 
Oder mit --mountOption:
 
Oder mit --mountOption:
 +
*docker run --mount source=volume-name,destination=/path/in/container,readonly alpine
  
 
docker run --mount source=volume-name,destination=/path/in/container,readonly alpine
 
 
==REGEL 9 – Verwenden Sie statische Analysetools==
 
==REGEL 9 – Verwenden Sie statische Analysetools==
 
Um Container mit bekannten Schwachstellen zu erkennen, scannen Sie Bilder mit statischen Analysetools.
 
Um Container mit bekannten Schwachstellen zu erkennen, scannen Sie Bilder mit statischen Analysetools.
  
Kostenlos
+
;So erkennen Sie Fehlkonfigurationen in Kubernetes:
Clair
+
 
Wissenswertes
+
*kubeaudit
Kommerziell
+
*kubesec.io
Snyk (Open Source und kostenlose Option verfügbar)
+
*Kube-Bank
Anker (Open Source und kostenlose Option verfügbar)
 
MicroScanner von Aqua Security (kostenlose Option für eine begrenzte Anzahl von Scans verfügbar)
 
JFrog XRay
 
Qualys
 
So erkennen Sie Fehlkonfigurationen in Kubernetes:
 
  
kubeaudit
+
;So erkennen Sie Fehlkonfigurationen in Docker:
kubesec.io
+
 
Kube-Bank
+
*inspec.io
So erkennen Sie Fehlkonfigurationen in Docker:
+
*dev-sec.io
  
inspec.io
 
dev-sec.io
 
 
==REGEL #10 - Setzen Sie die Protokollierungsebene auf mindestens INFO==
 
==REGEL #10 - Setzen Sie die Protokollierungsebene auf mindestens INFO==
 
Standardmäßig ist der Docker-Daemon so konfiguriert, dass er einen Basis-Logging-Level von 'info' hat, und wenn dies nicht der Fall ist: Setzen Sie den Docker-Daemon-Log-Level auf 'info'. Begründung: Durch das Einrichten einer geeigneten Protokollebene wird der Docker-Daemon so konfiguriert, dass Ereignisse protokolliert werden, die Sie später überprüfen möchten. Eine Basisprotokollebene von 'info' und höher würde alle Protokolle außer den Debug-Protokollen erfassen. Solange dies nicht erforderlich ist, sollten Sie den Docker-Daemon nicht auf der Protokollebene 'debug' ausführen.
 
Standardmäßig ist der Docker-Daemon so konfiguriert, dass er einen Basis-Logging-Level von 'info' hat, und wenn dies nicht der Fall ist: Setzen Sie den Docker-Daemon-Log-Level auf 'info'. Begründung: Durch das Einrichten einer geeigneten Protokollebene wird der Docker-Daemon so konfiguriert, dass Ereignisse protokolliert werden, die Sie später überprüfen möchten. Eine Basisprotokollebene von 'info' und höher würde alle Protokolle außer den Debug-Protokollen erfassen. Solange dies nicht erforderlich ist, sollten Sie den Docker-Daemon nicht auf der Protokollebene 'debug' ausführen.
  
So konfigurieren Sie die Protokollebene in docker-compose:
+
==Regel 11 – Linkt das Dockerfile zur Build-Zeit==
 
 
 
 
docker-compose --log-level info up
 
Regel #11 – Lint das Dockerfile zur Build-Zeit¶
 
 
Viele Probleme können verhindert werden, indem Sie beim Schreiben des Dockerfiles einige Best Practices befolgen. Das Hinzufügen eines Sicherheits-Linters als Schritt in der Build-Pipeline kann viel dazu beitragen, weitere Kopfschmerzen zu vermeiden. Einige Punkte, die es wert sind, überprüft zu werden, sind:
 
Viele Probleme können verhindert werden, indem Sie beim Schreiben des Dockerfiles einige Best Practices befolgen. Das Hinzufügen eines Sicherheits-Linters als Schritt in der Build-Pipeline kann viel dazu beitragen, weitere Kopfschmerzen zu vermeiden. Einige Punkte, die es wert sind, überprüft zu werden, sind:
  
Stellen Sie sicher, dass eine USERAnweisung angegeben ist
+
*Stellen Sie sicher, dass eine '''USER''' Anweisung angegeben ist
Stellen Sie sicher, dass die Basis-Image-Version angepinnt ist
+
*Stellen Sie sicher, dass die Basis-Image-Version angepinnt ist
Stellen Sie sicher, dass die Versionen der Betriebssystempakete angeheftet sind
+
*Stellen Sie sicher, dass die Versionen der Betriebssystempakete angeheftet sind
Vermeiden Sie die Verwendung von ADDzugunsten vonCOPY
+
*Vermeiden Sie die Verwendung von '''ADD''' zugunsten von '''COPY'''
Vermeiden Sie Curl-Bashing in RUNDirektiven
+
*Vermeiden Sie Curl-Bashing in '''RUN''' Direktiven
Verweise:
 
 
 
Docker-Baselines auf DevSec
 
Verwenden Sie die Docker-Befehlszeile
 
Überblick über docker-compose CLI
 
Logging-Treiber konfigurieren
 
Protokolle für einen Container oder Dienst anzeigen
 
Bewährte Vorgehensweisen für Dockerfile-Sicherheit
 
Ähnliche Projekte¶
 
OWASP Docker Top 10
 
  
BisherigeDeserialisierung
+
=So konfigurieren Sie die Protokollebene in docker-compose=
NächsterDotNet-Sicherheit
+
*docker-compose --log-level info up
 
=Links=
 
=Links=
 
https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html
 
https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html

Aktuelle Version vom 14. April 2024, 06:26 Uhr

Übersetzt aus dem Englischen

Einführung

Docker ist die beliebteste Containerisierungstechnologie. Bei sachgemäßer Verwendung kann es das Sicherheitsniveau erhöhen (im Vergleich zum Ausführen von Anwendungen direkt auf dem Host). Andererseits können einige Fehlkonfigurationen dazu führen, dass das Sicherheitsniveau herabgestuft oder sogar neue Schwachstellen eingeführt werden.

Das Ziel dieses Merkblatt ist es, eine benutzerfreundliche Liste mit häufigen Sicherheitsfehlern und bewährten Praktiken bereitzustellen, die Ihnen helfen, Ihre Docker-Container zu sichern.

Regeln

REGEL 0 – Host und Docker auf dem neuesten Stand halten

Um bekannte, Container-Escape-Schwachstellen zu verhindern, die in der Regel mit einer Eskalation auf Root-/Administratorrechte enden, ist das Patchen von Docker Engine und Docker Machine von entscheidender Bedeutung.

Außerdem teilen sich Container (im Gegensatz zu virtuellen Maschinen) den Kernel mit dem Host, daher treffen Kernel-Exploits, die innerhalb des Containers ausgeführt werden, direkt auf den Host-Kernel. Zum Beispiel führt ein Exploit zur Ausweitung von Kernel-Privilegien ( wie Dirty COW ), der in einem gut isolierten Container ausgeführt wird, zu Root-Zugriff auf einen Host.

REGEL 1 – Den Docker-Daemon-Socket nicht freigeben (auch nicht für die Container)

Docker-Socket /var/run/docker.sock ist der UNIX-Socket, auf den Docker lauscht. Dies ist der primäre Einstiegspunkt für die Docker-API. Der Besitzer dieses Sockets ist root. Jemandem Zugriff darauf zu gewähren, entspricht dem uneingeschränkten Root-Zugriff auf Ihren Host.

Aktivieren Sie den TCP- Docker-Daemon-Socket nicht. Wenn Sie einen Docker-Daemon mit -H tcp://0.0.0.0:XXX oder ähnlichem ausführen, stellen Sie unverschlüsselten und nicht authentifizierten direkten Zugriff auf den Docker-Daemon bereit. Wenn Sie dies wirklich, wirklich tun müssen, sollten Sie es sichern. Überprüfen Sie anhand der offiziellen Docker-Dokumentation, wie das geht .

Machen Sie /var/run/docker.sock nicht für andere Container verfügbar . Wenn Sie Ihr Docker-Image mit -v /var/run/docker.sock://var/run/docker.sockoder ähnlichem ausführen , sollten Sie es ändern. Denken Sie daran, dass das Mounten des Sockets schreibgeschützt keine Lösung ist, sondern nur die Ausnutzung erschwert. Äquivalent in der docker-compose-Datei ist etwa so:

volumes:
- "/var/run/docker.sock:/var/run/docker.sock"

REGEL 2 – Legen Sie einen Benutzer fest

Die Konfiguration des Containers für die Verwendung eines nicht privilegierten Benutzers ist der beste Weg, um Angriffe auf eine Rechteausweitung zu verhindern. Dies kann auf drei verschiedene Arten wie folgt erreicht werden:

Während der Laufzeit mit -u Option des docker run Befehls zB:

  • docker run -u 4000 alpine

Während der Bauzeit. Einfach Benutzer in Dockerfile hinzufügen und verwenden. Beispielsweise:

FROM alpine
RUN groupadd -r myuser && useradd -r -g myuser myuser
<HERE DO WHAT YOU HAVE TO DO AS A ROOT USER LIKE INSTALLING PACKAGES ETC.>
USER myuser

Aktivieren Sie die Unterstützung von Benutzernamensräumen ( --userns-remap=default) im Docker-Daemon Weitere Informationen zu diesem Thema finden Sie in der offiziellen Docker-Dokumentation

In Kubernetes kann dies im Sicherheitskontext mithilfe eines runAsNonRootFelds konfiguriert werden , z. B.:

kind: ...
apiVersion: ...
metadata:
  name: ...
spec:
  ...
  containers:
  - name: ...
    image: ....
    securityContext:
          ...
          runAsNonRoot: true
          ...

Als Kubernetes-Cluster-Administrator können Sie es mithilfe von Pod-Sicherheitsrichtlinien konfigurieren .

REGEL 3 – Beschränken Sie die Fähigkeiten (Gewähre nur bestimmte Fähigkeiten, die von einem Container benötigt werden)

Die Linux-Kernel-Fähigkeiten sind eine Reihe von Privilegien, die von Privilegierten verwendet werden können. Docker wird standardmäßig nur mit einer Teilmenge der Funktionen ausgeführt. Sie können es ändern und einige Funktionen löschen (mit --cap-drop), um Ihre Docker-Container zu härten, oder --cap-add bei Bedarf einige Funktionen hinzufügen (mit ). Denken Sie daran, keine Container mit dem --privileged Flag auszuführen - dies fügt dem Container ALLE Linux-Kernel-Funktionen hinzu.

Die sicherste Einrichtung besteht darin, alle Funktionen zu löschen --cap-drop allund dann nur die erforderlichen hinzuzufügen. Beispielsweise:

  • docker run --cap-drop all --cap-add CHOWN alpine

Und denken Sie daran: Führen Sie keine Container mit dem Flag --privileged aus !!!

In Kubernetes kann dies im Sicherheitskontext mit einem capabilities Feld konfiguriert werden , z. B.:

kind: ...
apiVersion: ...
metadata:
  name: ...
spec:
  ...
  containers:
  - name: ...
    image: ....
    securityContext:
          ...
          capabilities:
            drop:
              - all
            add:
              - CHOWN
          ...

Als Kubernetes-Cluster-Administrator können Sie es mithilfe von Pod-Sicherheitsrichtlinien konfigurieren .

REGEL 4 – Füge das Flag „no-new-privileges“ hinzu

Führen Sie Ihre Docker-Images immer mit --security-opt=no-new-privilegesaus, um zu verhindern, dass Berechtigungen setuid oder setgid Binärdateien eskalieren.

In Kubernetes kann dies im Sicherheitskontext mithilfe eines allowPrivilegeEscalationFelds konfiguriert werden , z. B.:

kind: ...
apiVersion: ...
metadata:
  name: ...
spec:
  ...
  containers:
  - name: ...
    image: ....
    securityContext:
          ...
          allowPrivilegeEscalation: false
          ...

Als Kubernetes-Cluster-Administrator können Sie die Kubernetes-Dokumentation zur Konfiguration mit Pod-Sicherheitsrichtlinien verwenden .

REGEL 5 – Deaktivieren der Kommunikation zwischen Containern (--icc=false)

Standardmäßig Inter-Container-Kommunikation (ICC) ist aktiviert - es bedeutet , dass alle Container miteinander (unter Verwendung sprechen können docker0 überbrückte Netzwerk ). Dies kann deaktiviert werden, indem der Docker-Daemon mit --icc=falseFlag ausgeführt wird. Wenn icc deaktiviert ist (icc=false), muss mit der Option --link=CONTAINER_NAME_or_ID:ALIAS mitgeteilt werden, welche Container kommunizieren können. Weitere Informationen finden Sie in der Docker-Dokumentation - Containerkommunikation

In Kubernetes können Netzwerkrichtlinien dafür verwendet werden.

REGEL 6 – Linux-Sicherheitsmodul verwenden (seccomp, AppArmor oder SELinux)

Deaktivieren Sie zunächst nicht das Standardsicherheitsprofil!

Ziehen Sie die Verwendung von Sicherheitsprofilen wie seccomp oder AppArmor in Betracht .

Anweisungen dazu in Kubernetes finden Sie in der Dokumentation zum Sicherheitskontext und in der Kubernetes-API-Dokumentation

REGEL 7 – Ressourcen begrenzen (Speicher, CPU, Dateideskriptoren, Prozesse, Neustarts)

Der beste Weg, um DoS-Angriffe zu vermeiden, besteht darin, die Ressourcen zu begrenzen. Sie können Speicher , CPU , maximale Anzahl von Neustarts ( --restart=on-failure:<number_of_restarts>), maximale Anzahl von Dateideskriptoren ( --ulimit nofile=<number>) und maximale Anzahl von Prozessen ( --ulimit nproc=<number>) begrenzen .

Weitere Informationen zu ulimits finden Sie in der Dokumentation

Sie können dies auch in Kubernetes tun: Zuweisen von Speicherressourcen zu Containern und Pods , Zuweisen von CPU-Ressourcen zu Containern und Pods und Zuweisen von erweiterten Ressourcen zu einem Container

REGEL 8 - Dateisystem und Volumes auf schreibgeschützt setzen

Führen Sie Container mit einem schreibgeschützten Dateisystem mit --read-only Flag aus. Beispielsweise:


  • docker run --read-only alpine sh -c 'echo "whatever" > /tmp'

Wenn eine Anwendung in einem Container vorübergehend etwas speichern muss, kombinieren Sie --read-only Flag mit --tmpfs wie folgt:


  • docker run --read-only --tmpfs /tmp alpine sh -c 'echo "whatever" > /tmp/file'

Äquivalent in der docker-compose-Datei ist:

version: "3"
services:
  alpine:
    image: alpine
    read_only: true

Äquivalent in Kubernetes im Sicherheitskontext ist:

kind: ...
apiVersion: ...
metadata:
  name: ...
spec:
  ...
  containers:
  - name: ...
    image: ....
    securityContext:
          ...
          readOnlyRootFilesystem: true
          ...

Wenn das Volume nur zum Lesen gemountet ist, mounten Sie es außerdem schreibgeschützt. Dies kann durch Anhängen :ro an Folgendes erfolgen -v:


  • docker run -v volume-name:/path/in/container:ro alpine

Oder mit --mountOption:

  • docker run --mount source=volume-name,destination=/path/in/container,readonly alpine

REGEL 9 – Verwenden Sie statische Analysetools

Um Container mit bekannten Schwachstellen zu erkennen, scannen Sie Bilder mit statischen Analysetools.

So erkennen Sie Fehlkonfigurationen in Kubernetes
  • kubeaudit
  • kubesec.io
  • Kube-Bank
So erkennen Sie Fehlkonfigurationen in Docker
  • inspec.io
  • dev-sec.io

REGEL #10 - Setzen Sie die Protokollierungsebene auf mindestens INFO

Standardmäßig ist der Docker-Daemon so konfiguriert, dass er einen Basis-Logging-Level von 'info' hat, und wenn dies nicht der Fall ist: Setzen Sie den Docker-Daemon-Log-Level auf 'info'. Begründung: Durch das Einrichten einer geeigneten Protokollebene wird der Docker-Daemon so konfiguriert, dass Ereignisse protokolliert werden, die Sie später überprüfen möchten. Eine Basisprotokollebene von 'info' und höher würde alle Protokolle außer den Debug-Protokollen erfassen. Solange dies nicht erforderlich ist, sollten Sie den Docker-Daemon nicht auf der Protokollebene 'debug' ausführen.

Regel 11 – Linkt das Dockerfile zur Build-Zeit

Viele Probleme können verhindert werden, indem Sie beim Schreiben des Dockerfiles einige Best Practices befolgen. Das Hinzufügen eines Sicherheits-Linters als Schritt in der Build-Pipeline kann viel dazu beitragen, weitere Kopfschmerzen zu vermeiden. Einige Punkte, die es wert sind, überprüft zu werden, sind:

  • Stellen Sie sicher, dass eine USER Anweisung angegeben ist
  • Stellen Sie sicher, dass die Basis-Image-Version angepinnt ist
  • Stellen Sie sicher, dass die Versionen der Betriebssystempakete angeheftet sind
  • Vermeiden Sie die Verwendung von ADD zugunsten von COPY
  • Vermeiden Sie Curl-Bashing in RUN Direktiven

So konfigurieren Sie die Protokollebene in docker-compose

  • docker-compose --log-level info up

Links

https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html

©Copyright 2021 - CheatSheets Series Team - Dieses Werk ist lizenziert unter einer Creative Commons Attribution 3.0 Unported License . Hergestellt mit Material für MkDocs