Backups unter Windows mit Restic

Ich sichere meine Daten regelmäßig und auf mehreren verschiedenen Datenträgern, so ist mir bisher noch nichts nennenswertes verloren gegangen. Das ganze mache ich unter Linux aktuell mit Back in Time, das per rsync und Hardlinks Snapshots auf eine externe Festplatte anlegt. Die Festplatte ist per LUKS verschlüsselt, und somit sind die Daten geschützt und nicht für dritte einsehbar.

Hier gibt es aber noch ein Windows-Laptop, für das ich mich verantwortlich fühle. Mir erscheint es sinnvoller mich im Vorfeld um die Datensicherung zu kümmern, als irgendwann bei Datenverlust die schlechten Nachrichten überbringen zu müssen. Also suchte ich nach einer vertrauenswürdigen Backup-Lösung für Windows. Ich bin jetzt bei Restic gelandet.

Generell fühle ich mich unter Windows ziemlich unwohl. Es funktioniert überhaupt nicht so, wie ich das unter Linux gewohnt bin. Dazu kommt noch ein komplett anderes Ökosystem an Software, die ich auch nicht einschätzen kann. Und gerade bei Backups möchte ich etwas langweiliges und verlässliches haben. Solange die Daten nur auf externen Festplatten in der Wohnung liegen, ist Verschlüsselung nicht so wichtig, weil das Laptop selbst nicht verschlüsselt ist. Bei Backups in die Cloud ist mir das allerdings sehr wichtig.

Ich hatte bisher Paragon Backup & Recover CE genutzt. Das ist kostenlos, und kann anscheinend inkrementelle Backups machen. Ich habe aber keinerlei Idee, wie das im Hintergrund funktioniert. Ich habe auch nicht wirklich die Recovery getestet. Es schien irgendwie Daten zu sichern, das erschien mir erstmal hinreichend zu sein. Die GUI fand ich nicht wirklich hilfreich, alles viel zu groß, der Informationsgehalt eher gering.

Dazu bin ich dann auch von diesem Hersteller abhängig, und ich weiß nicht, ob man das immer wiederherstellen können wird. Also habe ich mal auf Twitter gefragt und bekam Restic empfohlen. Das ist freie Software und gibt es für Linux und Windows. Das klingt schon einmal deutlich besser.

Restic verschlüsselt immer, das ist schon großartig. Dann können die Repositories lokal angelegt werden, aber auch über diverse Protokolle wie SFTP oder FTPS angesprochen werden. Man braucht auf der Gegenseite nichts besonderes, nur ein Dateisystem. Das kann man bei diversen Cloud-Anbietern bekommen. Die meisten werden direkt oder indirekt über rclone unterstützt. Die Backups von Windows kann ich dann auch unter Linux lesen, das ist also wunderbar für diesen Anwendungsfall.

Generell ist es sinnvoll, die Backup-Software für das jeweilige Betriebssystem angepasst zu wählen. In einem Windows-Ökosystem würde man bestimmt noch andere Dinge nutzen. Aber hier bei mir ist es ein Linux-Ökosystem, in das noch ein Windowslaptop rein soll. Daher ist das schon ganz passend so.

Restic unter Windows

Es gibt noch Restic Skripte für Windows, die einem ganz viel abnehmen. Man muss sie nur per ZIP-Datei von GitHub herunterladen und auspacken. Dann kann man sie mit einem Texteditor anpassen, das sieht dann zum Beispiel so aus:

Danach muss man sie noch freischalten, sonst kommt diese Meldung hier:

PS C:\restic> .\install.ps1
.\install.ps1 : Die Datei "C:\restic\install.ps1" kann nicht geladen werden. Die Datei "C:\restic\install.ps1" ist
nicht digital signiert. Sie können dieses Skript im aktuellen System nicht ausführen. Weitere Informationen zum         Ausführen von Skripts und Festlegen der Ausführungsrichtlinie erhalten Sie unter "about_Execution_Policies"             (https:/go.microsoft.com/fwlink/?LinkID=135170)..                                                                       In Zeile:1 Zeichen:1                                                                                                    + .\install.ps1                                                                                                         + ~~~~~~~~~~~~~
    + CategoryInfo          : Sicherheitsfehler: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

Das Kommando zum Freischalten steht auch in der Dokumentation:

PS C:\restic> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

Ausführungsrichtlinie ändern
Die Ausführungsrichtlinie trägt zum Schutz vor nicht vertrauenswürdigen Skripts bei. Wenn Sie die Ausführungsrichtlinie
 ändern, sind Sie möglicherweise den im Hilfethema "about_Execution_Policies" unter
