Entfernen von Build-Geheimnissen aus einem Image

DockerBeginner
Jetzt üben

Einführung

Build-Geheimnisse können in Images gelangen, wenn ein Dockerfile zu viel aus dem Build-Kontext kopiert. Der häufige Fehler ist COPY . /app/: Es ist zwar bequem, kann aber Token, Anmeldedaten, lokale Notizen und temporäre Dateien in das finale Image einschleusen. Sobald sich ein Geheimnis in einem Image-Layer befindet, können Laufzeitkontrollen diesen Fehler in der Lieferkette nicht mehr zuverlässig beheben.

In diesem Lab erstellen Sie ein bewusst undichtes lokales Image, weisen nach, dass ein Build-Token darin enthalten ist, und korrigieren den Build-Prozess, indem Sie die Kopiergrenzen im Dockerfile einschränken und eine .dockerignore-Datei hinzufügen. Abschließend stellen Sie das saubere Image bereit und verifizieren, dass der Laufzeit-Container das Build-Geheimnis nicht mehr enthält.

Untersuchung des unsicheren Build-Kontexts

In diesem Schritt untersuchen Sie den Build-Kontext und das unsichere Dockerfile. Der Build-Kontext ist das Verzeichnis, das an den Image-Builder gesendet wird. Wenn das Dockerfile den gesamten Kontext kopiert, kann jede Datei in diesem Verzeichnis Teil des finalen Images werden.

Beginnen Sie im Lab-Arbeitsbereich:

cd /home/labex/project/build-secret-image

Lesen Sie die Notizen:

sed -n '1,120p' BUILD_SECRET_NOTES.md

Listen Sie die Dateien auf, die derzeit im Build-Kontext existieren:

find . -maxdepth 1 -type f -printf '%f\n' | sort | tee evidence/initial-context-files.txt

Überprüfen Sie das unsichere Dockerfile:

sed -n '1,120p' Dockerfile.insecure | tee evidence/insecure-dockerfile-review.txt

Die riskante Zeile ist COPY . /app/. Sie kopiert app.sh, aber auch build-token.txt. Im nächsten Schritt werden Sie dieses Image erstellen und das Leck aus der Image-Laufzeitumgebung heraus nachweisen.

Erstellen des undichten Images und Nachweis des Geheimnisses

In diesem Schritt erstellen Sie das unsichere Image innerhalb des labex-v134 minikube-Profils. Durch das Erstellen innerhalb des Profils wird das Image für die Kubernetes-Node-Laufzeitumgebung sichtbar.

Kopieren Sie das unsichere Dockerfile in den aktiven Dockerfile-Namen und erstellen Sie das undichte Image:

cp Dockerfile.insecure Dockerfile
minikube -p labex-v134 image build -t labex/leaky-build:1.0 .

Führen Sie das Image innerhalb der minikube Docker-Laufzeitumgebung aus und suchen Sie nach der Token-Datei:

minikube -p labex-v134 ssh -- 'docker run --rm --entrypoint /bin/sh labex/leaky-build:1.0 -c "ls -l /app && cat /app/build-token.txt"' | tee evidence/leaky-image-contents.txt

Sie sollten build-token=labex-temporary-secret sehen. Das ist das Leck. Das Image läuft zwar, enthält aber eine Datei, die außerhalb des finalen Laufzeit-Images hätte bleiben sollen.

Erstellen eines sauberen Images mit begrenzter Kopiergrenze

In diesem Schritt korrigieren Sie den Image-Build. Zwei Änderungen sind wichtig: .dockerignore hält das Token aus dem Build-Kontext fern, der an den Builder gesendet wird, und das Dockerfile kopiert nur app.sh, anstatt das gesamte Verzeichnis zu kopieren.

Erstellen Sie .dockerignore:

cat > .dockerignore <<'EOF'
build-token.txt
evidence/
*.txt
EOF

Erstellen Sie das saubere Dockerfile:

cat > Dockerfile <<'EOF'
FROM busybox:1.36

WORKDIR /app
COPY app.sh /app/app.sh
RUN chmod 0555 /app/app.sh

USER 65534:65534
ENTRYPOINT ["/app/app.sh"]
EOF

Erstellen Sie das saubere Image:

minikube -p labex-v134 image build -t labex/clean-build:1.0 .

Untersuchen Sie das saubere Image aus der minikube Docker-Laufzeitumgebung heraus:

minikube -p labex-v134 ssh -- 'docker run --rm --entrypoint /bin/sh labex/clean-build:1.0 -c "ls -l /app; if [ -f /app/build-token.txt ]; then echo BUILD_SECRET_PRESENT; else echo NO_BUILD_SECRET; fi; id -u"' | tee evidence/clean-image-contents.txt

Die Ausgabe sollte NO_BUILD_SECRET und die UID 65534 anzeigen.

Bereitstellen des sauberen Images

In diesem Schritt stellen Sie das saubere Image bereit und verifizieren, dass der laufende Container meldet, dass kein Build-Geheimnis vorhanden ist. Dies hält den endgültigen Nachweis nah an Kubernetes, wo das Image tatsächlich ausgeführt wird.

Erstellen und wenden Sie das Pod-Manifest an:

cat > clean-build-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: clean-build-app
  namespace: cks-prep-build-secret
  labels:
    app: clean-build-app
spec:
  restartPolicy: Never
  containers:
    - name: app
      image: labex/clean-build:1.0
      imagePullPolicy: Never
      securityContext:
        runAsNonRoot: true
        runAsUser: 65534
        runAsGroup: 65534
        allowPrivilegeEscalation: false
EOF
kubectl apply -f clean-build-pod.yaml

Warten Sie auf den Pod und lesen Sie dessen Logs:

kubectl -n cks-prep-build-secret wait --for=condition=Ready pod/clean-build-app --timeout=120s
kubectl -n cks-prep-build-secret logs clean-build-app | tee evidence/clean-pod-logs.txt

Die Logs sollten Folgendes enthalten:

clean build image ready
NO_BUILD_SECRET

Zusammenfassung

Sie haben einen unsicheren Image-Build-Kontext untersucht, ein undichtes Image erstellt, das Vorhandensein des Build-Tokens nachgewiesen und den Build-Prozess anschließend mit .dockerignore und einer präzisen COPY-Anweisung im Dockerfile korrigiert. Sie haben ein sauberes Image erstellt und bereitgestellt, das als Non-Root-Benutzer ausgeführt wird und NO_BUILD_SECRET meldet. Damit ist die Stufe der Lieferkettensicherheit abgeschlossen, indem die Hygiene beim Image-Build mit der Kubernetes-Laufzeitverifizierung verknüpft wurde.