syncova-backup/docs/alerting.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

8.6 KiB

Meldungen und Benachrichtigungen

Phase 14. Der Teil der Anlage, der sagt, wann jemand hinsehen muss.

Das Meldungswesen hat einen Feind, und es ist nicht der fehlende Alarm:

Es ist der Alarm, den niemand mehr liest.

Ein System, das jede Minute dieselbe Meldung erzeugt, wird nach drei Tagen weggeklickt — und dann fehlt die eine, auf die es ankam. Jede Entscheidung dieser Phase ist an dieser Beobachtung gemessen.

Zwei Eigenschaften tragen alles

Eine Ursache, eine Meldung

Jeder Befund trägt einen Fingerabdruck aus Regel und betroffenem Gegenstand — nicht aus dem Zeitpunkt. Ein Teilindex macht eine zweite offene Meldung zur selben Ursache unmöglich:

CREATE UNIQUE INDEX alerts_single_open_idx ON alerts (fingerprint)
    WHERE status IN ('open', 'acknowledged');

Die Regel steht in der Datenbank und nicht in der Anwendung: Zwischen einem Nachsehen und einem Schreiben passt ein zweiter Control-Server. Der wiederholte Befund erhöht stattdessen einen Zähler — und der ist die eigentliche Auskunft: Einmal ist ein Zwischenfall, zwanzigmal ein Zustand.

Meldungen lösen sich selbst auf

Jede Regel liefert die Menge der derzeit zutreffenden Befunde. Was darin fehlt, aber noch offensteht, wird geschlossen — automatisch, mit dem Vermerk „Die Ursache besteht nicht mehr."

Ohne diesen Schritt bleibt jede Meldung stehen, bis jemand sie wegklickt. Nach zwei Wochen steht dort eine Liste erledigter Probleme, und die eine aktuelle geht darin unter.

Der Auswerter beschreibt deshalb den Ist-Zustand, statt Ereignisse zu zählen.

Bestätigen heißt nicht Erledigen

Eine bestätigte Meldung bleibt offen und in der Liste unerledigter Vorgänge. Sie wird weiter aktualisiert, solange die Ursache besteht. Wäre „bestätigen" dasselbe wie „schließen", verschwände der Zustand aus der Übersicht, obwohl er weiterbesteht.

Wer eine Meldung von Hand schließt, bekommt gesagt: „Besteht die Ursache weiterhin, erzeugt die nächste Auswertung eine neue Meldung."

Die elf Regeln

Regel Schwere Auslöser
backup_failure hoch / Warnung Letzter Lauf gescheitert oder mit Teilfehler
repeated_backup_failure kritisch Zwei Fehlschläge in Folge
repository_unavailable kritisch Repository als nicht erreichbar geführt
repository_filling Warnung Belegung ≥ 80 %
repository_full kritisch Belegung ≥ 90 %
agent_offline hoch 15 Minuten ohne Lebendmeldung
rpo_violation hoch Letzte erfolgreiche Sicherung älter als die RPO-Vorgabe
verification_failure kritisch Backup als corrupted eingestuft
unusual_change_rate hoch ≥ 90 % neue Daten in einer Zusatzsicherung
immutable_copy_missing Warnung Wiederherstellungspunkte ohne Löschschutz
certificate_expiry — Wird nicht geprüft

Warum die Zertifikatsregel schweigt

Die Agenten weisen sich über Betriebstokens aus, nicht über Zertifikate. Die Tabelle agent_certificates wird von keiner Stelle beschrieben — die Regel könnte nie auslösen.

Eine Regel, die dauerhaft schweigt, ist gefährlicher als keine: Sie erweckt den Eindruck, es werde geprüft. Sie erscheint deshalb im Regelwerk mit dieser Begründung und wird nicht ausgewertet.

Warum die Ransomware-Regel „Verdacht" heißt

unusual_change_rate erkennt, dass bei einer Zusatzsicherung fast alle Daten neu waren, obwohl die Quelle bereits gesichert war. Die Deduplizierung greift dann plötzlich nicht mehr, weil kein Block dem vorigen Backup gleicht.

Massenhafte Verschlüsselung durch Schadsoftware sieht genau so aus. Ein großes Update, eine Datenbankreorganisation oder ein Kettenwechsel aber auch.

Die Meldung sagt das ausdrücklich und rät, die Änderung zu prüfen, bevor ältere Wiederherstellungspunkte gelöscht werden. Eine Anlage, die „Ransomware erkannt" meldet und danebenliegt, wird beim nächsten Mal ignoriert — und dann liegt sie richtig.

Die Schwellen

Sie stehen beisammen im Code, weil ihre Wahl den Wert des ganzen Meldungswesens bestimmt:

  • Zwei Fehlschläge, nicht drei: Einer kann ein Netzwerkzucken sein, zwei hintereinander sind ein Zustand.
  • 15 Minuten ohne Lebendmeldung bei einem Meldeabstand von einer Minute: Ein zweiminütiger Netzwerkausfall weckt niemanden.
  • 90 % neue Daten und mindestens 100 MB: Ohne Untergrenze meldete jede kleine Quelle mit drei geänderten Dateien einen Verdacht.
  • 80 % / 90 % Belegung, getrennte Bereiche: Ein zu 95 % belegtes Repository erzeugt sonst zwei Meldungen zur selben Ursache.

