syncova-backup/docs/linux-agent.md
Jerrit Fritzsche 610719c316
Some checks failed
CI / Backend (Go) (push) Failing after 3m7s
CI / Frontend (React/TypeScript) (push) Successful in 37s
CI / Sicherheitsprüfungen (push) Successful in 44s
Syncova Backups V1
Enterprise-Backup-, Recovery-, Verification-, Security- und
Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme.

Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als
vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit
nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem
tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes
geht in keine Bewertung als "gut" ein.

Umfang (Phasen 0-23):

- Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll,
  Katalogaufbau allein aus den Manifesten — ohne Datenbank
- Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz
  Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck
- Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell)
- Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive
- Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit
- Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center,
  Ransomware-Heuristik (meldet, handelt nie)
- Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing
- Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository
- Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64

Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup
Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs.

Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die
systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine
wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md
und docs/release-candidate.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 09:10:54 +02:00

154 lines
6.6 KiB
Markdown

# Linux-Agent (Phase 6)
Phase 6 teilt sich fast alles mit Phase 5 — dieselbe Aufnahme, dieselbe
Lebendmeldung, dieselbe Auftragsübermittlung, dieselbe Engine. Was sie
eigenständig macht, sind die Eigenheiten eines Unix-Dateisystems: Sockets,
benannte Pipes, Gerätedateien, harte Verknüpfungen — und ein Dienstmodell, das
sich einsperren lässt.
## Der Fund: Ein Socket ist kein Fehler
Bis zu dieser Phase galt **jedes** Erfassungsproblem als übergangenes Objekt und
machte den Lauf damit zum Teilfehler. Auch ein Socket.
Auf einem Linux-System ist das ein Dauerzustand: In `/var/run` und `/tmp` liegen
ständig Sockets. Wer `/var` sichert, bekäme bei **jedem** Lauf einen Teilfehler.
Nach einer Woche klickt niemand mehr einen Teilfehler an — und dann fällt auch
der echte nicht mehr auf. Dieselbe Alarmmüdigkeit, gegen die Phase 14 und 16
gebaut sind.
Die Unterscheidung, die jetzt gilt:
| Objekt | Ergebnis | Warum |
| --- | --- | --- |
| Nicht lesbare Datei | **Datenverlust** → Teilfehler | Dort waren Daten, und sie fehlen |
| Gesperrtes Verzeichnis | **Datenverlust** → Teilfehler | Dasselbe |
| Socket | Vermerk, kein Fehler | Endpunkt eines laufenden Prozesses, kein Inhalt |
| Benannte Pipe (FIFO) | Vermerk, kein Fehler | Hat keinen Inhalt zum Sichern |
| Block-/Zeichengerät | Vermerk, kein Fehler | Dasselbe |
**Verschwiegen wird trotzdem nichts.** Die Zusammenfassung nennt sie auch im
Erfolgsfall:
```
Erfolgreich: 4 Dateien, 1 Verzeichnisse gesichert. 2 Objekt(e) ohne sicherbaren
Inhalt (Sockets, Pipes, Gerätedateien) wurden übergangen; das ist kein Fehler.
```
Und die Meldung benennt den Typ in Worten. `prw-r--r--` sagt einem Betreiber
nichts; „benannte Pipe (FIFO)" sagt ihm, dass er nichts zu tun hat.
### Was der Agent mit einer FIFO **nicht** tut
Er liest sie nicht. Das ist der klassische Backup-Bug: Ein Leseversuch auf einer
benannten Pipe ohne Schreiber blockiert **für immer**. Die Erfassung entscheidet
anhand des Dateityps, bevor sie öffnet — ein Test mit Zeitgrenze hält das fest.
## Symbolische Verweise werden erfasst, nicht verfolgt
Ein Verweis kommt als Verweis ins Backup und wird als Verweis zurückgeschrieben.
Verfolgte die Erfassung ihn, geriete sie bei einem Verweis auf ein
übergeordnetes Verzeichnis in eine Schleife — und ein Verweis nach `/` zöge das
ganze System ins Backup.
## Harte Verknüpfungen: der Inhalt kommt zurück, die Verknüpfung nicht
Zwei Namen derselben Datei erscheinen als **zwei Dateien**. Der Inhalt liegt
dank Deduplizierung nur einmal im Repository — der Platzbedarf im Backup ist
also derselbe.
Nach einer Wiederherstellung sind es jedoch **zwei unabhängige Dateien**:
```
Quelle: 2 Verknüpfungen
Ziel: 1 Verknüpfung
```
Das kostet Platz am Ziel und ändert die Bedeutung: Eine Änderung an der einen
wirkt nicht mehr auf die andere. Für die meisten Anwendungsfälle ist das
unerheblich; wer Paketverwaltungen oder Deduplizierungsbäume sichert, sollte es
wissen.
Umsetzbar wäre es — Inode-Nummer erfassen und beim Zurückschreiben `link()`
statt Kopie —, aber es griffe in das Manifestformat ein. Es steht hier als
benannte Grenze, nicht als Versehen.
## Die systemd-Einheit hatte drei Fehler
`deployment/syncova-agent.service` war gut gehärtet und **hätte nicht
funktioniert**:
**`--state /var/lib/syncova-agent`** — das ist ein Verzeichnis. Der Parameter
erwartet eine Datei. Der Agent hätte beim Start gemeldet, er sei bereits
registriert (ein vorhandenes Verzeichnis sieht für ihn wie eine Zustandsdatei
aus), und wäre ohne Token gelaufen.
**Kein `ReadWritePaths` für das Repository.** Bei `ProtectSystem=strict` ist das
gesamte Dateisystem nur lesbar. Der Agent hätte die Quelle vollständig gelesen
und gehasht — und dann keinen einzigen Block ablegen können. Der Fehler wäre
erst am Ende des Laufs aufgetreten.
**`RestrictAddressFamilies` ohne `AF_UNIX`.** Auf Systemen mit
`systemd-resolved` oder `nscd` läuft die Namensauflösung über einen
Unix-Socket. Ohne `AF_UNIX` findet der Agent seinen Server nicht und meldet
einen Netzfehler, während das Netz einwandfrei arbeitet.
Alle drei sind behoben. Der Repositorypfad ist an die eigene Anlage anzupassen —
liegt das Repository auf einer Freigabe, gehört deren Einhängepunkt in
`ReadWritePaths`.
> Die Einheit ist weiterhin **nicht auf einem Linux-System geprüft**.
> `systemd-analyze verify` gibt es auf macOS nicht.
## Was die Härtung leistet
Der Agent liest fremde Daten und spricht mit dem Netz — genau die Art Dienst,
die man einsperrt:
- **`CAP_DAC_READ_SEARCH` statt root.** Er darf fremde Dateien lesen, sonst
nichts. Der Unterschied ist beträchtlich: Lesen ist etwas anderes als
Alleskönnen.
- **`ProtectSystem=strict`, `ProtectHome=read-only`**, Schreibrechte nur auf
Zustand und Repository.
- **`MemoryDenyWriteExecute`, `RestrictSUIDSGID`, `NoNewPrivileges`,
Systemaufruffilter** — die üblichen Riegel gegen Ausnutzung eines Fehlers im
Dienst selbst.
- **`Nice=10`, `IOSchedulingClass=idle`** — ein Backup soll dem laufenden
Betrieb nicht die Maschine wegnehmen.
- **Das Schlüsselmaterial steht in einer Datei, nicht in `Environment=`.** Ein
`Environment=` im Unit-File ist für jeden Benutzer über `systemctl show`
lesbar.
## Nachweis
Auf einem Quellverzeichnis mit gewöhnlichen Dateien, einer harten Verknüpfung,
einem symbolischen Verweis, einer benannten Pipe, einem Unix-Socket und einem
gesperrten Verzeichnis:
```text
Erfassung 4 Dateien, 2 Objekte ohne sicherbaren Inhalt vermerkt
Sicherung Erfolg (Exit 0) — kein Teilfehler wegen Socket und Pipe
Restore 4 Dateien bitgenau, Symlink erhalten, Rechte erhalten
Sonderdateien im Ziel: keine — korrekt
Harte Verknüpfung: Quelle 2, Ziel 1 — dokumentierte Grenze
```
Der gesperrte Ordner erzeugte dabei erwartungsgemäß einen Rechtefehler und damit
einen Teilfehler — bis er freigegeben wurde. Genau diese Unterscheidung ist der
Kern der Phase.
## Was offen bleibt
- **Die systemd-Einheit ist ungeprüft.** Sie ist inhaltlich korrigiert, aber nie
auf einem Linux-System geladen worden.
- **Erweiterte Attribute und ACLs werden nicht gesichert.** POSIX-ACLs,
SELinux-Kontexte und `xattr` gehen verloren. Für eine Wiederherstellung auf
demselben System ist das meist unerheblich, für eine Systemwiederherstellung
nicht.
- **Keine Sicherung offener Dateien mit konsistentem Stand.** Es gibt keinen
Schattenkopie-Mechanismus wie VSS unter Windows; eine Datenbank, die während
der Sicherung schreibt, landet in dem Zustand, in dem sie gerade ist. Für
Datenbanken gehört ein eigener Ablauf davor (Dump oder Snapshot des
Dateisystems).
- **Harte Verknüpfungen werden aufgelöst** (siehe oben).