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>
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_insecureist 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.