10 Best Practices zum Sichern von Docker-Images. Teil 2

Eine Übersetzung des Artikels wurde speziell für Studenten des Linux-Sicherheitskurses erstellt .


Lesen Sie den ersten Teil


5. Belassen Sie keine sensiblen Daten in Docker-Bildern


Manchmal benötigen Sie beim Erstellen einer Anwendung in einem Docker-Image vertrauliche Daten wie einen privaten SSH-Schlüssel zum Extrahieren von Code aus einem privaten Repository oder Token zum Installieren geschlossener Pakete. Wenn Sie sie in einen Docker-Zwischencontainer kopieren, werden sie in der Ebene zwischengespeichert, zu der sie hinzugefügt wurden, auch wenn Sie sie später löschen. Diese Token und Schlüssel müssen außerhalb der Dockerfile gespeichert werden.

Verwenden Sie mehrstufige Builds


Bearbeiten Sie mithilfe der Docker-Unterstützung für mehrstufige Builds Geheimnisse in der mittleren Bildebene, die anschließend gelöscht werden, damit keine vertraulichen Daten den endgültigen Build erreichen. Verwenden Sie den folgenden Code, um geheime Daten zur Middleware hinzuzufügen:

 FROM: ubuntu as intermediate WORKDIR /app COPY secret/key /tmp/ RUN scp -i /tmp/key build@acme/files . FROM ubuntu WORKDIR /app COPY --from=intermediate /app . 

Verwenden Sie Docker Secrets-Befehle


Verwenden Sie die Alpha-Funktion in Docker, um vertrauliche Daten zu verwalten und vertrauliche Dateien bereitzustellen, ohne sie zwischenzuspeichern:

 # syntax = docker/dockerfile:1.0-experimental FROM alpine # shows secret from default secret location RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecre # shows secret from custom secret location RUN --mount=type=secret,id=mysecret,dst=/foobar cat /foobar 

Weitere Informationen zum Verwalten vertraulicher Daten finden Sie auf der Docker-Website.

Achten Sie auf rekursives Kopieren


Sie sollten auch darauf achten, Dateien in das erstellte Image zu kopieren. Mit dem folgenden Befehl wird beispielsweise der gesamte Assemblykontextordner rekursiv in ein Docker-Image kopiert, wodurch auch vertrauliche Dateien kopiert werden können:

 COPY . . 

Wenn sich in Ihrem Ordner vertrauliche Dateien befinden, löschen Sie diese oder ignorieren Sie sie mit .dockerignore :

 private.key appsettings.json 

6. Verwenden Sie feste Tags für die Immunität


Jedes Docker-Bild kann mehrere Tags haben, die Variationen derselben Bilder darstellen. Das am häufigsten verwendete Tag ist " latest und steht für die neueste Version eines Bildes. Bild-Tags sind nicht unveränderlich, und ein Bildautor kann dasselbe Tag mehrmals veröffentlichen.

Dies bedeutet, dass sich das Basisimage für Ihre Docker-Datei zwischen den Builds ändern kann. Dies kann aufgrund von Änderungen am Basisimage zu unerwartetem Verhalten führen.

Es gibt verschiedene Möglichkeiten, um dieses Problem zu beheben:

  • Bevorzugen Sie das spezifischste verfügbare Tag. Wenn das Bild mehrere Tags hat, wie z. :8.0.1 :8 und :8.0.1 oder sogar :8.0.1-alpine , bevorzugen Sie letzteres, da dies der spezifischste Link zum Bild ist. Vermeiden Sie die Verwendung der gängigsten Tags, z. B. "latest". Denken Sie beim Fixieren eines bestimmten Tags daran, dass es eventuell gelöscht werden kann.
  • Um das Problem zu beheben, dass auf ein bestimmtes Image-Tag nicht mehr zugegriffen werden kann und die Anzeigenanzeige für Gruppen, die darauf angewiesen sind, eingeschränkt ist, sollten Sie einen lokalen Spiegel dieses Images in der Registrierung oder im Konto starten, die bzw. das von Ihnen gesteuert wird. Es ist wichtig, die für diesen Ansatz erforderlichen Wartungskosten zu berücksichtigen, da dies bedeutet, dass Sie die Registrierung warten müssen. Es wird empfohlen, das Image, das Sie in Ihrer Registrierung verwenden möchten, zu replizieren, um sicherzustellen, dass sich das von Ihnen verwendete Image nicht ändert.
  • Seien Sie äußerst spezifisch! Anstatt das Tag zu ziehen, ziehen Sie das Bild mithilfe eines bestimmten SHA256-Links zum Docker-Bild, um sicherzustellen, dass Sie für jede Anforderung dasselbe Bild erhalten. Beachten Sie jedoch, dass die Verwendung eines SHA256-Links das folgende Risiko birgt: Wenn sich das Bild ändert, funktioniert der Hash möglicherweise nicht mehr.

7. Verwenden Sie KOPIEREN anstelle von HINZUFÜGEN


