Dokumentation und Aenderungsliste fuer rc8
Der Abschnitt "Wohin darf zurueckgeschrieben werden?" im Runbook ist der wichtigste Zusatz: Dass ein Ziel an ProtectSystem=strict scheitert und nicht an den Rechten des Verzeichnisses, sieht man dem Fehler nicht an. Die Tabelle nennt die vier Faelle samt Grund. Die Beispiel-Einheit in der Installationsanleitung fuehrte in denselben Fehler — sie nannte nur das Repository in ReadWritePaths. Eine Anleitung, deren Ergebnis keine Wiederherstellung zulaesst, ist schlimmer als keine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
20b0919676
commit
b78a6fb51c
54
CHANGELOG.md
54
CHANGELOG.md
@ -1,5 +1,59 @@
|
||||
# Änderungen
|
||||
|
||||
## V1 — Release Candidate 8, 18. August 2026
|
||||
|
||||
Wiederherstellung von Dateien und Ordnern mit Auswahl statt Textfeld — und die
|
||||
Erklärung, warum vorher gar keine Wiederherstellung funktionierte.
|
||||
|
||||
### Warum keine Wiederherstellung ging
|
||||
|
||||
Nicht die Rechte des Zielverzeichnisses, sondern die Härtung des Dienstes: Er
|
||||
läuft mit `ProtectSystem=strict` und `ReadWritePaths` nur auf Repository und
|
||||
Sicherungsordner. Jedes Ziel außerhalb endete mit `mkdir: permission denied` —
|
||||
und zwar **nach** der Vorabprüfung, an der unangenehmsten Stelle. `/tmp`
|
||||
scheiterte anders: Mit `PrivateTmp=yes` hat der Dienst ein eigenes `/tmp`, und
|
||||
was dort landet, ist von außen unsichtbar.
|
||||
|
||||
`setup.sh` legt jetzt `/srv/syncova-restore` an und trägt es ein;
|
||||
`--wiederherstellungsziel` ergänzt weitere. Der Ort liegt unter `/srv`, weil
|
||||
`/var/lib` auf der Sperrliste des Zielschutzes steht — beide Regeln zugleich zu
|
||||
erfüllen lässt genau `/srv` übrig.
|
||||
|
||||
### Auswahl statt Textfeld
|
||||
|
||||
- **Ordnerbaum für das Ziel.** Er meldet je Verzeichnis, ob der Dienst dort
|
||||
schreiben darf — **gemessen** durch eine Probedatei, nicht aus den Rechtebits
|
||||
abgeleitet. Gesperrte Orte werden gezeigt, nicht versteckt: Sonst bliebe
|
||||
offen, warum ein Pfad fehlt.
|
||||
- **Browser für den Backup-Inhalt.** Ordner **und** einzelne Dateien lassen
|
||||
sich zurückholen. Der Baum entsteht aus den Pfaden, nicht aus
|
||||
Verzeichniseinträgen — ein Manifest kann eine Datei enthalten, deren
|
||||
Elternordner nicht als eigener Eintrag vorliegt.
|
||||
|
||||
Zwei neue Endpunkte, der eingefrorene Vertrag ist entsprechend erweitert:
|
||||
`GET /filesystem/browse` und `GET /backups/{id}/contents`.
|
||||
|
||||
### Behoben
|
||||
|
||||
- **„can't access property toLocaleString, chunks_checked is undefined"** beim
|
||||
Integritätslauf. Die Ergebnisse liegen unter `details`, und die Felder heißen
|
||||
`missing_chunks`/`corrupted_chunks`. Betrifft alle vier Prüfendpunkte — sie
|
||||
tragen dieselbe Hülle. Derselbe Fehler wie zuvor bei `/retention-policies`:
|
||||
die Antwortform angenommen statt geprüft. Alle konsumierten Endpunkte sind
|
||||
jetzt gegen den laufenden Dienst abgeglichen.
|
||||
|
||||
### Geist Mono liegt im Paket
|
||||
|
||||
Drei Schnitte, 128 KB, OFL-Lizenz dabei. Ausgeliefert vom eigenen Ursprung —
|
||||
das verlangt die CSP, und ein Backup-Server, dessen Oberfläche von der
|
||||
Erreichbarkeit eines CDN abhängt, wäre auch ohne CSP falsch.
|
||||
|
||||
### Bekannte Grenze
|
||||
|
||||
**Eine Auswahl je Lauf**, kein Mehrfachhaken. Eine Liste ausgewählter Pfade
|
||||
kennt die API nicht; mehrere Läufe hintereinander ergäben mehrere Ausgänge, und
|
||||
ein „teilweise fehlgeschlagen" ließe sich dann nicht mehr erklären.
|
||||
|
||||
## V1 — Release Candidate 7, 18. August 2026
|
||||
|
||||
Behebt einen Absturz, macht die Sitzung brauchbar und stellt das Aussehen um.
|
||||
|
||||
@ -187,12 +187,17 @@ ExecStart=/opt/syncova/bin/syncova-api
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# Härtung: Der Dienst braucht Netz und sein Repository, sonst nichts.
|
||||
# Härtung: Der Dienst braucht Netz, sein Repository und eine Fläche für
|
||||
# Wiederherstellungen — sonst nichts.
|
||||
#
|
||||
# ReadWritePaths ist die Stelle, an der eine Wiederherstellung scheitert, wenn
|
||||
# man sie vergisst: Mit ProtectSystem=strict ist alles andere für den Dienst
|
||||
# schreibgeschützt, und die Rechte des Zielverzeichnisses helfen dann nicht.
|
||||
NoNewPrivileges=yes
|
||||
PrivateTmp=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ReadWritePaths=/srv/syncova-repository
|
||||
ReadWritePaths=/srv/syncova-repository /srv/syncova-restore
|
||||
ProtectKernelTunables=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectControlGroups=yes
|
||||
@ -285,6 +290,25 @@ sudo firewall-cmd --permanent --add-service=https # firewalld
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
## 8b. Wohin Wiederherstellungen schreiben dürfen
|
||||
|
||||
`setup.sh` legt `/srv/syncova-restore` an und trägt es in `ReadWritePaths` der
|
||||
systemd-Einheit ein. Ohne diesen Eintrag scheitert **jede** Wiederherstellung:
|
||||
Der Dienst läuft mit `ProtectSystem=strict`, und die Rechte des
|
||||
Zielverzeichnisses helfen dann nicht.
|
||||
|
||||
Weitere Ziele beim Einrichten nennen:
|
||||
|
||||
```bash
|
||||
sudo ./setup.sh --wiederherstellungsziel /srv/wiederherstellung \
|
||||
--wiederherstellungsziel /mnt/nas/restore
|
||||
```
|
||||
|
||||
Nicht möglich sind `/tmp` (privater Namensraum des Dienstes) und die
|
||||
Systemverzeichnisse `/etc`, `/usr`, `/var/lib`, `/root` — Letztere sperrt der
|
||||
Zielschutz, weil eine Wiederherstellung dorthin das System überschriebe, auf dem
|
||||
die Anlage läuft.
|
||||
|
||||
## 9. Erstes Repository
|
||||
|
||||
Ein Repository entsteht **auf einem Datenträger**, nicht in einer
|
||||
|
||||
@ -51,9 +51,44 @@ Original nicht mehr.
|
||||
|
||||
## 1. Dateien und Ordner
|
||||
|
||||
### Wohin darf zurückgeschrieben werden?
|
||||
|
||||
**Die wichtigste Frage, und sie ist nicht offensichtlich.** Der Dienst läuft mit
|
||||
`ProtectSystem=strict`: Außerhalb weniger Pfade ist das Dateisystem für ihn
|
||||
schreibgeschützt, unabhängig von den Rechten des Verzeichnisses. Ein Ziel
|
||||
außerhalb endet mit `mkdir: permission denied` — und zwar erst **nach** der
|
||||
Vorabprüfung.
|
||||
|
||||
| Ort | Ergebnis |
|
||||
| --- | --- |
|
||||
| `/srv/syncova-restore` | ✓ von `setup.sh` angelegt und eingetragen |
|
||||
| weitere aus `--wiederherstellungsziel` | ✓ |
|
||||
| `/tmp/…` | ✗ landet im privaten `/tmp` des Dienstes und ist von außen unsichtbar |
|
||||
| `/etc`, `/usr`, `/var/lib`, `/root` … | ✗ vom Zielschutz gesperrt |
|
||||
| alles andere | ✗ schreibgeschützt durch `ProtectSystem=strict` |
|
||||
|
||||
Der Ordnerbaum in der Oberfläche beantwortet das direkt: Er meldet je
|
||||
Verzeichnis, ob der Dienst dort schreiben darf — **gemessen** durch eine
|
||||
Probedatei, nicht aus den Rechtebits abgeleitet.
|
||||
|
||||
Ein weiteres Ziel nachträglich freigeben:
|
||||
|
||||
```bash
|
||||
sudo systemctl edit syncova-api # ReadWritePaths= ergänzen
|
||||
sudo systemctl restart syncova-api
|
||||
```
|
||||
|
||||
### Über die Oberfläche
|
||||
|
||||
Wiederherstellungspunkte → Punkt wählen → *Wiederherstellen* → Zielpfad angeben.
|
||||
Wiederherstellungspunkte → Punkt wählen → *Wiederherstellen*.
|
||||
|
||||
1. **Ziel** über den Ordnerbaum wählen. Beschreibbare Orte stehen oben als
|
||||
Vorschlag; ein Unterverzeichnis lässt sich anlegen.
|
||||
2. **Umfang** über den Backup-Browser wählen — das gesamte Backup, ein Ordner
|
||||
oder eine einzelne Datei.
|
||||
3. **Vorabprüfung** — sie schreibt nichts und stellt fest, ob jeder benötigte
|
||||
Block noch da ist.
|
||||
4. **Ausführen.**
|
||||
|
||||
### Über die API
|
||||
|
||||
@ -68,7 +103,16 @@ curl -X POST https://<server>/api/v1/restores \
|
||||
}'
|
||||
```
|
||||
|
||||
`path_prefix` beschränkt auf einen Teilbaum. Ohne ihn kommt alles zurück.
|
||||
`path_prefix` trifft **einen Ordner oder eine einzelne Datei**: Der Server
|
||||
vergleicht auf Gleichheit oder Präfix mit Verzeichnisgrenze — `dokumente`
|
||||
trifft dabei nicht `dokumentation`. Ohne ihn kommt alles zurück.
|
||||
|
||||
Den Inhalt eines Backups durchsehen, ohne etwas zurückzuschreiben:
|
||||
|
||||
```bash
|
||||
curl -s -H "Authorization: Bearer <token>" \
|
||||
"https://<server>/api/v1/backups/<id>/contents?path=berichte" | jq '.data.entries'
|
||||
```
|
||||
|
||||
Fortschritt:
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user