Wat je nodig hebt
- Een OpenCloud-server die je vanaf de backupmachine kunt bereiken.
- Een aparte gebruiker voor de backup, zodat een gelekt token alleen bij die backups kan.
- Python 3 en git op de machine die je wilt backuppen. Extra pakketten zijn niet nodig.
Stap 1: maak een app-token
OpenCloud accepteert via WebDAV geen gewoon wachtwoord. Log in als de backupgebruiker, maak bij de instellingen een app-token aan en zet het in een bestand dat alleen jij kunt lezen:
mkdir -p ~/.config/backup
chmod 700 ~/.config/backup
nano ~/.config/backup/opencloud.env # OPENCLOUD_URL, OPENCLOUD_USER, OPENCLOUD_TOKEN
chmod 600 ~/.config/backup/opencloud.env
Zet dit bestand nooit in een git-repository.
Stap 2: maak per repository een bundle
Een bundle is één bestand met de volledige geschiedenis. Controleer hem direct na het maken:
git -C ~/mijn-repo bundle create /tmp/backup/mijn-repo.bundle --all
git bundle verify /tmp/backup/mijn-repo.bundle
Let op: een bundle bevat alleen wat gecommit is. Commit dus eerst.
Stap 3: upload met WebDAV
Het WebDAV-adres van een bestand is <server>/remote.php/dav/files/<gebruiker>/<pad>. Een map maak je met MKCOL, een bestand upload je met PUT. In Python, zonder extra pakketten:
import base64, urllib.request
def dav(methode, url, gebruiker, token, data=None):
sleutel = base64.b64encode(f"{gebruiker}:{token}".encode()).decode()
verzoek = urllib.request.Request(url, data=data, method=methode,
headers={"Authorization": f"Basic {sleutel}"})
with urllib.request.urlopen(verzoek, timeout=120) as antwoord:
return antwoord.read()
Een MKCOL op een map die al bestaat geeft een fout terug (405). Vang die af, dan kun je het script veilig opnieuw draaien.
Stap 4: controleer op geheimen
Doorzoek vóór het uploaden elke versie van elk bestand in de geschiedenis op de letterlijke waarden van je tokens en op bekende vormen van sleutels. git rev-list --all --objects geeft alle objecten; met git cat-file -t kies je de blobs en met git cat-file blob lees je de inhoud. Vind je iets, upload dan niets en stuur jezelf een melding. Zo komt een per ongeluk gecommit token nooit in je backup terecht.
Stap 5: test het herstel
Een backup is pas klaar als je hem hebt teruggezet. Haal de bundle op met GET en kloon hem in een tijdelijke map:
git clone -q mijn-repo.bundle /tmp/hersteltest/mijn-repo
git -C /tmp/hersteltest/mijn-repo log -1 --format=%H
Vergelijk die commit met het origineel. Gelijk? Dan werkt je backup.
Stap 6: plan het in
Een systemd-timer met Persistent=true draait een gemiste backup alsnog als de machine weer aan staat:
[Timer]
OnCalendar=*-*-* 23:30:00
Persistent=true
Ruim oude backups op in hetzelfde script, bijvoorbeeld alles ouder dan 30 nachten. Gebruik daarvoor PROPFIND met Depth: 1 om de mappen op te vragen.