Docker bietet zwei Befehle zum Kopieren von Dateien vom Host in das Docker-Image, wenn es erstellt wird: COPY und ADD . Befehle sind von Natur aus ähnlich, unterscheiden sich jedoch in ihrer Funktionalität:

  • KOPIEREN - kopiert rekursiv lokale Dateien und gibt dabei die Quell- und Zieldateien oder Verzeichnisse an. Mit COPY müssen Sie Standorte deklarieren.
  • ADD - kopiert rekursiv lokale Dateien, erstellt implizit ein Zielverzeichnis, wenn es nicht vorhanden ist, und akzeptiert Archive als lokale oder ferne URLs als Quelle, die es erweitert oder in das Zielverzeichnis lädt.
    Obwohl die Unterschiede zwischen ADD und COPY nicht so grundlegend sind, sind sie wichtig. Seien Sie sich dessen bewusst, um potenzielle Sicherheitsprobleme zu vermeiden:
  • Wenn Remote-URLs verwendet werden, um Daten direkt an ihren ursprünglichen Speicherort herunterzuladen, kann dies zu Brokerangriffen führen, die den Inhalt der heruntergeladenen Datei ändern. Darüber hinaus müssen Herkunft und Authentizität von Remote-URLs weiter überprüft werden. Bei Verwendung von COPY muss die Quelle für Dateien, die von Remote-URLs heruntergeladen werden sollen, über eine sichere TLS-Verbindung angegeben und ihre Herkunft muss ebenfalls überprüft werden.
  • Hinweise zum Speicherplatz und zu den Bildebenen: Mit COPY können Sie das Hinzufügen des Archivs von entfernten Speicherorten trennen und in verschiedene Ebenen entpacken, wodurch der Cache der Bilder optimiert wird. Wenn Remotedateien erforderlich sind, kombinieren Sie alle Dateien zu einem RUN-Befehl, der anschließend herunterlädt, extrahiert und löscht. Auf diese Weise wird der einschichtige Vorgang auf mehreren Ebenen optimiert, die mithilfe von ADD erforderlich wären.
  • Wenn lokale Archive verwendet werden, extrahiert ADD diese automatisch in das Zielverzeichnis. Dies ist zwar akzeptabel, birgt jedoch das Risiko, dass Zip-Bomben und Zip Slip-Sicherheitslücken entstehen , die dann automatisch gestartet werden können.

8. Verwenden Sie Metadaten-Tags


Bildbezeichnungen stellen Metadaten für die von Ihnen erstellten Bilder bereit. Auf diese Weise können Benutzer leichter herausfinden, wie das Bild verwendet wird. Das am häufigsten verwendete Tag lautet "Betreuer" und gibt die E-Mail-Adresse und den Namen der Person an, die dieses Bild unterstützt. Fügen Sie Metadaten mit dem folgenden LABEL Befehl hinzu:

 LABEL maintainer="me@acme.com" 

Fügen Sie zusätzlich zu den Kontakten des Betreuers alle für Sie wichtigen Metadaten hinzu. Diese Metadaten können Folgendes enthalten: einen Festschreibungs-Hash, einen Link zur entsprechenden Assembly, einen Qualitätsstatus (wurden alle Tests bestanden?), Einen Quellcode, einen Link zum Speicherort der Datei SECURITY.TXT usw.

Es wird empfohlen, die Datei SECURITY.TXT (RFC5785) zu unterstützen, die auf Ihre Richtlinie zur verantwortlichen Offenlegung für Ihr Docker-Etikettenschema verweist, wenn Sie neue hinzufügen. Beispiel:

 LABEL securitytxt="https://www.example.com/.well-known/security.txt" 

Weitere Label-Informationen für Docker-Images anzeigen:

https://label-schema.org/rc1/

9. Verwenden Sie eine mehrstufige Baugruppe für kleine und sichere Bilder


Wenn Sie eine Anwendung mit dem Dockerfile , werden viele Artefakte erstellt, die nur zum Zeitpunkt der Dockerfile erforderlich sind. Dies können Entwicklungstools und Bibliotheken sein, die zum Kompilieren benötigt werden, oder Abhängigkeiten, die zum Ausführen von Komponententests, temporären Dateien, Geheimnissen usw. benötigt werden.

Das Speichern dieser Artefakte in einem Basis-Image, das in der Produktion verwendet werden kann, führt zu einer Vergrößerung des Docker-Images, was sich erheblich auf die Zeit zum Herunterladen auswirken und auch die Angriffsfläche erhöhen kann, wodurch mehr Pakete installiert werden. Dasselbe gilt für das Docker-Image, das Sie verwenden. Möglicherweise benötigen Sie ein bestimmtes Docker-Image, um den Anwendungscode zu erstellen, aber nicht, um ihn auszuführen.

Golang ist ein gutes Beispiel. Um eine Golang-Anwendung zu erstellen, benötigen Sie einen Go-Compiler. Der Compiler erstellt eine ausführbare Datei, die auf jedem Betriebssystem ohne Abhängigkeiten ausgeführt wird, einschließlich sauberer Abbilder.

Dies ist ein guter Grund, warum Docker in der Lage ist, in Etappen zu bauen. Mit dieser Funktion können Sie während des Zusammenbaus mehrere temporäre Bilder verwenden und nur das letzte Bild zusammen mit den Informationen speichern, die Sie in das Bild kopiert haben. Sie haben also zwei Bilder:

  • Das erste Image ist sehr groß und mit vielen Abhängigkeiten verbunden, die zum Erstellen der Anwendung und Ausführen der Tests verwendet werden.
  • Das zweite Bild ist in Bezug auf Größe und Anzahl der Bibliotheken sehr hell und enthält nur Kopien der Artefakte, die zum Ausführen der Anwendung in der Produktion erforderlich sind.

10. Verwenden Sie den Linter


Verwenden Sie den Linter, um häufige Fehler zu vermeiden und Best Practices zu etablieren, die Ingenieure automatisch befolgen können.

Ein solcher Linter ist Hadolint . Es analysiert das Dockerfile und warnt vor Fehlern, die nicht den Empfehlungen entsprechen.



Hadolint wird in einer integrierten Entwicklungsumgebung (IDE) noch leistungsfähiger. Wenn Sie beispielsweise hadolint als VSCode-Erweiterung verwenden, treten bei der Eingabe Flusenfehler auf. Dies hilft beim schnelleren Schreiben der besten Dockerdateien.

Weitere Informationen zum Schutz Ihrer Docker-Bilder.

Source: https://habr.com/ru/post/de482044/


All Articles