Eigentlich wollte ich in diesem Blogbeitrag beschreiben, wie ich das Erstellen einer Sicherheitskopie meines Obsidian Vault, welches ich bisher händisch via Forklift angestoßen habe, mit der Hilfe von rsync
und dem launchd
-Framework auf meinem Mac automatisiere. Mit Forklift erstellte ich eine inkrementelle Sicherheitskopie, also wurden nur neue oder modifizierte Dateien übertragen. Ausserdem wurden auch alle Dateien in der Sicherheitskopie gelöscht, die auch im Quellordner gelöscht wurden. Dies sollte nun automatisch alle Stunde stattfinden.
Nachdem ich die entsprechenden Skripte und Befehle erstellt und beschrieben hatte, fiel mir jedoch auf, dass das zeitgesteuerte und automatische Erstellen einer Sicherheitskopie eigentlich keine gute Idee ist, da ein versehentliches Löschen einer Datei oder des Inhalts des Ordners dann auch beim nächsten Sicherungslauf auf der Synology nachvollzogen wird.
Daher habe ich den Blogartikel etwas modifiziert und beschreibe nun, wie ich statt Forklift zu nutzen, bei dem einige Schritte auszuführen sind, das Ganze in einen Apple-Kurzbefehl einbinde, den ich einfach in der Menüleiste aufrufen kann.
Es ist aber ein weiterer Artikel geplant, in dem ich, auch mit dem Befehl rsync
dann ein wirkliches automatisches Backup erstelle. Die Vorbereitungen werden aber gleich sein, nur der rsync
-Aufruf muss dann etwas angepasst werden. Was ich aber gerne vor einer veröffentlich etwas testen möchte.
Vorgehensweise
ssh
undrsync
müssen auf dem Mac installiert sein.- Auf der Synology muss der Remote-Zugriff mit SSH aktiviert sein.
- Die SSH-Konfigurationsdatei muss entsprechend angepasst und der Schlüssel im Mac-Schlüsselbund hinterlegt werden.
- Das entsprechende
rsync
-Kommando wird in einen Kurzbefehl gepackt
Schritt 1: SSH auf der Synology aktivieren
Zunächst sollte sichergestellt werden, dass auf dem Mac ssh
und rsync
installiert sind. Dazu wird auf dem Mac ein Terminal Fester gestartet und folgende Befehle eingeben:
ssh -v localhost
und
rsync -V
Beide Befehle sollten eigentlich installiert sein. Falls nicht können sie mit homebrew nachinstalliert werden.
Auf der Synology wird in der Systemsteuerung unter „Terminal & SNMP” der SSH-Dienst aktiviert:
Ausserdem muss noch die rsync-Option in den Datendiensten angeschaltet werden. Dies hatte ich in einer ersten Version des Artikels noch verneint, korrigiere mich aber hiermit. Damit ist der Teil, der auf der Synology stattfindet, erledigt. Als Test kann das Terminal aufgerufen werden, um sich mit SSH mit der Synology zu verbinden:
leif@mac:$ ssh 192.168.1.80 The authenticity of host '192.168.1.80 (192.168.1.80)' can't be established. ED25519 key fingerprint is SHA256:Ob4Waq/MTrWU9wEvL/jENlP1/uMPk5/ibPYhJ6i9c94. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.1.80' (ED25519) to the list of known hosts. leif@192.168.1.80's password: Using terminal commands to modify system configs, execute external binary files, add files, or install unauthorized third-party apps may lead to system damages or unexpected behavior, or cause data loss. Make sure you are aware of the consequences of each command and proceed at your own risk. Warning: Data should only be stored in shared folders. Data stored elsewhere may be deleted when the system is updated/restarted. leif@Synology:$
Damit wird bei der ersten Verbindung mit dem Server via SSH ein Schlüssel als Fingerabdruck des Servers auf dem Computer hinterlegt, der unter ~/.ssh/known_hosts
gespeichert wird.
Schritt 2: SSH Konfiguration auf dem Mac
Damit eine SSH-Verbindung ohne Passworteingabe funktioniert, sind einige Schritte notwendig. Das meiste dazu habe ich mir „klassisch” durch Videos und andere Informationsquellen angeeignet. Sehr lehrreich fand ich ein Video von Martin Leyrer, das ich nur empfehlen kann: Besser leben mit SSH — media.ccc.de. Die Vortragsvideos von Martin Leyrer kann ich generell empfehlen.
Als erstes muss auf dem Mac ein SSH-Schlüssel-Paar erstellt werden. Dabei sollte für jeden Server immer ein eigenes Schlüssel-Paar erstellt werden:
ssh-keygen -a 420 -f ~/.ssh/synology-tutorial.ed25519 -C "My Synology Tutorial key"
Dieser Befehl erstellt einen privaten und einen öffentlichen Schlüssel mit dem ed25519-Verschlüsselungsalgorithmus. Die Option -a
macht das Ganze etwas sicherer, da eine weitere Funktion verwendet wird. Die Option -f
definiert den Speicherort und den Namen, typischerweise im Verzeichnis ~/.ssh
(die Tilde steht für das Home-Verzeichnis). Die Option -C
gibt dem Key einen Namen, womit später auf dem Server der Schlüssel identifiziert werden kann. Bei der Generierung wird auch nach einer Passphrase gefragt. Hier sollte ein sicheres Passwort vergeben werden, aber nicht vergessen, es sich zu merken.
Wenn kein Fehler auftritt, wird eine Bestätigung angezeigt, die etwa so aussieht:
Generating public/private ed25519 key pair. Enter passphrase (empty for no passphrase): PASSWORD_EINGABE Enter same passphrase again: PASSWORD_EINGABE Your identification has been saved in /Users/leif/.ssh/synology-tutorial.ed25519 Your public key has been saved in /Users/leif/.ssh/synology-tutorial.ed25519.pub The key fingerprint is: SHA256:XXXXXXXxxxxxxxrXXXXXXXXXXXXXXXXXXXXXXXX My Synology Tutorial key The key's randomart image is: +--[ED25519 256]--+ | .+hjjjs+..| | Bolls...| | jdjdj +*| | *kd*| | a s. ..| | sss .aa . | | sasad .| | .oso s . | | .=ss . | +----[SHA256]-----+
Das Verzeichnis ~/.ssh
auf dem Mac sollte dann etwa so aussehen:
ls -la ~/.ssh drwx------ 5 leif staff 160 17 Mai 17:44 . drwxr-x---+ 18 leif staff 576 17 Mai 17:32 .. -rw------- 1 leif staff 268 17 Mai 17:19 known_hosts -rw------- 1 leif staff 464 17 Mai 17:39 synology-tutorial.ed25519 -rw-r--r-- 1 leif staff 106 17 Mai 17:39 synology-tutorial.ed25519.pub
Es wurde also ein privater Schlüssel synology-tutorial.ed25519
und ein öffentlicher Schlüssel synology-tutorial.ed25519.pub
erstellt. Der private Schlüssel ist natürlich auf dem Rechner zu behalten, während der öffentliche Schlüssel nun auf die Synology kopiert wird:
ssh-copy-id -i ~/.ssh/synology-tutorial.ed25519.pub 192.168.1.80
Wobei die 192.168.1.80
die lokale IP-Adresse meiner Synology ist. Hier könnte auch der Servername stehen, falls im lokalen Netz die Namen vom DNS-Server aufgelöst werden. Da bei mir den Geräte feste IP-Adressen zugeordnet sind, nehme ich an dieser Stelle die IP-Adresse. Bei dem Aufruf benötige ich keinen Benutzer-Namen, da ich auf beiden System den gleichen Namen nutze. Ansonsten müsste der Benutzer-Name vom Server der IP-Adresse vorangestellt werden.
Nachdem nun der öffentliche Schlüssel übertragen wurde, kann getestet werden, ob man sich mit dem Schlüssel anmelden kann:
ssh -i ~/.ssh/synology-tutorial.ed25519 192.168.1.80
Da beim Generieren des Schlüssels ein Passwort vergeben wurde, wird nun nach diesem gefragt. Achtung; damit ist nicht das Benutzer-Passwort auf dem Server gemeint. Somit ist natürlich nicht so viel gewonnen, denn es wurde so nur das eine Passwort durch ein anderes ersetzt.
Um die Passwortabfrage zu vermeiden, wird eine kleine Datei im Verzeichnis ~/.ssh
mit dem Namen config
und dem folgendem Inhalt erstellt:
Host synology hugo HostName 192.168.1.80 UseKeychain yes AddKeysToAgent yes User leif PreferredAuthentications publickey IdentityFile ~/.ssh/synology-tutorial.ed25519
Mit dieser Konfiguration kann eine SSH-Session auf meiner Synology entweder mit den Befehlen ssh synology
oder ssh hugo
gestartet werden. Beim dem Parameter HostName
habe ich die bei mir festvergebene IP-Adresse angegeben. Die Parameter UseKeychain
und AddKeysToAgent
stellen zusammen mit dem Mac-spezifischen Befehl:
ssh-add --apple-use-keychain ~/.ssh/synology-tutorial.ed25519
sicher, dass die Passphrase nicht mehr eingegeben werden muss, da sie nun sicher in der Schlüsselbundverwaltung gespeichert ist.
Beim Nachvollziehen meiner Anleitung auf einem frisch in einer virtuellen Maschine installierten macOS hatte ich ein Problem mit den Rechten beim Aufruf des obigen Befehls, das bei der ersten Installation auf meinem Mac nicht aufgetreten war:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0644 for '/Users/leif/.ssh/synology-tutorial.ed25519.pub' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored.
Nach etwas Suche im Web fand ich als Problemlösung folgende Rechte-Einstellungen:
chmod 700 ~/.ssh
sowie
chmod 600 ~/.ssh/*
Nun sollte schnell eine Session mit dem Aufruf von
ssh synology
aufgebaut werden, ohne dass ein Passwort abgefragt wird. Somit sind alle Vorbereitungen getroffen, das entsprechende rsync
-Kommando zu erstellen.
Schritt 3: Das rsync-Kommando
Wie ich in der Einleitung schon erwähnt habe, nutze ich an dieser Stelle rsync
um eine einfache Sicherung meines Obsidian Vault zu erstellen. Mit dem folgenden Befehl wird der lokale Ordner 1:1 mit dem Ordner auf der Synology abgeglichen. Dabei werden nur Änderungen übertragen, und Dateien, die im Quellordner gelöscht wurden, werden auch im Zielordner gelöscht. Das hat den Vorteil, gerade wenn man auch über das Netz, Sicherheitskopien machen möchte, nicht immer der ganze Ordner kopiert werden muss.
In meinem Kontext war der Aufruf von rsync
mit einigen Problemen behaftet, da der Befehl etwas zickig im Umgang mit Leerzeichen in einem Pfad ist. Auf der Quellseite reichten Anführungszeichen, während auf der Zielseite zusätzlich zu den doppelten Anführungszeichen auch einfache verlangt wurden, worauf ich erst nach langem Forschen kam, da die Fehlermeldungen in diesem Falle nicht zielführend waren. Das Ergebnis der Bemühungen sieht für mein Beispiel so aus:
rsync -avz --delete --exclude "@eaDir" --filter "P @eaDir/" -e 'ssh' "/Users/leif/Documents/01 ObsidianNotes/" synology:"'/volume1/homes/leif/98 Backup/Obsidian/ObsidianNotes'"
Die Optionen -avz
stehen für „archive”, „verbose” und „compress”, wobei die a
-Option mehrere andere Optionen zusammenfasst, die sicherstellen, dass der gesamte Ordner auch übertragen wird. Die v
-Option schaltet eine erweiterte Protokollierung an. Die z
-Option komprimiert die Daten während der Übertragung, was vielleicht im internen Netz nicht so wichtig ist.
--delete
sorgt dafür, dass Dateien, die im Originalverzeichnis gelöscht wurden, auch auf der Synology gelöscht werden. Daher erstellt dieses Vorgehen kein Backup, sondern nur eine 1:1 Kopie des Vaults. rsync
bietet allerdings auch weitergehende Optionen, wie zum Beispiel --backup
zusammen mit --backup-dir
, die dann eher ein Backup erstellen, auf die ich, wie oben angekündigt, in einem weiteren Artikel eingehe.
--exclude "@eaDir"
und --filter "P @eaDir/"
habe ich eingeführt, da meine Synology alle Dateien indexiert und diese Index-Dateien bei jedem Lauf des Befehls immer wieder gelöscht werden und dann wieder auf der Synology neu erstellt werden. Es gibt scheinbar keine Möglichkeit gibt, einzelne Ordner von der Erstellung eines Indexes der Universal Search auszuschließen, daher habe ich diese Optionen gewählt.
-e 'ssh'
spezifiziert, welches „Remote-Shell-Programm“ für die Übertragung verwendet werden soll. Alternativen wären unter anderem rsh
oder telnet
, die aber nicht so sicher sind wie ssh
.
Als nächstes wird der Quellordner angegeben, wobei ich den gesamten Pfad spezifiziert habe. Da mein Quellordner im Pfad auch Leerzeichen hat, muss der Pfad von Anführungszeichen umschlossen werden:
"/Users/leif/Documents/01 ObsidianNotes/"
Der Zielpfad beginnt mit dem Rechnernamen, wie er in der ssh-config-Datei definiert wurde. Getrennt durch einen Doppelpunkt folgt der Zielordner, der aufgrund von Leerzeichen im Pfad in einfache und doppelte Anführungszeichen eingeschlossen wird:
synology:"'/volume1/homes/leif/98 Backup/Obsidian/ObsidianNotes'"
Der Befehl sollte zunächst im Terminal getestet werden. Falls der Befehl im Terminal fehlerfrei läuft, kann der Kurzbefehl in Angriff genommen werden.
Der Kurzbefehl
Eigentlich dachte ich, dass es einfach genügen würde, die Kommandozeile:
rsync -avz --delete --exclude "@eaDir" --filter "P @eaDir/" -e 'ssh' "/Users/leif/Documents/01 ObsidianNotes/" synology:"'/volume1/homes/leif/98 Backup/Obsidian/ObsidianNotes'"
In einen Kurzbefehl in die Aktion „Shell-Skript ausführen” zu kopieren und dann einfach über die Menüleiste auszuführen.
Das funktioniert auch sehr gut, solange dieser Kurzbefehl mit dem Ausführen-Button im Automator ausgeführt wird. Aber wenn dieser Kurzbefehl über das Menü aufgerufen wird, gibt es eine Fehlermeldung: ‘rsync: opendir „/Users/leif/Documents/01 ObsidianNotes/.” failed: Operation not permitted‘. Da ich das gleiche Problem mit der Ausführung eines Skripts im launchd-Framework hatte, kannte ich schon den Grund und auch die Lösung des Problems. Alle Programme, die einen Festplattenzugriff benötigen, müssen diese Berechtigung in den Systemeinstellungen unter dem Punkt „Datenschutz und Sicherheit” erhalten. Da die Kurzbefehl-Anwendung und das Terminal diese Berechtigung meist schon bei ersten Aufruf vom dem User bekommen haben, läuft das Skript im Terminal und auch als Kurzbefehl, wenn er in der App gestartet wird. Wenn aber der Kurzbefehl über das Menü aufgerufen wird, läuft er nicht mehr innerhalb der App und hat damit nicht die Berechtigung, auf die Festplatte zuzugreifen. Leider ist es auch nicht möglich rsync
die Berechtigung zu geben. Die Lösung, die ich am Ende in dem Beitrag „How to run a LaunchAgent that runs a script…” gefunden habe, besteht darin, eine Programmhülse zu verwenden, in der das Skript ausgeführt wird. MacOS ist mittlerweile sehr restriktiv, was den Festplattenzugriff angeht und erlaubt nur, dass „richtigen” Programmen diese Berechtigung gegeben werden kann. Im Prinzip kann diese Hülle in jeder Programmiersprache programmiert werden, die Programme erstellt. In dem oben genannten Artikel werden für Nicht-Programmierer Automator, der Script Editor oder ein Tool namens Platypus empfohlen.
Ich habe mich für die Automator-App entschieden und dafür das Skript noch um eine Logging-Funktion erweitert, damit man eventuelle Fehler nachvollziehen kann. Als Log-Datei habe ich eine leere Datei unter dem Ordner /tmp
erstellt:
touch /tmp/vault-sicherung.log
Neben der Ausgabe des rsync
-Aufrufs sollte auch noch das Datum und die Uhrzeit in die Log-Datei schreiben geschrieben werde und so sieht das fertige Skript aus:
echo -e "\n\n$(date +"%Y-%m-%d %H:%M:%S")" >> /tmp/vault-sicherung.log rsync -avz --delete --exclude "@eaDir" --filter "P @eaDir/" -e 'ssh' "/Users/leif/Documents/01 ObsidianNotes/" synology:"'/volume1/homes/leif/98 Backup/Obsidian/ObsidianNotes'" >> /tmp/vault-sicherung.log
Mit echo -e "\n\n$(date +"%Y-%m-%d %H:%M:%S")" >> /tmp/vault-sicherung.log
werden zunächst zwei leere Zeilen und dann der Zeitstempel in dem Format 2024-06-04 18:30:44
geschriebenen und danach das Ergebnis der Ausführung des Kommandos. Das >>
steht dabei für das Anhängen des Strings am ende der Log-Datei.
Nachdem nun das Skript fertig ist, wird Automator gestartet und ein neues Dokument erstellt. Dabei ist die Option „Programm” zu wählen.
n dem nun aufgehenden Fenster wird aus der Bibliothek die Aktion “Shell-Skript ausführen” in das Arbeitsablauffenster geschoben und dann das oben erstellte Skript hineinkopiert.
Das Ganze wird nun nochmal getestet, wobei man einen Blick auf die Log-Datei werfen sollte. BTW: Bei jedem Test wird natürlich schon eine Sicherheitskopie auf die Synology geschrieben. Falls also keine Änderungen im Quellordner gemacht wurden, wird auch nichts übertragen. In die Log-Datei wird dann aber trotzdem ein Eintrag gemacht, der etwa so aussieht:
2024-06-04 10:56:07 SERVER ist erreichbar. Starte rsync. building file list ... done sent 86782 bytes received 20 bytes 57868.00 bytes/sec total size is 193118530 speedup is 2224.82
Wenn alles läuft kann das Automator-Programm gespeichert werden. Ich habe es unter dem Namen „SaveVault” im benutzereigenen Programme-Ordner, der bei mir unter ~/Applications (im Finder unter leif -> Programme) zu finden ist.
Dieses Programm reicht bereits aus, um über einen Launcher wie Spotlight, Alfred.app oder Raycast aufgerufen zu werden. Auch könnte das Programm in das Dock gezogen werden und dort ständig im Zugriff sein. Mein Ziel war es jedoch, es mit einem Kurzbefehl in der Menüleiste zu starten. Deshalb muss noch dieser Kurzbefehl erstellt werden. Dazu wird ein neuer Kurzbefehl mit der Aktion „App öffnen” erstellt. Als App wird dann „SaveVault” ausgewählt:
Falls das Programm „SaveVault” nicht zur Auswahl steht, hilft es, das Programm einmal direkt zu starten und die Kurzbefehle-App danach neu zu starten.
Nun wird noch unter den Kurzbefehl-Optionen die Option “In der Menüleiste anzeigen” aktiviert, der Kurzbefehl geschlossen — fertig. Beim ersten Aufruf über die Menüleiste muss folgender Dialog bestätigt werden, womit das Programm „SaveVault” automatisch in die Liste der Programme mit dem Zugriff eingetragen wird:
Nun sollte ein neuer Eintrag in der Log-Datei stehen…
Falls Änderungen in dem Automator-Programm gemacht werden und das dann wieder gestartet wird, erscheint der obige Dialog zur Sicherheit wieder.
Fazit
Nachdem ich nun diesen Kurzbefehl habe, kann ich einfach per Menüeintrag eine Sicherheitskopie von meinem Obsidian Vault machen, wozu vorher einige manuelle Schritte notwendig waren, da Forklift nicht über die Kurzbefehle App gesteuert werden kann.
Meine bisherigen Versuche, ein rsync-Skript zu schreiben, waren bisher durch das Fehlen der richtigen Optionen im Zusammenhang mit der Synology nicht erfolgreich.
Dieses Problem, wenn es nicht nur meine eigene Unfähigkeit war, konnte ich nun lösen.
Meine bisherigen Shortcuts, mit denen ich Daten auf der Festplatte manipuliert hatte, liefen immer im Kontext von Anwendungen, die diese Berechtigung hatten, so dass ich es vorher nie bemerkt hatte. Jetzt habe ich eine Lösung für dieses Problem.
So, soweit dieser erste Teil, der dann vielleicht doch eher eine Fingerübung darstellt, die Ergänzung, wie man ein richtiges Backup eines Ordners erstellt, werde ich in den nächsten Tagen veröffentlichen.
Bis dahin freue ich mich über Korrekturen, Feedback und weitere Ideen in den Kommentaren.
Schreibe einen Kommentar