Changes between Initial Version and Version 1 of BackupSystemWww


Ignore:
Timestamp:
Oct 24, 2026, 4:11:39 PM (12 days ago)
Author:
Johannes Lode
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • BackupSystemWww

    v1 v1  
     1= Backups der Web-Dienste =
     2
     3[[PageOutline(2-3)]]
     4
     5Diese Seite beschreibt, '''was''' bei den Web-Diensten gesichert wird, '''wo die Grenzen''' der LV-weisen Sicherung liegen und '''wie eine Ad-hoc-Sicherung von Hand''' läuft, bevor an einem Dienst geschraubt wird.
     6
     7Die Mechanik von Dirvish selbst — Bank, Vaults, Branches, Expire, Recovery — steht in [wiki:BackupSystem]. Hier steht nur, was dienstspezifisch ist. Siehe auch [wiki:WebDienste].
     8
     9== Hosts ==
     10
     11||= Host =||= Rolle =||
     12|| `backer` || Dirvish-Server. Alle `dirvish`-Aufrufe werden hier abgesetzt, als root. ||
     13|| `laubfrosch` || Web-Host. NGINX, Docker-Container der Web-Dienste, Webroots unter `/var/www/`. ||
     14|| `janus` || Datenbank-Server. MariaDB nativ, nicht im Container. ||
     15
     16== Vaults und ihre Grenzen ==
     17
     18Die Web-Dienste sind so aufgebaut, dass App-Code und Datenmasse in getrennten LVs liegen. Der Rsync bleibt mit `xdev` innerhalb eines Dateisystems; damit ist der Umfang eines Vaults durch die LV-Grenze definiert und nicht durch eine Exclude-Liste, die mit jedem Update erodiert.
     19
     20||= Vault =||= Dienst =||= Zustand außerhalb des LV =||
     21|| `www-cloudservice` || Nextcloud (inkl. Passman) || Datenbank `cloudservice` auf `janus` ||
     22|| `www-usvn` || USVN / Subversion || ||
     23|| `www-trac` || Trac || ||
     24|| `www-octoprint` || !OctoPrint || ||
     25|| `www-iobroker` || ioBroker || ||
     26|| `janus-local` || lokale Daten auf `janus`, u.a. die SQL-Dumps || ||
     27
     28'''Die rechte Spalte ist die eigentliche Fallgrube.''' Ein Vault ist genau so viel wert, wie die Antwort auf die Frage „welcher Zustand dieses Dienstes liegt ''nicht'' in diesem LV?" vollständig ist. Das betrifft Datenbanken auf anderen Hosts, Redis- oder !SQLite-Stände, und — weil `xdev` ja gerade nicht über Dateisystemgrenzen geht — jeden weiteren Mount ''innerhalb'' des Baums, etwa ein Docker-Volume unterhalb des Webroots.
     29
     30Prüfung pro Dienst, einmalig und nach jedem Umbau:
     31
     32{{{#!sh
     33# auf laubfrosch: hängt innerhalb des Webroots noch etwas eigenes?
     34findmnt -R /var/www/<dienst>
     35}}}
     36
     37Taucht dort ein Mount auf, der in keinem Vault steht, ist er unsichtbar für das Backup.
     38
     39== Nextcloud und Passman im Detail ==
     40
     41=== Warum Dump und config.php nur als Paar taugen ===
     42
     43Passman verschlüsselt die ohnehin schon clientseitig verschlüsselten Credentials auf dem Server ein zweites Mal. Der dafür verwendete Schlüssel wird aus `passwordsalt` und `secret` aus der `config.php` abgeleitet. Daraus folgt:
     44
     45 * Ein Datenbank-Dump ohne die zugehörige `config.php` ist für die Passman-Daten '''wertlos''' — auch dann, wenn alle Benutzer ihr Vault-Passwort noch wissen.
     46 * `passwordsalt`, `secret` und `instanceid` sind aus keinem Backup rekonstruierbar. Gehen sie verloren, sind sie weg.
     47 * Beim Rollback eines fehlgeschlagenen Versionsupgrades müssen Dump und `config.php` '''vom selben Zeitpunkt''' stammen. In der `config.php` steht die `version`, die zum Schemastand der Datenbank passen muss; eine neue `config.php` auf einer alten Datenbank führt beim Start direkt in den Upgrade- oder Fehlerzustand.
     48
     49Die `config.php` liegt auf `laubfrosch` unter:
     50
     51{{{
     52/var/www/cloudservice.vpn21.net/htdocs/virgin/config/config.php
     53}}}
     54
     55Sie liegt damit innerhalb des Webroots und wird vom Vault `www-cloudservice` erfasst — ''sofern'' `config/` nicht als eigenes Docker-Volume gemountet ist. Das ist mit dem `findmnt` oben zu verifizieren und ist der wichtigste Einzelpunkt dieser Seite.
     56
     57=== Was aus dem Backup grundsätzlich nicht wiederkommt ===
     58
     59Der Vault-Key eines Passman-Vaults verlässt den Client nie. Es gibt keine Admin-Funktion, fremde Vaults zu sichern oder zu exportieren; die aktuelle Passman-Version registriert genau ein `occ`-Kommando, und das ist ein Wartungs-Check für Sharing-ACLs. Die Sicherung erfasst also die Daten aller Benutzer, aber lesbar macht sie nur der jeweilige Benutzer mit seinem Vault-Passwort.
     60
     61Konsequenz für den Betrieb: Jeder Benutzer muss sein Vault-Passwort außerhalb von Nextcloud hinterlegt haben. Wer eine Nextcloud-unabhängig lesbare Kopie will, muss sie selbst ziehen — im Vault unter den Einstellungen als JSON-Export (vollständiger als CSV, da Custom Fields erhalten bleiben) und anschließend verschlüsselt ablegen. Zentral anstoßen lässt sich das nicht.
     62
     63=== Sicherheitliche Kehrseite ===
     64
     65Sobald SQL-Dump und `passwordsalt`/`secret` beide unverschlüsselt im Dirvish-Baum liegen, ist dieses Dateisystem der direkte Weg zur serverseitigen Entschlüsselungsschicht aller Passman-Daten. Dirvish verschlüsselt nichts, und die Hardlink-Historie bedeutet, dass das für alle Images gilt. Das ist eine bewusste Entscheidung wert, keine Nebenwirkung.
     66
     67== Ad-hoc-Sicherung vor einem Eingriff ==
     68
     69Anzuwenden vor jedem Versionsupgrade und vor jedem Eingriff an einem Dienst. Die Images laufen in der normalen Rotation des Vaults mit; wer einen Pre-Upgrade-Stand länger halten will, muss ihn vor dem Verfallen auslagern.
     70
     71=== Nextcloud (`www-cloudservice`) ===
     72
     73Drei Hosts, der Reihe nach. Die Reihenfolge ist nicht beliebig: Erst stillstellen, dann dumpen, dann einsammeln.
     74
     75 1. '''Auf `laubfrosch`''' — Instanz stillstellen, damit Dump und Dateistand zueinander passen. Der `trap` sorgt dafür, dass ein Abbruch die Cloud nicht im Wartungsmodus stehen lässt:
     76{{{#!sh
     77cd /var/www/cloudservice.vpn21.net
     78./enter-nextcloud-fpm-docker-container.sh
     79./occ maintenance:mode --on
     80}}}
     81 1. '''Auf `janus`''' — Dump ziehen, in dasselbe Verzeichnis, das der `pre-client` des Vaults `janus-local` benutzt:
     82{{{#!sh
     83# als root, sonst keine Schreibrechte in /var/lib
     84mysqldump --single-transaction --quick --default-character-set=utf8mb4 \
     85  -u root -p cloudservice | gzip > /var/lib/cloudservice-$(date +%F-%H%M).sql.gz
     86}}}
     87  `--single-transaction` liefert bei reinem InnoDB einen konsistenten Snapshot ohne Sperren. `--default-character-set=utf8mb4` ist zwingend, sonst schreddert der Dump die 4-Byte-Zeichen — die Instanz läuft mit `utf8mb4` / `utf8mb4_bin`.
     88 1. '''Auf `laubfrosch`''' — Wartungsmodus wieder aus:
     89{{{#!sh
     90cd /var/www/cloudservice.vpn21.net
     91./enter-nextcloud-fpm-docker-container.sh
     92./occ maintenance:mode --off
     93}}}
     94 1. '''Auf `backer`''' — beide Hälften einsammeln, als root. Der Code-/Config-Stand und der Dump liegen in verschiedenen Vaults und müssen deshalb beide gezogen werden:
     95{{{#!sh
     96dirvish --vault www-cloudservice
     97dirvish --vault janus-local
     98}}}
     99 1. '''Gegenprobe''' auf `backer`, bevor der Eingriff beginnt:
     100{{{#!sh
     101dirvish-locate www-cloudservice config/config.php | tail
     102}}}
     103  Zu sehen sein muss das soeben erzeugte Image. Erst dann ist der Rollback-Stand vollständig: Dump, `config.php` und App-Code vom selben Zeitpunkt.
     104
     105=== Übrige Dienste ===
     106
     107Gleiches Muster, verkürzt. Für Dienste ohne Zustand außerhalb des LV bleibt nur der letzte Schritt:
     108
     109{{{#!sh
     110# auf backer, als root
     111dirvish --vault www-usvn        # bzw. www-trac, www-octoprint, www-iobroker
     112}}}
     113
     114Hat der Dienst Zustand außerhalb seines LV (Spalte in der Vault-Tabelle oben), gehören davor dieselben Schritte wie bei Nextcloud: Dienst stillstellen oder in einen konsistenten Zustand bringen, Zustand in eine Datei schreiben, die in einem Vault liegt, dann erst `dirvish`. Beim Ausfüllen der Tabelle ist je Dienst zu klären:
     115
     116 * Läuft eine Datenbank außerhalb des LV, und wohin wird sie gedumpt?
     117 * Hält der Dienst Zustand im RAM, der beim harten Stop verloren geht (ioBroker, !OctoPrint)?
     118 * Liegt eine SQLite-Datei im LV, die während des Rsync beschrieben werden kann?
     119
     120== Safe-Auszug der unersetzlichen Schlüssel ==
     121
     122Weil `passwordsalt`, `secret` und `instanceid` unersetzlich sind, existieren sie zusätzlich auf Papier. Das Script `[attachment:nc-secrets-sheet.sh]` erzeugt den Auszug als Klartext-Blatt und als QR-Code.
     123
     124Ablage des Scripts: als Anhang an dieser Seite sowie auf `laubfrosch` unter `/var/www/cloudservice.vpn21.net`.
     125
     126Aufruf auf `laubfrosch`:
     127
     128{{{#!sh
     129cd /var/www/cloudservice.vpn21.net
     130./nc-secrets-sheet.sh htdocs/virgin/config/config.php cloudservice.vpn21.net
     131}}}
     132
     133Erzeugt werden `nc-secrets-<datum>.txt` und `nc-secrets-<datum>.png`. Der QR-Code enthält exakt dieselben `key=value`-Zeilen wie das Blatt, nicht die Prosa drumherum, mit Fehlerkorrektur auf Stufe `H`.
     134
     135Eigenschaften, auf die beim Umgang zu achten ist:
     136
     137 * Fehlt einer der drei Einträge in der `config.php` oder ändert sich deren Schreibweise, bricht das Script ab, statt ein unvollständiges Blatt zu erzeugen.
     138 * `umask 077` steht im Script, die Dateien entstehen also nicht kurzzeitig mit offenen Rechten. Trotzdem gehören sie '''nicht''' in das Dirvish-Revier und sind nach dem Druck zu löschen — der vorgesehene Weg ist Papier und Safe.
     139 * Das Blatt gehört '''nicht''' ins Passman-Vault und nicht ins Wiki: Ohne diese Werte lässt sich das Vault nicht öffnen, in dem sie dann lägen. Ins Wiki gehört das Script, nicht seine Ausgabe.
     140 * Die Werte ändern sich im Normalbetrieb nicht, auch nicht über Versionsupgrades hinweg. Der Ausdruck altert also nicht und muss nur bei einem Neuaufsetzen der Instanz erneuert werden. Datum und Instanzname stehen auf dem Blatt, damit er in Jahren noch zuzuordnen ist.