"https:/go.microsoft.com/fwlink/?LinkID=135170" beschriebenen Sicherheitsrisiken ausgesetzt. Möchten Sie die
Ausführungsrichtlinie ändern?
[J] Ja  [A] Ja, alle  [N] Nein  [K] Nein, keine  [H] Anhalten  [?] Hilfe (Standard ist "N"): A

Als nächstes muss man die Dateien noch einzeln als vertrauenswürdig markieren, sonst kommt das hier:

PS C:\restic> .\install.ps1
.\install.ps1 : Die Datei "C:\restic\install.ps1" kann nicht geladen werden. Die Datei "C:\restic\install.ps1" ist
nicht digital signiert. Sie können dieses Skript im aktuellen System nicht ausführen. Weitere Informationen zum
Ausführen von Skripts und Festlegen der Ausführungsrichtlinie erhalten Sie unter "about_Execution_Policies"
(https:/go.microsoft.com/fwlink/?LinkID=135170)..
In Zeile:1 Zeichen:1
+ .\install.ps1
+ ~~~~~~~~~~~~~
    + CategoryInfo          : Sicherheitsfehler: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

Das geht hiermit:

PS C:\restic> Unblock-File *.ps1

Nun kann man die installation durchlaufen lassen. Ich habe es als Test erstmal auf eine externe Festplatte gepackt:

PS C:\restic> .\install.ps1
[[Init]] Repository successfully initialized.
created restic repository ee25e8b2b9 at D:\restic-test

Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.
[[Init]] Repository successfully initialized.
[[Scheduler]] Backup task scheduled.

Das trägt dann auch direkt noch ein Kommando ein, sodass das automatisch jeden Tag durchläuft. In einem deutschen Windows heißt das Teil Aufgabenplanung, und sieht unter Windows 10 so furchtbar aus, wie ich es erwartet hatte:

Dort gibt es keine Suchfunktion, aber man kann das Restic Backup dann dort finden:

Dies habe ich einmal händisch gestartet, um es zu testen. In der Logdatei stand dann das hier:

[[Internet]] Local repository. Skipping internet connectivity check.
[[Backup]] Start 04/03/2022 16:22:28
[[Backup]] Start 04/03/2022 16:22:28 [C:\]
no parent snapshot found, will read all files
creating VSS snapshot for [c:\]
successfully created snapshot for [c:\]

Files:         275 new,     0 changed,     0 unmodified
Dirs:           90 new,     0 changed,     0 unmodified
Added to the repo: 249.125 MiB

processed 275 files, 252.579 MiB in 0:22
snapshot 1e1962f0 saved
[[Backup]] Completed with errors
[[Backup]] End 04/03/2022 16:22:51 [C:\]
[[Backup]] End 04/03/2022 16:22:51
[[Maintenance]] Start 04/03/2022 16:22:51
[[Maintenance]] Start forgetting...
Applying Policy: keep 30 daily, 52 weekly, 24 monthly, 10 yearly snapshots
keep 1 snapshots:
ID        Time                 Host        Tags        Reasons           Paths
--------------------------------------------------------------------------------------------------
1e1962f0  2022-04-03 16:22:28  mu-fx8320   C:\         daily snapshot    C:\Users\Martin\Documents
                                                       weekly snapshot
                                                       monthly snapshot
                                                       yearly snapshot
--------------------------------------------------------------------------------------------------
1 snapshots

[[Maintenance]] Start pruning...
loading indexes...
loading all snapshots...
finding data that is still in use for 1 snapshots
[0:00] 100.00%  1 / 1 snapshots

searching used packs...
collecting packs for deletion and repacking
[0:00] 100.00%  56 / 56 packs processed


to repack:            0 blobs / 0 B
this removes          0 blobs / 0 B
to delete:            0 blobs / 0 B
total prune:          0 blobs / 0 B
remaining:          433 blobs / 249.138 MiB
unused size after prune: 0 B (0.00% of remaining size)

done
[[Maintenance]] Start checking...
using temporary cache in C:\WINDOWS\TEMP\restic-check-cache-362139903
create exclusive lock for repository
load indexes
check all packs
check snapshots, trees and blobs
no errors were found
[0:00] 100.00%  1 / 1 snapshots

[[Maintenance]] End 04/03/2022 16:24:56
[[General]] Errors found. Log: C:\restic\logs\20220403T1622276765.err.txt
[[Retry]] Sleeping for 15 min and then retrying...
[[History]] Backup success rate: 1 / 3 (33,33 %)
[[Email]] Sending email completed with errors

Das Problem war wohl eine Datei, die nicht aus der Schattenkopie gezogen werden konnte. Naja, klingt nicht so wild.

