Ein Release verifizieren
Restow ist Software, die Ihre Sicherungen und Ihre Schlüssel hält. Sie sollten daher prüfen können, dass das, was Sie betreiben, das ist, was das Projekt gebaut hat, und sehen können, was vor der Veröffentlichung getestet wurde. Diese Seite zeigt, wie, und sagt offen, wo die Prüfungen enden.
Was in einem Release steckt
Abschnitt betitelt „Was in einem Release steckt“Jedes Release ist ein GitHub-Release in restow-backup/restow, die Images liegen in der GitHub Container Registry. Ein Release enthält:
- Zwei Images, jeweils für
linux/amd64undlinux/arm64:ghcr.io/restow-backup/restow(API, Worker, Scheduler, restic, die Agent-Downloads und das eigenständige Restore-Werkzeugrestow-restore) undghcr.io/restow-backup/restow-web(der Caddy-Edge und die Weboberfläche). Beide tragen denselben Tag und sind mit cosign signiert. - Die Smoke-Berichte:
smoke-report.md(amd64) undsmoke-report-arm64.md, das Ergebnis des unten beschriebenen Release-Smoke-Laufs. Die Release-Notes fassen sie im Abschnitt Verification zusammen. - Die Agent-Binärdateien für das Endpunkt-Backup:
restow-agent_<version>_<os>-<arch>für Linux und macOS auf amd64 und arm64. - Die SBOMs:
restow-<version>-linux-<arch>.spdx.json, eine je Architektur, im SPDX-Format. - Der Release-Stack:
docker-compose.ymlundenv.example, die Dateien ausdeploy/release/, gegen die der Smoke-Lauf testet. SHA256SUMS(der SHA-256 jeder anderen Datei des Releases) undSHA256SUMS.sigstore.json(die cosign-Signatur dieser Liste).
Die Release-Notes nennen außerdem die Digests der beiden Multi-Architektur-Manifeste, je eine Zeile (restow: sha256:... und restow-web: sha256:...). Der optionale Updater prüft die gezogenen Images gegen diese beiden Zeilen.
Docker-Tags
Abschnitt betitelt „Docker-Tags“- 0.x.y (Beta):
:<version>und:beta. Ein:latestgibt es noch nicht. - Ab 1.0.0, ein stabiles Release:
:<version>,:MAJOR.MINOR,:MAJORund:latest. - Eine Vorabversion (
-rc.N): nur:<version>.
Nennen Sie für alles, woran Ihnen liegt, die genaue Version in der .env (RESTOW_IMAGE, RESTOW_WEB_IMAGE) statt eines wandernden Tags, damit ein Update dann passiert, wenn Sie es entscheiden. Siehe Updates.
Eine Image-Signatur prüfen
Abschnitt betitelt „Eine Image-Signatur prüfen“Die Images sind mit cosign im schlüssellosen Modus (keyless) signiert. Es gibt keinen langlebigen Signaturschlüssel, der abfließen könnte: Der Release-Workflow auf GitHub Actions weist seine Identität über das OIDC-Token von GitHub gegenüber Sigstore nach und erhält ein kurzlebiges Zertifikat. Die Prüfung stellt fest, dass die Signatur von genau diesem Workflow, im Repository restow-backup/restow, auf einem Versions-Tag erstellt wurde.
cosign verify ghcr.io/restow-backup/restow:0.1.0 \ --certificate-identity-regexp '^https://github.com/restow-backup/restow/\.github/workflows/release\.yml@refs/tags/v' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comFühren Sie denselben Befehl für ghcr.io/restow-backup/restow-web:0.1.0 aus. Fehlt eine Signatur, stammt sie von einem anderen Workflow oder gehört sie zu anderem Inhalt, beendet cosign den Befehl mit einem Fehler. Die Release-Pipeline signiert mit cosign 3.1.3, verwenden Sie daher ein aktuelles cosign.
Um genau das Manifest zu prüfen, das in den Release-Notes steht, setzen Sie statt des Tags seinen Digest ein: ghcr.io/restow-backup/restow@sha256:<Digest> mit denselben zwei Optionen. Die Signatur wurde über dieses Manifest erstellt.
Die SBOM prüfen
Abschnitt betitelt „Die SBOM prüfen“Jede Architektur hat eine Software-Stückliste (SBOM) im SPDX-Format, mit syft aus dem Image erzeugt. Sie erhalten sie zweimal:
- als Datei
restow-<version>-linux-<arch>.spdx.jsonam GitHub-Release, zum Lesen, Scannen und Archivieren, und - als cosign-Attestation vom Typ
spdxjson, die am Image dieser Architektur hängt, sodass sie durch eine Signatur an das Image gebunden ist und nicht nur durch einen Dateinamen.
Die Attestation hängt am Image jeder einzelnen Architektur (an dessen eigenem Digest), nicht am Multi-Architektur-Tag. docker buildx imagetools inspect ghcr.io/restow-backup/restow:0.1.0 listet den Digest jeder Plattform auf. Die Optionen unten stammen aus dem Release-Workflow (--type spdxjson ist der Typ, mit dem er attestiert, die Identitäts-Optionen sind die der Signatur). Der Befehl selbst wurde noch nicht gegen ein veröffentlichtes Release ausgeführt. Schlagen Sie daher in der cosign-Dokumentation zu verify-attestation nach, falls er sich in Ihrer Version anders verhält:
cosign verify-attestation --type spdxjson \ ghcr.io/restow-backup/restow@sha256:<Digest des Images linux/amd64 oder linux/arm64> \ --certificate-identity-regexp '^https://github.com/restow-backup/restow/\.github/workflows/release\.yml@refs/tags/v' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comDie Prüfsummen prüfen
Abschnitt betitelt „Die Prüfsummen prüfen“SHA256SUMS listet den SHA-256 jeder Datei des Releases auf, auch der Agent-Binärdateien, der SBOMs, der Smoke-Berichte, der docker-compose.yml und der env.example. Die Liste ist mit cosign schlüssellos signiert, und SHA256SUMS.sigstore.json ist diese Signatur als Sigstore-Bundle. Laden Sie beide Dateien neben den Dateien herunter, die Sie prüfen möchten, und prüfen Sie dann die Signatur der Liste und die Dateien gegen die Liste. Die Option --bundle ist das Gegenstück zum --bundle, mit dem der Release-Workflow signiert, und die Identitäts-Optionen sind dieselben wie oben:
cosign verify-blob SHA256SUMS \ --bundle SHA256SUMS.sigstore.json \ --certificate-identity-regexp '^https://github.com/restow-backup/restow/\.github/workflows/release\.yml@refs/tags/v' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com
sha256sum -c --ignore-missing SHA256SUMS--ignore-missing überspringt die Dateien, die Sie nicht heruntergeladen haben. Die Agent-Binärdateien im Release sind dieselben, die im smoke-getesteten Image liegen. So können Sie eine Agent-Binärdatei auch unabhängig von Ihrer eigenen Restow-Instanz prüfen (siehe den letzten Abschnitt).
Was der Release-Smoke-Lauf prüft
Abschnitt betitelt „Was der Release-Smoke-Lauf prüft“Bevor etwas veröffentlicht wird, startet ein Skript genau die Images, die veröffentlicht werden sollen, aus dem Release-Stack (deploy/release/docker-compose.yml) auf einem frischen Runner, einmal auf amd64 und einmal auf arm64, und führt die folgenden Prüfungen aus. Das Release hängt daran: Schlägt eine Prüfung fehl, wird nichts veröffentlicht. Dasselbe Skript läuft nachts auf main, ohne etwas zu veröffentlichen, und Sie können es selbst ausführen (pnpm smoke im Repository). Der Bericht jedes Laufs hängt am Release. Die Prüfungen:
- Installation. Das Image trägt seine Metadaten (Version, Revision, Plattform), restic,
restow-restoreund die Agent-Downloads mit ihren Prüfsummen. Der Release-Compose-Stack startet auf einer leeren Datenbank mit allen angewendeten Migrationen. Gibt es ein früheres Release, wird ein Stack der vorherigen Images mit einem Mandanten und einem Backup auf die neuen Images umgestellt. Am Ende wird die API auf der gefüllten Datenbank neu gestartet und ändert nichts. - Health.
/healthzund/readyzantworten, der Edge antwortet über HTTPS, Worker und Scheduler haben sich gemeldet, und kein Container startet ständig neu. - Passkey-Anmeldung. Erst-Einrichtung, dann in einem echten Browser: Notfall-Anmeldung, einen Passkey auf einem virtuellen Authenticator registrieren, abmelden und mit dem Passkey wieder anmelden, einen Mandanten im Assistenten anlegen, und jeder Bildschirm auf Deutsch und Englisch ohne fehlende Übersetzung.
- Microsoft 365 gegen einen Entwicklermandanten. Läuft nur, wenn Zugangsdaten für einen Microsoft-365-Entwicklermandanten als Repository-Secrets konfiguriert sind, nie gegen einen Kundenmandanten, und sagt sonst in klaren Worten „übersprungen“.
- IMAP-Backup und -Restore. Ein Postfach mit 24 Nachrichten in zwei Ordnern auf einem echten IMAP-Server, ein Backup, drei weitere Nachrichten und ein inkrementelles Backup, ein Restore neben die Originale mit jeder wiederhergestellten Nachricht per SHA-256 verglichen und die Restore-Prüfung grün.
- Journal-Empfang und Kettenprüfung. Ein synthetischer Exchange-Journalbericht per SMTP, das Archivobjekt vorhanden, die Hash-Kette geprüft und durch einen zweiten Bericht fortgesetzt, eine unbekannte Journaladresse abgewiesen und der Archiv-Export (eine EML-ZIP mit
MANIFEST.csvundSHA256SUMS) enthält die Originale byte-genau. - Eigenständiger Restore.
restow-restoreaus dem Image stellt bei gestopptem Server und ohne Netzwerk im Container den Speicher aus Prüfung 5 wieder her, und jede Datei stimmt überein. Eine Kopie mit einem beschädigten Byte wird abgewiesen. - Speicherziele. S3 (Garage), ein lokaler Pfad und ein eingehängtes Verzeichnis, das für eine NFS- oder SMB-Freigabe steht, bekommen je einen Schreibvorgang (ein Backup), einen Lesevorgang (die Restore-Prüfung) und einen Scrub.
- Scans. Trivy auf dem Image und
pnpm auditauf hohe und kritische Meldungen. Kritische Funde, für die es eine Korrektur gibt, lassen den Lauf scheitern. Kritische Funde ohne Korrektur stehen im Bericht, sie werden nicht verschwiegen. - Endpunkt-Backup und -Restore. Das echte Install-Skript installiert den Agent in einem Linux-Container aus dem laufenden Stack, meldet ihn mit einem Einmal-Token an, sichert einen Ordner, und eine Restore-Aufgabe legt ihn in einem neuen Verzeichnis ab, in dem jede Datei per SHA-256 übereinstimmt.
- Mail-Import und -Export. EML-Dateien und eine MBOX im Import-Ordner des Servers sowie eine in Stücken hochgeladene MBOX werden zu einem importierten Postfach. Es wird als EML-ZIP und als MBOX-Dateien exportiert. Die EML-Dateien kommen byte-genau zurück, jede Nachricht per Message-ID, und beide Prüfsummenlisten stimmen mit den Dateien überein. Siehe Mail-Dateien importieren und exportieren.
Was der Smoke-Lauf nicht tut
Abschnitt betitelt „Was der Smoke-Lauf nicht tut“Der Bericht nennt jeden dieser Punkte, und keiner wird je als bestanden dargestellt:
- Microsoft 365 gegen einen echten Mandanten. Prüfung 4 wurde noch nicht gegen einen echten Mandanten ausgeführt. Der Codepfad ist nach der API und dem dokumentierten Graph-Verhalten umgesetzt, und bei seinem ersten echten Lauf sind Korrekturen an Details zu erwarten. Das ist der wichtigste Grund, die Beta neben Ihren bestehenden Sicherungen zu betreiben.
- Der Update-Pfad. Es gibt vor 0.1.0 kein früheres öffentliches Release, deshalb meldet dieser Teil von Prüfung 1 „nicht ausgeführt“. Er läuft ab dem nächsten Release.
- Journal-Objekte werden nicht mit ihrer Quelle verglichen. Das Journal-Token eines Mandanten setzt die Prüfung selbst in der Datenbank, weil es noch keine API gibt, die es herausgibt, und keine API liefert die Rohbytes eines archivierten Objekts. Der Export ist daher der Zeuge dafür, dass die Originale unverändert zurückkommen.
- Kritische Funde ohne Korrektur. Der Scan kann nichts gegen Kritisches tun, das die Distribution nicht behoben hat (zum Beispiel im Debian-Basisimage). Sie werden aufgelistet, nicht als Fehler gezählt.
- Windows. 0.1.0 hat keinen Windows-Agent, und die Endpunkt-Prüfung läuft nur unter Linux.
Was die CI bei jedem Pull Request prüft
Abschnitt betitelt „Was die CI bei jedem Pull Request prüft“Jeder Pull Request und jeder Push führt Folgendes aus, und ein Release wiederholt alles auf dem getaggten Commit:
- Lint und eine Sperre, dass der Kern nie aus den
ee/-Modulen importiert, - Typprüfung, Unit-Tests und die Tests gegen ein echtes PostgreSQL, mit einer Sperre, dass keine der PostgreSQL-Suiten übersprungen wurde,
- i18n-Vollständigkeit: Jeder Schlüssel der englischen Übersetzung existiert auf Deutsch und umgekehrt,
- der vollständige Build und ein Docker-Build beider Images mit einem Blick hinein (restic,
restow-restore, die Agent-Prüfsummen, die Image-Labels), pnpm auditauf hohe und kritische Meldungen,- Abhängigkeitslizenzen gegen eine Positivliste und aktuelle Hinweise zu Drittsoftware,
- ein Secret-Scan über die Historie (gitleaks),
- der Go-Agent: Formatierung,
go vet, Tests mit Race-Detektor, ShellCheck, Integrationstests gegen das echte restic und einen Append-only-REST-Server, das Install-Skript und die Cross-Builds für Linux und macOS, - ShellCheck für jedes Shell-Skript und ein Linter für die Workflows.
Die Pipeline verwendet nur das GITHUB_TOKEN des Laufs: kein persönliches Zugriffstoken und keinen langlebigen Signaturschlüssel. Jede Drittanbieter-Action ist auf einen Commit festgelegt, und jedes Container-Image, das ein Schritt ausführt, ist per Digest festgelegt.
Prüfungen für Mitwirkende
Abschnitt betitelt „Prüfungen für Mitwirkende“Pull Requests von außen brauchen außerdem zwei Dinge, die automatisch geprüft werden: eine unterschriebene Contributor License Agreement (CLA; ein Kommentar am Pull Request, der im Repository festgehalten wird) und ein Developer-Certificate-of-Origin-Sign-off (DCO) bei jedem Commit (git commit -s). Wie die Editionen und der Quellcode lizenziert sind, steht unter Lizenz und Editionen.
Was nicht signiert ist
Abschnitt betitelt „Was nicht signiert ist“Ehrlichkeit über die Lücken ist wichtiger als eine lange Liste grüner Prüfungen:
- Die Agent-Binärdateien sind nicht codesigniert. Sie tragen keine Code-Signatur, und Updates des Agents sind ebenfalls nicht signiert. Die Install-Skripte und das Self-Update des Agents prüfen SHA-256-Prüfsummen, die von Ihrer eigenen Restow-Instanz stammen, derselben Instanz, die die Binärdateien ausliefert. Das schützt vor beschädigten oder abgeschnittenen Downloads, nicht vor einer kompromittierten Instanz. Signierte Agent-Releases sind ein späterer Schritt. Um eine Binärdatei unabhängig zu prüfen, vergleichen Sie sie mit der signierten
SHA256SUMSdes Releases, wie oben gezeigt. - Restow prüft seine eigene Signatur nicht. Die cosign-Signatur zu prüfen, tun Sie von Hand. Der optionale Updater prüft die gezogenen Images gegen die Digests in den Release-Notes, nicht die Signatur, und die Update-Prüfung liest nur die Release-Liste.
- Eine Signatur ist keine Prüfung des Inhalts. Sie belegt, welcher Workflow aus welchem Tag ein Image gebaut hat. Sie ersetzt nicht das Lesen der Release-Notes und den Test einer Wiederherstellung Ihrer eigenen Daten.