# 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: ```sql 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.