restic.exe : error: open \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4\Users\Martin\Documents\zocker.kdb: Access is 
denied.
In C:\restic\backup.ps1:255 Zeichen:13
+             & $ResticExe backup $folder_list $vss_option --tag "$tag" ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (error: open \\?...cess is denied.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Warning: at least one source file could not be read
[[Backup]] Completed with errors
[[General]] Errors found. Log: C:\restic\logs\20220403T1622276765.err.txt
[[Email]] Sending email completed with errors

Der Snapshot ist jedenfalls da:

PS C:\restic> restic -r 'D:\restic-test' snapshots
repository ee25e8b2 opened successfully, password is correct
ID        Time                 Host        Tags        Paths
--------------------------------------------------------------------------------
1e1962f0  2022-04-03 16:22:28  mu-fx8320   C:\         C:\Users\Martin\Documents
--------------------------------------------------------------------------------
1 snapshots

Ich habe den Ordner dann einmal auf mein Linux-System kopiert und dort mit restic mount eingebunden. Dann kann man dort alle Snapshots anschauen. Das hat super geklappt, alle Dateien waren da.

Alle Daten sichern

Als nächstes habe ich dann den kompletten Nutzerordner sichern wollen. Man muss ein bisschen aufpassen, weil der angezeigte Pfad zwar »Benutzer« im Explorer ist, aber »Users« wirklich auf dem Dateisystem.

Das initiale Backup schien recht schnell auf die externe Festplatte zu laufen, Auslastung war sehr gut.

Es gab dann allerdings auch Probleme, und zwar liegt das OneDrive im Nutzerverzeichnis. Anscheinend kann davon keine Schattenkopie erstellt werden, wahrscheinlich weil es ein anderes Dateisystem ist. Ich habe das daher von der Sicherung ausgeschlossen, mit der local.exclude. Da muss man den ganzen Pfad angeben, also C:\Users\…\OneDrive. Alternativ kann man wohl auch noch auf die Schattenkopie verzichten. Ich kenne mich aber unter Windows nicht genug aus, um zu wissen, ob das sinnvoll oder gefährlich ist.

Hetzner Storage Box

Neben der externen Festplatte möchte ich aber auch noch einen Cloud-Speicher haben. Zum einen muss dann die externe Festplatte nicht regelmäßig an das Laptop angeschlossen werden. Zum anderen schützt es aber auch gegen Verletzung der Wohnung wie Einbruch, Brand oder Hochwasser (unwahrscheinlich hier).

Anbieter für Speicher gibt es viel. Ich habe jetzt Hetzner Storage Box genommen, weil es Zugriff per SFTP anbietet und die Server in Deutschland stehen. Eine andere Variante wäre Backblaze B2, das ich schon früher einmal genutzt hatte. Dort stehen die Server wahrscheinlich in den USA. Preislich tut sich da nicht viel, beides wenige EUR/Monat.

Die Storage Box bietet auch noch Sub-Accounts an, das ist sehr praktisch. Dadurch kann jedes Laptop nochmal komplett getrennt werden und nicht versehentlich die Backups der anderen Rechner überschreiben. Restic kann zwar Repositories teilen um noch mehr Deduplizierung zu machen, jedoch erscheint mir das hier bei uns keinen Vorteil zu bringen.

Erfreulicherweise war unter Windows 11 schon SSH direkt mit dabei. Ich habe auf meinem Linuxrechner ein RSA-Schlüsselpaar erzeugt. Diesen trägt man dann wie gewohnt unter .ssh/authorized_keys innerhalb des Sub-Accounts in der Storage Box ein. Die Schlüssel packt man im Windows-Rechner dann im Nutzerverzeichnis nach .ssh, auch wenn das unter Windows etwas deplaziert wirkt. Als Repository-Pfad nutzt man dann sftp://u1234-sub1@u1234-sub1.your-storagebox.de:23/. Es ist ganz wichtig, dass man Port 23 nutzt, weil man für Port 22 (Standard) nochmal ein merkwürdiges Schlüsselformat braucht, was nicht geklappt hatte. Aber mit Port 23 geht es dann.

Dann habe ich das Restic Backup nochmal gestartet, und es fing an viele Dateien hochzuladen. Das sieht dann doch wunderbar aus!

Eine weitere schicke Möglichkeit der Storage Box sind 10 automatische Snapshots. Jede Woche wird jetzt ein neuer Snapshot angelegt, sodass ein versehentliches oder böswilliges Löschen der Backups innerhalb von 10 Wochen behoben werden kann. Das ist noch eine gute weitere Absicherung gegen Crypto-Trojaner oder ähnlichem.

Automatisierung klemmt

Irgendwie sind dann aber keine weiteren Backups auf dem Server aufgetaucht. Irgendwas ist auf dem Client also noch kaputt. In der Aufgabenplanung kann man sehen, dass die Aufgabe die ganze Zeit läuft. Es sieht für mich so aus, als würde das Programm nicht sauber beenden und daher auch kein neues Backup angestoßen werden.

Ich habe also versucht die Ursache zu finden. Da gibt es einen Ordner mit Logdateien, in den man schauen kann:

Schaut man die letzte Datei an, so findet man das hier:

restic.exe : subprocess ssh: load pubkey "C:\\WINDOWS\\system32\\config\\systemprofile/.ssh/id_rsa": Permission denied
In C:\restic\backup.ps1:80 Zeichen:14
+     $locks = & $ResticExe list locks --no-lock -q 3>&1 2>> $ErrorLog
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (subprocess ssh:...rmission denied:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Da stimmt also irgendwas mit den Berechtigungen nicht. Die Berechtigungen von Windows verstehe ich nicht. Das scheint irgendwie komplex mit ACL zu sein, und noch SELinux zu übersteigen von der Komplexität her. Ich verstehe es nicht, und ich habe auch ehrlich gesagt keine Lust mit damit auseinanderzusetzen.

Um überhaupt erst in den Ordner zu kommen, muss man den Explorer als Admin starten. Dazu muss man nach C:\Windows\Explorer.exe navigieren und den per Rechtsklick als Admin starten. Dann kann man in den Ordner:

Von dort aus kann man dann die Berechtigungen anzeigen lassen:

DAs sieht so aus, als hätte der Nutzer System da Zugriff drauf. Aber mal schauen, was die erweiterten Rechte so sagen. Da war dann als Besitzer noch der normale Account eingetragen. Das habe ich geändert auf System:

Das war SSH dann aber auch nicht mehr recht, dann waren es plötzlich zu viele Rechte:

restic.exe : subprocess ssh: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
In C:\restic\backup.ps1:80 Zeichen:14
+     $locks = & $ResticExe list locks --no-lock -q 3>&1 2>> $ErrorLog
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (subprocess ssh:...@@@@@@@@@@@@@@@:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

subprocess ssh: @         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
subprocess ssh: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
subprocess ssh: Permissions for 'C:\\WINDOWS\\system32\\config\\systemprofile/.ssh/id_rsa' are too open.
subprocess ssh: It is required that your private key files are NOT accessible by others.
subprocess ssh: This private key will be ignored.
subprocess ssh: Load key "C:\\WINDOWS\\system32\\config\\systemprofile/.ssh/id_rsa": bad permissions

Boah, ey. Unter Linux ist das ein chmod 0600, aber was ist das unter Windows? Also nochmal dahin navigiert. Und dann kann man die Rechte schon gar nicht mehr einsehen:

Klickt man auf Erweitert, so sieht man dann auch nichts:

Irgendwann später war ich noch einmal da, da sah es dann anders aus:

Ich konnte den Besitzer auf System ändern:

Ich bin davon ausgegangen, dass ich die Rechte entfernt hatte. Aber als ich nochmal reingeschaut hatte, war der normale Nutzer dann doch wieder da:

Ändern ging irgendwie auch nicht, wegen geht nicht:

Wegen ist nicht:

Ich hatte dann keinen Bock mehr. Wenn jemand das liest und sich mit den Berechtigungen unter Windows 11 auskennt, freue ich mich über eine E-Mail.

Ich bin dann in der Aufgabenplanung hingegangen und habe versucht den Nutzer zu ändern, unter dem das ausgeführt wird. Das ging aber auch nicht:

Sie haben eine Erkältung, oder Krebs, oder ihre Wohnungstüre ist nicht abgeschlossen, oder ich bin gar kein Arzt. Und da fehlt ein Leerzeichen.

Ich habe dann die Aufgabe als XML exportiert, die Aufgabenverwaltung unter dem normalen Nutzer noch einmal gestartet und die Aufgabe importiert. Das ging dann noch immer nicht, bis ich dann irgendwann die funktionierende Kombination gefunden habe:

Man muss also den Benutzer eingeben und dann auf Namen überprüfen klicken.

Dann wird der Name mit dem Rechnernamen vervollständigt. Der Nutzername ist natürlich nicht der, der angezeigt wird, sondern ein interner Name.

Dann die Aufgabe so einstellen, dass sie unabhängig von der Benutzeranmeldung ausgeführt wird. Das Passwort nicht speichern. Hier klappt das korrekte Passwort nämlich nicht. Das braucht man wohl nur, wenn man sich gegen ein Active Directory ausweisen muss. Dank SSH ist das hier nicht der Fall.

Jedenfalls klappt es jetzt so, das Backup wurde hochgeladen. Nachdem das Backup fertig war, war die Aufgabe aber noch nicht zu Ende. Die ist wohl wieder stecken geblieben. Insgesamt scheint es aber zu funktionieren. Vielleicht hängt es am E-Mail-Versand. Aber trotzdem kommt so grob alle drei Tage ein neuer Snapshot an. Das ist schon einmal deutlich besser als gar nichts.