Dateien mit cURL herunterladen und SHA-256-Prüfsummen prüfen
Laden Sie mit cURL eine Datei herunter und prüfen Sie deren Bytes mit
sha256sum anhand einer vertrauenswürdigen Prüfsumme. Das folgende Bash-Skript
hält den Download in einem temporären Verzeichnis und gibt ihm erst nach erfolgreicher Verifizierung
seinen endgültigen Dateinamen. Sie können dasselbe Skript lokal und in GitHub Actions ausführen.
Eine vertrauenswürdige Prüfsumme wählen
SHA-256 erzeugt einen 256-Bit-Hashwert, der meist als 64 Hexadezimalzeichen dargestellt wird. Ein übereinstimmender Hashwert bestätigt, dass die heruntergeladenen Bytes dem erwarteten Wert entsprechen. Er belegt nicht, wer diesen Wert bereitgestellt hat: Wer sowohl einen Download als auch seine Prüfsumme ersetzen kann, kann beide zur Übereinstimmung bringen.
Beziehen Sie die erwartete Prüfsumme über HTTPS aus den Release-Metadaten des Herausgebers und bewahren Sie sie zusammen mit der versionierten URL auf, von der Sie herunterladen möchten. Wenn Sie die Echtheit des Releases unabhängig von dessen Hosting-Website prüfen müssen, folgen Sie dem Verfahren des Herausgebers zur Signaturprüfung. Verwenden Sie dabei einen Signaturschlüssel, dessen Identität Sie unabhängig bestätigt haben. Das cURL-Projekt stellt separate Signaturen für seine Release-Archive bereit; das Prüfsummenbeispiel hier prüft diese Signaturen nicht.
Verifizierung mit Bash automatisieren
Verwenden Sie Linux mit Bash, einen cURL-Build mit HTTPS-Unterstützung und GNU coreutils:
sha256sum, mktemp, ln
und rm. Ziel ist das aktuelle Verzeichnis. Es muss beschreibbar sein
und auf einem Dateisystem liegen, das Hardlinks unterstützt. Das Skript verwendet
ln -T von GNU; es ist kein portables Skript für
/bin/sh oder macOS.
Die Beispiele wurden mit Bash 5.2.21, cURL 8.5.0 und coreutils 9.4 unter Ubuntu 24.04 sowie mit
Bash 5.3.15, cURL 8.22.0 und coreutils 9.11 unter Linux getestet.
Speichern Sie dies als verify-download.sh in einem Verzeichnis, das Sie kontrollieren.
Führen Sie es wie unten gezeigt mit Bash aus; binden Sie es nicht per Source in Ihre Shell ein.
Die drei Argumente sind die HTTPS-URL, der erwartete SHA-256-Hashwert und ein lokaler Dateiname.
Ausgabenamen dürfen Leerzeichen, führende Bindestriche oder wörtliche Zeichen
% enthalten, aber keinen Schrägstrich oder Zeilenumbruch.
Eine vorhandene Datei, ein Verzeichnis oder ein symbolischer Link gilt als Fehler und bleibt
unverändert.
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
if [[ $# -ne 3 ]]; then
printf 'Usage: bash verify-download.sh HTTPS_URL SHA256 OUTPUT_NAME\n' >&2
exit 2
fi
url=$1
expected=$2
output=$3
if [[ $url != https://* || ! $expected =~ ^[[:xdigit:]]{64}$ ]]; then
printf 'Provide an HTTPS URL and a 64-digit hexadecimal SHA-256 checksum.\n' >&2
exit 2
fi
case "$output" in
''|.|..|*/*|*$'\n'*|*$'\r'*)
printf 'Provide a filename without slashes or line breaks.\n' >&2
exit 2
;;
esac
if [[ -e "./$output" || -L "./$output" ]]; then
printf 'Destination already exists: %s\n' "$output" >&2
exit 1
fi
umask 077
temp_dir=$(mktemp -d ./.verify-download.XXXXXX)
trap 'rm -rf -- "$temp_dir"' EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
curl -q -fsSL --globoff --proto '=https' --proto-redir '=https' \
--connect-timeout 10 --max-time 120 --retry 3 \
--output "$temp_dir/payload" --url "$url"
if ! printf '%s %s\n' "$expected" "$temp_dir/payload" | sha256sum --check --status -; then
printf 'SHA-256 mismatch or unreadable download.\n' >&2
exit 1
fi
ln -T -- "$temp_dir/payload" "./$output"
printf 'Verified: %s\n' "$output"
Die cURL-Optionen lassen HTTP-Fehler wie 404 zum Fehlschlag führen
(-f), blenden die Fortschrittsanzeige aus, ohne Fehlermeldungen zu
unterdrücken (-sS), und folgen Weiterleitungen
(-L). Sowohl die ursprüngliche Anfrage als auch Weiterleitungen sind
auf HTTPS beschränkt. --globoff behandelt die URL wörtlich;
-q steht an erster Stelle und verhindert, dass eine lokale
.curlrc die Anfrage verändert. Bei vorübergehenden Fehlern erfolgen bis zu
drei Wiederholungsversuche, mit einem Zeitlimit von 120 Sekunden pro Übertragungsversuch.
Das Skript erstellt einen Prüfsummeneintrag: den Hashwert, zwei Leerzeichen und den privaten Pfad
der Nutzdaten.
GNU sha256sum --check
liest diesen Eintrag von der Standardeingabe. Mit --status entscheidet der
Exit-Status darüber, ob die Verifizierung erfolgreich war. Keine entfernte Prüfsummendatei darf
bestimmen, welche lokalen Dateinamen geprüft werden.
Nach einer Übereinstimmung fügt
GNU ln
der bereits verifizierten Datei den endgültigen Namen hinzu. -T
behandelt das Ziel als exakten Namen, auch wenn dort ein Verzeichnis existiert. Da
-f fehlt, wird nichts ersetzt. Das temporäre Verzeichnis liegt neben
dem Ziel, sodass beide Namen auf demselben Dateisystem liegen. Der Exit-Trap entfernt den temporären
Namen und das Verzeichnis; die verifizierte Datei bleibt unter ihrem endgültigen Namen erhalten.
Fehler beim Download oder bei der Prüfsummenprüfung liefern einen Rückgabewert ungleich null und
entfernen temporäre Daten, ohne die endgültige Datei anzulegen. Erneute Ausführungen beginnen einen
neuen Download; sie setzen keine teilweise heruntergeladenen Daten fort. Die Traps behandeln auch
normale Unterbrechungen. Ein Stromausfall oder SIGKILL kann jedoch ein
Verzeichnis .verify-download.* hinterlassen, das manuell entfernt werden muss.
Dies ist ein Download in ein Verzeichnis, das Ihnen gehört, kein Schutz vor einem anderen Prozess,
der Ihre Dateien verändern kann.
Ein cURL-Release verifizieren
Das Release cURL 8.22.0 enthält
curl-8.22.0.tar.gz. Seine
Release-Metadaten geben für genau diese Datei den Wert
digest als
sha256:d54dd598bf05927a726deb38df31c6a255ba83ff1de57c5d1464dac3ed8f44a1 an.
Verwenden Sie die 64 Zeichen nach sha256: als erwarteten Wert.
Die Dateien .tar.xz und .zip haben andere Bytes
und Prüfsummen.
Dies sind JSON-Metadaten, keine Eingabedatei für sha256sum --check.
Versuchen Sie nicht, eine Prüfsummen-URL durch Anhängen von .sha256 an eine
Download-URL zu erraten: curl-8.5.0.tar.gz.sha256 stellt unter dieser Adresse keine Datei
bereit. Hier legen wir den für die Release-Datei veröffentlichten Hashwert fest und laden das
Archiv von curl.se herunter:
bash verify-download.sh \
'https://curl.se/download/curl-8.22.0.tar.gz' \
'd54dd598bf05927a726deb38df31c6a255ba83ff1de57c5d1464dac3ed8f44a1' \
'curl-8.22.0.tar.gz'
Bei Erfolg endet der Befehl mit dem Status null und gibt Folgendes aus:
Verified: curl-8.22.0.tar.gz
Das Archiv liegt nun in Ihrem aktuellen Verzeichnis. Damit laden Sie Quellcode herunter; cURL wird weder installiert noch aktualisiert. Um das Beispiel zu wiederholen, verwenden Sie einen anderen Ausgabenamen oder entfernen Sie zuvor bewusst den vorherigen Download. Um ein anderes Release zu verifizieren, wählen Sie dessen exakte Datei und aktualisieren Sie sowohl die URL als auch den Hashwert.
Integration in GitHub Actions
Legen Sie verify-download.sh im Stammverzeichnis Ihres Repositorys ab und speichern
Sie diesen Workflow als .github/workflows/verify-download.yml. Er verwendet dieselbe festgelegte URL
und denselben Hashwert. Der letzte Schritt listet das verifizierte Archiv mit den Ubuntu-Befehlen
tar und gzip auf. Ersetzen Sie ihn durch
Ihren Build-Schritt, sobald die Prüfung funktioniert.
name: Verify download
on: [push, pull_request]
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- name: Download and verify
shell: bash
run: |
bash verify-download.sh \
'https://curl.se/download/curl-8.22.0.tar.gz' \
'd54dd598bf05927a726deb38df31c6a255ba83ff1de57c5d1464dac3ed8f44a1' \
'curl-8.22.0.tar.gz'
- name: Read verified archive
shell: bash
run: tar -tzf curl-8.22.0.tar.gz > /dev/null
GitHub Actions stoppt nach einem Fehler standardmäßig nachfolgende Schritte.
Behalten Sie dieses Verhalten bei: Wenn Sie continue-on-error oder ein
|| true hinzufügen, das einen Erfolg erzwingt, könnte ein späterer Schritt
auch nach fehlgeschlagener Verifizierung fortfahren. Prüfen Sie Änderungen an Prüfsummen zusammen
mit Aktualisierungen von Abhängigkeiten. Einen „erwarteten“ Hashwert aus der gerade heruntergeladenen
Datei zu berechnen, würde sie nur mit sich selbst vergleichen.
Fehlerbehebung
- HTTP-Fehler, einschließlich
curl: (22): Prüfen Sie die exakte URL der Release-Datei. Eine Fehlerseite darf nicht zu Ihrem Release-Archiv werden. Auch eine Weiterleitung zu HTTP wird abgelehnt, selbst wenn das Ziel erreichbar ist. - Unvollständige Übertragung, etwa
curl: (18): Der Server hat die Antwort geschlossen, bevor die angekündigte Länge angekommen ist. Prüfen Sie die Verbindung und versuchen Sie es erneut. Meldet der Server eine kürzere Datei als erfolgreiche Antwort, lehnt der Prüfsummenvergleich die veränderten Bytes dennoch ab. - SHA-256 stimmt nicht überein: Gleichen Sie die Release-Version und die Dateiendung des Archivs mit den Metadaten des Herausgebers ab. Ersetzen Sie die erwartete Prüfsumme nicht durch den Wert des verdächtigen Downloads.
- Ziel existiert bereits: Die vorherige Datei bleibt erhalten. Wählen Sie einen anderen lokalen Namen oder prüfen und entfernen Sie den vorherigen Download selbst.
- Hardlink- oder Schreibfehler: Verwenden Sie ein beschreibbares lokales Dateisystem, das Hardlinks unterstützt. Schlägt der Schritt zur Bereitstellung unter dem endgültigen Namen fehl, liefert er einen Rückgabewert ungleich null, selbst wenn die Prüfsumme übereinstimmt.
