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>
107 lines
4.0 KiB
Desktop File
107 lines
4.0 KiB
Desktop File
[Unit]
|
|
Description=Syncova Backup Agent
|
|
Documentation=file:///usr/share/doc/syncova/agent.md
|
|
# Ohne Netz ist die Anmeldung am Control Server zwecklos.
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
# --state erwartet eine **Datei**, kein Verzeichnis.
|
|
#
|
|
# Stand hier zuvor ein Verzeichnispfad. Der Agent haette beim Start gemeldet,
|
|
# er sei bereits registriert (ein vorhandenes Verzeichnis sieht fuer ihn wie
|
|
# eine Zustandsdatei aus) und waere ohne Token gelaufen.
|
|
ExecStart=/usr/local/bin/syncova-agent run --state /var/lib/syncova-agent/agent.json
|
|
|
|
# Der Verschlüsselungsschlüssel steht in einer Datei, nicht in Environment=.
|
|
# Ein Environment= im Unit-File wäre für jeden Benutzer über
|
|
# "systemctl show" lesbar (PROMPT.md §141: keine Secrets im Klartext dort, wo
|
|
# sie nicht hingehören). Die Datei gehört root und trägt Modus 0600.
|
|
EnvironmentFile=/etc/syncova/agent.env
|
|
|
|
# Ein abgelehntes Token behebt sich nicht durch Warten: der Agent beendet sich
|
|
# dann mit einem von Null verschiedenen Status. "on-failure" startete ihn in
|
|
# einer Endlosschleife neu und füllte nur das Journal. Deshalb wird ausdrücklich
|
|
# ein Startversuchslimit gesetzt.
|
|
Restart=on-failure
|
|
RestartSec=15s
|
|
StartLimitBurst=5
|
|
StartLimitIntervalSec=300
|
|
|
|
# --- Härtung -------------------------------------------------------------
|
|
# Der Agent liest fremde Daten und spricht mit dem Netz. Er ist damit genau die
|
|
# Art Dienst, die man einsperrt.
|
|
|
|
# Ein eigenes Systemkonto; angelegt mit:
|
|
# useradd --system --home /var/lib/syncova-agent --shell /usr/sbin/nologin syncova-agent
|
|
#
|
|
# Das Konto braucht Leserechte auf alles, was gesichert werden soll, und
|
|
# Schreibrechte auf das Repository. Fehlt eines davon, meldet der Agent das als
|
|
# uebergangenes Objekt — der Lauf wird zum Teilfehler, nicht zum stillen Erfolg.
|
|
User=syncova-agent
|
|
Group=syncova-agent
|
|
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
PrivateDevices=true
|
|
ProtectSystem=strict
|
|
ProtectHome=read-only
|
|
ProtectKernelTunables=true
|
|
ProtectKernelModules=true
|
|
ProtectKernelLogs=true
|
|
ProtectControlGroups=true
|
|
ProtectClock=true
|
|
ProtectHostname=true
|
|
ProtectProc=invisible
|
|
RestrictSUIDSGID=true
|
|
RestrictRealtime=true
|
|
RestrictNamespaces=true
|
|
LockPersonality=true
|
|
MemoryDenyWriteExecute=true
|
|
RemoveIPC=true
|
|
|
|
# Der Agent schreibt an genau zwei Stellen: seinen Zustand und das Repository.
|
|
#
|
|
# **Der Repositorypfad ist Pflicht.** Bei ProtectSystem=strict ist das gesamte
|
|
# Dateisystem nur lesbar; ohne diesen Eintrag koennte der Agent zwar lesen und
|
|
# hashen, aber keinen einzigen Block ablegen — die Sicherung schluege mit einem
|
|
# Schreibfehler fehl, und zwar erst nach dem Lesen der ganzen Quelle.
|
|
#
|
|
# Der Pfad ist an die eigene Anlage anzupassen. Liegt das Repository auf einer
|
|
# Freigabe, gehoert deren Einhaengepunkt hierher.
|
|
ReadWritePaths=/var/lib/syncova-agent
|
|
ReadWritePaths=/srv/syncova-repository
|
|
|
|
# IP-Sockets fuer den Control Server — und AF_UNIX fuer die Namensaufloesung.
|
|
#
|
|
# AF_UNIX stand hier zuvor nicht. Auf Systemen mit systemd-resolved oder nscd
|
|
# laeuft die Namensaufloesung ueber einen Unix-Socket: Ohne AF_UNIX findet der
|
|
# Agent seinen Server nicht und meldet einen Netzfehler, waehrend das Netz
|
|
# einwandfrei arbeitet.
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
|
|
# DAC_READ_SEARCH erlaubt das Lesen fremder Dateien, ohne dem Agent root zu
|
|
# geben. Ohne diese Fähigkeit müsste er als root laufen — der Unterschied ist
|
|
# beträchtlich: Lesen ist etwas anderes als Alleskönnen.
|
|
AmbientCapabilities=CAP_DAC_READ_SEARCH
|
|
CapabilityBoundingSet=CAP_DAC_READ_SEARCH
|
|
|
|
# Systemaufrufe auf das Nötige beschränken.
|
|
SystemCallFilter=@system-service
|
|
SystemCallFilter=~@privileged @resources @obsolete @mount @swap @reboot
|
|
SystemCallArchitectures=native
|
|
|
|
# Ein Backup soll dem laufenden Betrieb nicht die Maschine wegnehmen.
|
|
Nice=10
|
|
IOSchedulingClass=idle
|
|
IOSchedulingPriority=7
|
|
|
|
# Das Journal ist die Protokollsenke; der Agent schreibt strukturiert nach stderr.
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=syncova-agent
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|