Zustellung

Zwei Kanäle, beide mit echter Auslieferung — geprüft gegen einen echten SMTP-Server und einen echten HTTP-Empfänger, nicht gegen Attrappen.

Kanal Zustellung
email SMTP; Schweregrad in der Betreffzeile, Meldungskennung im Rumpf
webhook HTTP-POST mit JSON; Authorization: Bearer … zur Prüfung der Herkunft
  • Nur neue Meldungen werden zugestellt. Eine aktualisierte nicht — sonst bekäme der Bereitschaftsdienst alle fünf Minuten dieselbe Mail, solange der Zustand anhält. Ein Eindeutigkeitsindex sichert das zusätzlich ab.
  • Jeder Kanal hat eine Schwelle. Standard ist high. Ohne sie bekäme der Bereitschaftsdienst nachts jede Information; nach einer Woche schaltet er die Benachrichtigungen ab, und dann kommt auch die kritische nicht mehr an.
  • Webhook verlangt HTTPS. Eine Meldung über unverschlüsseltes HTTP verrät einem Mitleser, welche Anlage gerade nicht gesichert wird. allow_insecure ist der ausdrückliche Ausweg; einen Schalter „Zertifikat egal" gibt es nicht.
  • Der Schweregrad steht im Betreff. Wer nachts auf sein Telefon sieht, liest die Betreffzeile und sonst nichts.
  • Fehlgeschlagene Zustellungen werden am Kanal vermerkt (last_delivery_error, consecutive_failures). Ein Kanal, der seit Wochen nichts zustellt, ist genauso schlimm wie eine fehlende Meldung — und ohne dieses Feld fällt es niemandem auf.
  • Zugangsgeheimnisse werden verschlüsselt abgelegt und gehen nie in eine API-Antwort, ein Protokoll oder eine Fehlermeldung.

Endpunkte

Methode Pfad Recht
GET /api/v1/alerts alerts.read
GET /api/v1/alerts/summary alerts.read
GET /api/v1/alerts/{id} alerts.read
POST /api/v1/alerts/{id}/acknowledge alerts.write
POST /api/v1/alerts/{id}/resolve alerts.write
GET /api/v1/notification-channels settings.read
POST /api/v1/notification-channels settings.write
DELETE /api/v1/notification-channels/{id} settings.write

Die Kanäle hängen am Einstellungsrecht, nicht am Meldungsrecht: Wer Benachrichtigungen umleitet, kann erreichen, dass niemand mehr von einem Ausfall erfährt. Anlegen und Löschen werden auditiert.

/alerts/summary liefert die Lage und das Regelwerk. Eine leere Meldungsliste ist erst dann eine gute Nachricht, wenn man weiß, was überhaupt geprüft wird.

Nachgewiesen

Gegen den laufenden Dienst:

Nachweis Ergebnis
Regelwerk 10 von 11 Regeln werden geprüft, die elfte mit Begründung
Erkennung 12 Meldungen aus echten Zuständen (6 kritisch, 3 ernst)
Deduplizierung Nach mehreren Durchgängen eine Meldung je Ursache, Zähler steigt
Selbstauflösung Zwei Repositories wieder erreichbar → beide Meldungen automatisch geschlossen, die anderen zwei blieben offen
Zustellung Webhook-Empfänger erhielt Meldung samt Bearer-Token
Keine Doppelzustellung Nach weiterem Durchgang weiterhin genau eine Zustellung
Schwelle Null Zustellungen unterhalb critical an den kritischen Kanal
Geheimnis Erscheint nicht in der API-Antwort
Bestätigen Zustand acknowledged, Meldung bleibt in der Liste; zweiter Versuch 409

Bekannte Grenzen

  • Keine Wiederholung fehlgeschlagener Zustellungen. Ein nicht erreichbarer Empfänger bleibt es meist auch beim zweiten Versuch, und die Schleife soll nicht daran hängen. Der Kanalzustand macht das Problem sichtbar.
  • Keine Ruhezeiten und keine Eskalation. Eine Meldung geht sofort an alle passenden Kanäle; es gibt keine Wartungsfenster für Benachrichtigungen und keine Weiterleitung, wenn niemand reagiert.
  • Regeln und Schwellen sind fest. Sie stehen im Code, nicht in der Datenbank. Eine Oberfläche zum Ändern gäbe es erst, wenn klar ist, welche Schwellen sich in der Praxis als falsch erweisen.
  • Kein Test der Kanäle vor dem Ernstfall. Ob eine Adresse stimmt, zeigt sich bei der ersten echten Meldung.
  • Die Zertifikatsregel wartet auf eine Zertifikatsverwaltung für Agenten.