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>
15 KiB
Installation
Diese Anleitung führt von einem leeren Server zu einer Anlage, die sichert und wiederherstellt. Sie beschreibt den Serverteil; die Agenten stehen in agent-installation.md.
Voraussetzungen
| Betriebssystem | Linux (amd64 oder arm64). Der Server wird für Windows nicht ausgeliefert |
| PostgreSQL | 15 oder neuer, erreichbar vom Server. Geprüft gegen 17 (Entwicklung und CI) und 15 (Debian 12) |
| Speicher für das Repository | eigener Datenträger oder eigene Freigabe — nicht dasselbe Gerät wie die zu sichernden Daten |
| Reverse Proxy | optional, aber empfohlen, sofern der Dienst nicht selbst TLS bedient |
Das Repository gehört nicht auf denselben Datenträger wie die Quelle. Ein Datenträgerausfall nähme sonst Original und Sicherung gemeinsam mit. Das ist keine Feinheit der Einrichtung, sondern der Zweck der Übung.
Und nicht nach /tmp, /var/tmp, /run oder auf ein tmpfs.
systemd-tmpfiles räumt die ersten beiden regelmäßig auf, ein tmpfs liegt im
Arbeitsspeicher. Die Sicherungen verschwänden dort von selbst — ohne Meldung,
bis jemand sie braucht. setup.sh lehnt solche Orte ab; die Diensteinheit
könnte mit PrivateTmp=yes ohnehin nicht starten.
Der kurze Weg: setup.sh
Das Paket bringt ein Einrichtungsskript mit. Es geht genau die Schritte dieser Anleitung, und was es angelegt hat, baut es bei einem Abbruch wieder zurück.
tar -xzf syncova-<version>-linux-amd64.tar.gz
cd syncova-<version>-linux-amd64
sudo ./setup.sh
Es fragt nach Datenbank, Repository und dem ersten Administrator, installiert
PostgreSQL auf Wunsch mit, erzeugt den Verschlüsselungsschlüssel und richtet den
Dienst ein. Für einen unbeaufsichtigten Lauf: sudo ./setup.sh --unbeaufsichtigt
mit den Werten aus der Umgebung (./setup.sh --hilfe zeigt sie).
Später aktualisieren: sudo ./update.sh — es sichert vorher Datenbank und
Konfiguration und nimmt sich selbst zurück, wenn der Dienst danach nicht
hochkommt. Entfernen: sudo ./uninstall.sh — es lässt Datenbank, Repository
und Konfiguration liegen, sofern man nicht ausdrücklich etwas anderes verlangt.
Eine bestehende Installation überschreibt setup.sh nicht. Es bricht ab und
verweist auf update.sh; der Unterschied ist, dass ein Update vorher sichert.
Der Rest dieses Dokuments beschreibt dieselben Schritte von Hand — für alle, die wissen wollen, was das Skript tut, oder die davon abweichen müssen.
1. Paket auspacken
tar -xzf syncova-<version>-linux-amd64.tar.gz
cd syncova-<version>-linux-amd64
# Prüfsummen des Inhalts kontrollieren
shasum -a 256 -c SHA256SUMS
./bin/syncova-api --version
Die Versionsabfrage braucht keine Konfiguration. Sie ist der schnellste Weg festzustellen, welche Fassung auf einem Server liegt.
Der Paketinhalt:
bin/ Programme
web/ Weboberfläche (statische Dateien)
migrations/ SQL-Migrationen zum Nachlesen (sie stecken zusätzlich in den Programmen)
docs/ diese Dokumentation
deployment/ Beispiel für die Entwicklungsumgebung und die systemd-Einheit des Agenten
2. Datenbank anlegen
CREATE USER syncova WITH PASSWORD '<starkes-passwort>';
CREATE DATABASE syncova OWNER syncova;
Syncova legt das Schema nicht beim Start an. Das ist Absicht: Ein Dienst, der beim Hochfahren stillschweigend das Schema ändert, macht aus einem versehentlichen Neustart eine Migration.
3. Verschlüsselungsschlüssel erzeugen
./bin/syncova-admin generate-key
Ausgegeben wird ein Wert der Form v1:<base64>.
Ohne diesen Schlüssel sind die abgelegten Geheimnisse verloren — MFA-Geheimnisse, Zugangsdaten der Virtualisierungsverbünde und die Datenschlüssel der Repositories. Er gehört an einen Ort außerhalb dieser Anlage: in einen Passwortspeicher oder einen Tresor. In ein Backup, das Syncova selbst erzeugt, gehört er ausdrücklich nicht — dann bräuchte man ihn, um an ihn heranzukommen.
4. Konfiguration
Syncova liest ausschließlich Umgebungsvariablen; eine Konfigurationsdatei gibt
es nicht. Alle tragen das Präfix SYNCOVA_.
# /etc/syncova/syncova.env — nur für root lesbar (chmod 0600)
SYNCOVA_ENV=production
SYNCOVA_DB_HOST=127.0.0.1
SYNCOVA_DB_PORT=5432
SYNCOVA_DB_NAME=syncova
SYNCOVA_DB_USER=syncova
SYNCOVA_DB_PASSWORD=<passwort>
SYNCOVA_DB_SSLMODE=require
SYNCOVA_ENCRYPTION_KEYS=v1:<base64-schluessel>
SYNCOVA_ENCRYPTION_CURRENT_KEY=v1
SYNCOVA_HTTP_LISTEN_ADDRESS=127.0.0.1:8080
SYNCOVA_LOG_LEVEL=info
SYNCOVA_LOG_FORMAT=json
Die wichtigsten weiteren Werte:
| Variable | Vorgabe | Wozu |
|---|---|---|
SYNCOVA_HTTP_TLS_CERT_FILE / _KEY_FILE |
leer | TLS im Dienst selbst. Nur eines von beiden zu setzen verweigert den Start — sonst liefe der Dienst im Klartext, obwohl der Betreiber Verschlüsselung eingerichtet zu haben glaubt |
SYNCOVA_HTTP_REQUESTS_PER_MINUTE |
600 | allgemeine Ratenbegrenzung |
SYNCOVA_AUTH_REQUIRE_MFA_FOR_PRIVILEGED_USERS |
false | zweiter Faktor für Konten mit Benutzer-, Rollen- oder Sicherheitsrechten |
SYNCOVA_RESTORE_ALLOWED_ROOTS |
leer | begrenzt Wiederherstellungsziele auf bestimmte Verzeichnisbäume |
Lauscht der Dienst ohne TLS auf allen Schnittstellen, warnt er beim Start in Großbuchstaben. Der Betrieb hinter einem Reverse Proxy ist der Normalfall und völlig in Ordnung — solange der Dienst dann nur lokal erreichbar ist.
5. Schema anlegen
set -a; . /etc/syncova/syncova.env; set +a
./bin/syncova-migrate up
./bin/syncova-migrate status
Passt das Schema später nicht zur Programmversion, verweigert syncova-api den
Start mit einer erklärenden Meldung. Das ist kein Schikane, sondern der Schutz
davor, dass eine neue Fassung auf ein altes Schema schreibt.
6. Ersten Administrator anlegen
./bin/syncova-admin create-admin --username admin
Das Passwort wird abgefragt und wiederholt — es steht nicht in einer Umgebungsvariablen und nicht in den Aufrufparametern. Beides landete sonst in der Prozessliste und in der Shell-Historie.
In einem Skript geht es über die Standardeingabe:
printf '%s\n%s\n' "$PASSWORD" "$PASSWORD" | ./bin/syncova-admin create-admin --username admin
Es gibt kein Standardkonto im Programm. Ein ausgeliefertes Kennwort wäre bekannt, sobald es einmal jemand nachschlägt.
Das Kommando legt nur den ersten Administrator an; danach entstehen weitere Konten über die Oberfläche oder die API.
7. Dienst einrichten
# /etc/systemd/system/syncova-api.service
[Unit]
Description=Syncova Control Plane
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
User=syncova
Group=syncova
EnvironmentFile=/etc/syncova/syncova.env
ExecStart=/opt/syncova/bin/syncova-api
Restart=on-failure
RestartSec=5
# 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 /srv/syncova-restore
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
MemoryDenyWriteExecute=yes
[Install]
WantedBy=multi-user.target
AF_UNIX gehört in die Liste: Mit systemd-resolved läuft die Namensauflösung
über einen Unix-Socket. Ohne diesen Eintrag findet der Dienst seine Datenbank
nicht und meldet einen Netzfehler, während das Netz einwandfrei arbeitet.
sudo systemctl daemon-reload
sudo systemctl enable --now syncova-api
curl -s http://127.0.0.1:8080/health/ready
8. Oberfläche ausliefern
setup.sh erledigt diesen Schritt selbst; er steht hier für den Fall, dass Sie
von Hand einrichten oder die Vorgabe ersetzen wollen. Ist die Anlage bereits
eingerichtet und die Oberfläche fehlt noch:
sudo /opt/syncova/setup.sh --weboberflaeche
Das richtet nginx ein, stellt ein selbst signiertes Zertifikat aus und nennt
dessen Fingerabdruck. Mit --ohne-weboberflaeche unterbleibt der Schritt.
Die API bleibt dabei an 127.0.0.1:8080 gebunden. Erreichbar ist sie nur
durch nginx hindurch — ein Angreifer im Netz kommt nicht an ihr vorbei, und die
Verschlüsselung lässt sich nicht umgehen, indem man Port 8080 direkt anspricht.
Die Oberfläche ist ein Satz statischer Dateien unter web/. Sie braucht einen
SPA-Fallback, sonst ergibt ein Neuladen auf /recovery-points einen 404:
server {
listen 443 ssl;
server_name syncova.example;
root /opt/syncova/web;
location / {
try_files $uri /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
}
Zwei Punkte, die in dieser Kurzfassung fehlen und die setup.sh mitsetzt:
http2schreibt sich je nach nginx-Fassung anders. Ab 1.25.1 als eigene Anweisunghttp2 on;, davor als Parameterlisten 443 ssl http2;. Die neue Schreibweise auf einer älteren Fassung ergibt „unknown directive http2" — nginx startet dann nicht. Debian 12 liefert 1.22.- Zeitüberschreitungen hochsetzen. Eine Vorabprüfung liest jeden Block; die Vorgabe von 60 Sekunden bricht sie bei großen Beständen ab.
Selbst signiertes Zertifikat
Es schützt gegen Mitlesen, nicht gegen einen Mittelsmann — niemand bestätigt,
dass es zu diesem Server gehört. Deshalb nennt setup.sh den Fingerabdruck;
vergleichen Sie ihn beim ersten Aufruf mit dem, den der Browser anzeigt. Danach
ist die Warnung unbedenklich.
Für den Dauerbetrieb gehört ein Zertifikat einer Zertifizierungsstelle hierher
— eine eigene CA oder Let's Encrypt. Legen Sie es nach
/etc/syncova/tls/server.crt und server.key und laden Sie nginx neu.
Firewall
setup.sh meldet den Zustand der Firewall und öffnet nichts. Eine
Einrichtung, die selbsttätig einen Port ins Netz öffnet, hebelt genau die
Entscheidung aus, für die jemand die Firewall aufgesetzt hat. Port 443 geben
Sie selbst frei:
sudo ufw allow 443/tcp # ufw
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:
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 Datenbankzeile:
sudo install -d -o syncova -g syncova -m 0700 /srv/syncova-repository
sudo -u syncova ./bin/syncova-repo create \
--path /srv/syncova-repository --name "Hauptziel" --hardened
--hardened setzt den Aufbewahrungsschutz: Manifeste, Blöcke, Schutzvermerke,
Descriptor und Datenschlüssel bekommen das Unveränderlich-Kennzeichen des
Dateisystems. Ein so angelegtes Repository lässt sich nicht mit rm -rf
entfernen — auch nicht von root, ohne den Schutz vorher aufzuheben.
Danach wird es in der Control Plane eingetragen:
curl -X POST https://syncova.example/api/v1/repositories \
-H "Authorization: Bearer <token>" -H 'Content-Type: application/json' \
-d '{"name":"Hauptziel","location":"/srv/syncova-repository"}'
Der Endpunkt legt nichts an, sondern übernimmt: Er öffnet das vorhandene Repository und liest dessen Kennung aus dem Descriptor. Liegt dort keines, lehnt er ab, statt einen Eintrag ohne Ablage dahinter zu erzeugen.
Anschließend die Durchsetzungsstufe messen — sie wird gemessen, nicht behauptet:
curl -X POST https://syncova.example/api/v1/repositories/<id>/enforcement/measure \
-H "Authorization: Bearer <token>"
10. Erster Auftrag
Über die Oberfläche (Backup-Assistent, zehn Schritte) oder die API:
curl -X POST https://syncova.example/api/v1/jobs \
-H "Authorization: Bearer <token>" -H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" -d '{
"name": "Dateiserver täglich",
"repository_id": "<repository>",
"schedule": {"type": "daily", "time": "02:00", "time_zone": "Europe/Berlin"},
"sources": [{"type": "filesystem", "id": "/srv/daten", "name": "Daten"}]
}'
Ohne Zeitzone rechnet der Server in UTC, nicht in der Ortszeit des Servers. Sonst liefe dieselbe Konfiguration auf zwei Servern zu verschiedenen Zeiten.
11. Der Schritt, den die meisten auslassen
# Eine Wiederherstellung durchführen, bevor man sie braucht
curl -X POST https://syncova.example/api/v1/verification \
-H "Authorization: Bearer <token>" -H 'Content-Type: application/json' \
-d '{"backup_id":"<id>","verification_type":"restore_test"}'
Erst danach steigt ein Wiederherstellungspunkt auf recoverable. Alles davor
ist ein Indiz, kein Nachweis.
Aktualisierung auf eine neue Fassung
# 1. Datenbank sichern — ein Rollback ersetzt keine Sicherung
pg_dump -Fc syncova > syncova-vor-update.dump
# 2. Dienst anhalten
sudo systemctl stop syncova-api
# 3. Programme austauschen
sudo tar -xzf syncova-<neu>-linux-amd64.tar.gz -C /opt/syncova --strip-components=1
# 4. Migrationen anwenden
sudo -u syncova /opt/syncova/bin/syncova-migrate up
# 5. Starten und nachsehen
sudo systemctl start syncova-api
curl -s http://127.0.0.1:8080/health/ready
Reihenfolge einhalten: Die Migrationen laufen mit dem neuen Programm, und der Dienst startet erst danach. Läuft er noch, während sich das Schema ändert, arbeitet er auf einem Stand, den er nicht kennt.
Geht etwas schief: syncova-migrate down nimmt genau eine Migration zurück
und verlangt in der Produktion SYNCOVA_MIGRATE_CONFIRM_DOWN=yes. Daten in
Tabellen, die es vorher nicht gab, sind danach weg — deshalb Schritt 1.
Was nach der Installation zu tun bleibt
- Zweiten Faktor einrichten, mindestens für alle Konten mit Löschrecht.
- Benachrichtigungsweg einrichten, sonst erfährt niemand von einem Ausfall.
syncova-dr exportregelmäßig laufen lassen — die Konfigurationssicherung im Repository ist das, was nach einem Totalverlust des Servers übrig bleibt.- Den Verschlüsselungsschlüssel außerhalb der Anlage hinterlegen.