Dateiintegrität mit sha512sum in CI/CD automatisieren
Vergleichen Sie mit sha512sum --check --strict checksums.sha512 Dateien mit einem freigegebenen
Prüfsummenmanifest, bevor Ihre Pipeline sie verwendet. Schlägt die Prüfung fehl, gibt der Befehl
einen Exit-Status ungleich null zurück. So kann ein verändertes oder fehlendes Artefakt den Job
stoppen. Entscheidend ist, woher die erwarteten Prüfsummen stammen.
Eine vertrauenswürdige Vergleichsbasis wählen
Eine SHA-512-Prüfsumme beschreibt die Bytes einer Datei. Eine übereinstimmende Prüfsumme sagt für sich genommen nicht aus, wer diese Bytes erstellt hat. Wenn jemand sowohl eine Datei als auch ihre erwartete Prüfsumme ersetzen kann, kann die Prüfung dennoch erfolgreich sein.
Erstellen Sie für Ihre eigenen unveränderlichen Dateien ein Manifest aus freigegebenen Dateien und prüfen Sie Änderungen an diesem Manifest. Beziehen Sie bei einem Download die erwartete Prüfsumme über einen authentifizierten Kanal des Herausgebers. Wenn signierte Prüfsummen verfügbar sind, befolgen Sie zuerst dessen Anweisungen zur Signaturprüfung. Die Anleitung von Debian zur Image-Verifizierung zeigt diesen Unterschied zwischen der Prüfung heruntergeladener Bytes und der Authentifizierung ihrer Quelle.
Das folgende Beispiel erfasst zwei kleine Dateien als Vergleichsbasis und verwendet diese anschließend in CI erneut. Neue Prüfsummen aus beliebigen Dateien zu erzeugen, die CI erhält, würde den Vergleich wirkungslos machen.
Ablauf der Dateiprüfung
Verwenden Sie Bash und GNU coreutils. Diese Beispiele wurden mit Bash 5.1 und coreutils 8.32 unter Ubuntu 22.04 sowie mit Bash 5.3 und coreutils 9.12 unter macOS getestet. Prüfen Sie die Implementierung, bevor Sie fortfahren:
sha512sum --version
Die erste Zeile sollte GNU coreutils ausweisen. Ein gleichnamiger Befehl kann eine
andere Implementierung sein. Unter macOS stellt
das coreutils-Paket von Homebrew GNU-Werkzeuge bereit. Befolgen Sie
dessen PATH-Anweisungen zu gnubin, um die Namen ohne Präfix zu verwenden.
Führen Sie jeden folgenden Bash-Block aus demselben übergeordneten Verzeichnis aus. Die Klammern
begrenzen Verzeichniswechsel auf eine Subshell. Diese Einrichtung erstellt ein neues Verzeichnis
namens sha512-demo und verweigert die Wiederverwendung eines vorhandenen
Verzeichnisses. Eine erneute Ausführung überschreibt Ihre Dateien daher nicht:
(
set -eC
mkdir sha512-demo
cd sha512-demo
mkdir assets
printf 'release 1\n' > assets/app.txt
printf '{"mode":"production"}\n' > assets/config.json
)
Hier stoppt set -e die Subshell bei einem Fehler, und
-C verhindert, dass die Ausgabeumleitung eine vorhandene reguläre Datei
überschreibt. Falls die Einrichtung fehlschlägt, beheben Sie den Fehler, bevor Sie zum nächsten
Block wechseln. Wählen Sie ein anderes übergeordnetes Verzeichnis, wenn Sie ein weiteres
Demobeispiel benötigen.
Hashes erzeugen
Erstellen Sie das Manifest einmalig, solange beide Dateien die freigegebenen Bytes enthalten:
(
set -eC
cd sha512-demo
sha512sum -- assets/app.txt assets/config.json > checksums.sha512
)
Jede Zeile enthält einen 128-stelligen hexadezimalen SHA-512-Hashwert, eine Moduskennzeichnung und einen Dateinamen. Durch die explizite Dateiliste führt eine fehlende Eingabe zu einem Fehler, und das Manifest wird nicht selbst gehasht. Ersetzen Sie diese Liste für Ihre eigenen Dateien und setzen Sie Dateinamen mit Leerzeichen in Anführungszeichen.
Dieser Befehl verweigert auch das Überschreiben einer vorhandenen Datei namens
checksums.sha512. Falls die Erstellung fehlschlägt, verwenden Sie das neu erstellte
Manifest nicht: Es könnte leer oder unvollständig sein. Bewahren Sie das bisherige freigegebene
Manifest auf, wenn Sie eine beabsichtigte Aktualisierung vorbereiten, und prüfen Sie den Ersatz,
bevor Sie ihn übernehmen.
Dateien prüfen
Führen Sie die Prüfung in dem Verzeichnis aus, von dem aus die relativen Dateinamen erstellt wurden:
(
cd sha512-demo &&
sha512sum --check --strict checksums.sha512
)
Mit den Originaldateien lautet die Ausgabe:
assets/app.txt: OK
assets/config.json: OK
--check liest das Manifest und vergleicht jede darin benannte Datei.
--strict sorgt außerdem dafür, dass fehlerhaft formatierte Prüfsummenzeilen
zum Fehlschlagen der Prüfung führen, selbst wenn andere Einträge übereinstimmen. Auch ein leeres
Manifest führt zu einem Fehler. Fügen Sie --ignore-missing nicht hinzu, wenn jedes
aufgeführte Artefakt erforderlich ist. Diese Optionen sind im
von Debian bereitgestellten GNU-Handbuch zu sha512sum dokumentiert.
Um den Fehlerfall auszuprobieren, bearbeiten Sie sha512-demo/assets/app.txt und führen Sie den
Prüfblock erneut aus. Er meldet assets/app.txt: FAILED und endet mit einem Exit-Status
ungleich null. Stellen Sie die ursprünglich freigegebenen Bytes wieder her, bevor Sie die
folgenden CI-Beispiele für eine erfolgreiche Prüfung verwenden. Lassen Sie das Manifest unverändert.
Fehlerbehandlung und häufige Probleme
Berechtigungsprobleme
Das Prüfprogramm benötigt Lesezugriff auf das Manifest und die Dateien sowie Zugriff über deren übergeordnete Verzeichnisse. Prüfen Sie die Berechtigungen und bitten Sie bei Bedarf den Eigentümer um entsprechenden Zugriff. Ändern Sie nicht pauschal die Eigentumszuordnung und machen Sie sensible Dateien nicht öffentlich zugänglich, nur damit eine Prüfung erfolgreich ist.
Abweichende Hashwerte untersuchen
Eine Abweichung bedeutet, dass sich die Bytes von der Vergleichsbasis unterscheiden. Ursachen können ein unvollständiger Download, geänderte Zeilenenden oder eine beabsichtigte Bearbeitung sein. Beschaffen Sie eine neue vertrauenswürdige Kopie oder untersuchen Sie die Änderung. Die erwartete Prüfsumme neu zu erzeugen, würde die Abweichung verbergen.
Ein Fehler wegen einer fehlenden Datei kann auch bedeuten, dass Sie den Befehl im falschen Verzeichnis ausgeführt haben. Relative Pfade im Manifest werden ausgehend vom Arbeitsverzeichnis des Prozesses aufgelöst, nicht vom Speicherort des Manifests. Beschaffen Sie bei fehlerhaft formatierten Zeilen das Originalmanifest, statt eine formatierte Prüfsummentabelle von einer Webseite zu kopieren. Erfassen Sie sowohl die Standardausgabe als auch die Standardfehlerausgabe in den CI-Protokollen, damit Sie die Ursache erkennen können.
CI/CD-Integration
Fügen Sie für dieses Beispiel mit unveränderlichen Dateien sha512-demo/assets/ und das
freigegebene Manifest sha512-demo/checksums.sha512 Ihrem Repository hinzu. Beide folgenden
Workflows prüfen diese ausgecheckten Dateien, ohne das Manifest neu zu erzeugen. Prüfen Sie
Manifeständerungen: Ein Pull Request, der sowohl die Dateien als auch ihre erwarteten Hashwerte
ändert, kann diese Prüfung bestehen.
Platzieren Sie die Prüfung vor dem Schritt, der die Dateien verwendet, und machen Sie das Deployment von ihrem Erfolg abhängig. Wenn Ihre Artefakte aus einem anderen Job stammen, rufen Sie sie vor der Prüfung ab und halten Sie das freigegebene Manifest getrennt von der Ausgabe, die dieser Job erzeugt.
Beispiel für GitHub Actions
Fügen Sie dies als .github/workflows/integrity.yml hinzu oder integrieren Sie den Prüfschritt in
einen vorhandenen Workflow. Er verwendet actions/checkout, um das
Repository abzurufen:
name: Verify file integrity
on: [push, pull_request]
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Verify approved assets
working-directory: sha512-demo
shell: bash
run: sha512sum --check --strict checksums.sha512
Bei GitHub gibt die explizit angegebene Shell bash einen fehlgeschlagenen
Befehl an den Schritt weiter. Siehe dazu die
Dokumentation zu Shells in Workflows.
Lassen Sie die Fehlerunterdrückung für diesen Schritt deaktiviert.
Beispiel für GitLab CI
Integrieren Sie für einen GitLab-Runner mit Docker-Executor diesen Job in
.gitlab-ci.yml:
verify_integrity:
image: ubuntu:22.04
script:
- cd sha512-demo
- sha512sum --check --strict checksums.sha512
Das Ubuntu-Image stellt GNU coreutils bereit. GitLab
lässt den Job bei einem Exit-Status ungleich null eines Skriptbefehls fehlschlagen,
auch bei einem fehlgeschlagenen Verzeichniswechsel. Behalten Sie die Befehle als separate
Skripteinträge bei und aktivieren Sie allow_failure für diese Freigabeprüfung nicht.
Änderungen nach einem Docker-Build erkennen
Um Artefakte zu prüfen, die aus einem Image kopiert wurden, vergleichen Sie diese exportierten Dateien vor ihrer Verteilung mit dem freigegebenen Manifest. Ein während des Builds erzeugtes Manifest kann spätere Byteänderungen nur erkennen, solange es selbst vertrauenswürdig bleibt. Es kann weder die Authentizität der Build-Eingaben nachweisen noch davor schützen, dass jemand sowohl die Dateien als auch das Manifest ersetzt.
Aussagekraft einer erfolgreichen Prüfung verstehen
Die Prüfung liest jede aufgeführte Datei. Bei großen Artefakten müssen daher sämtliche Bytes erneut gelesen werden. Sie prüft weder nicht aufgeführte Dateien noch Eigentumszuordnung, Berechtigungen oder Zeitstempel. Ein erfolgreiches Ergebnis bedeutet, dass die aufgeführten Bytes mit der Vergleichsbasis übereinstimmen. Es beweist nicht, dass das Verzeichnis ausschließlich freigegebene Dateien enthält oder dass der Build reproduzierbar ist.
