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>
10 KiB
Ransomware-Heuristik (Phase 16)
Die Vorgabe des Implementierungsplans (§18) steht in vier Worten:
Do not make destructive decisions automatically. Alert first.
Dieses Paket löscht nichts, sperrt nichts und hält nichts an. Es beschreibt, was auffällig ist, und überlässt jede Entscheidung einem Menschen.
Der Grund ist nicht Vorsicht, sondern Erfahrung: Eine Heuristik, die selbsttätig handelt, macht aus jedem Fehlalarm einen Schaden — und Fehlalarme wird es geben, weil ein Betriebssystem-Update von außen genauso aussieht wie ein Verschlüsselungsangriff. Ein Werkzeug, das bei einem Softwarerollout die Sicherungskette anhält, wird abgeschaltet. Ein abgeschaltetes Werkzeug erkennt gar nichts.
Was gemessen wird
Sechs Signale, alle sechs aus dem Plan. Fünf davon fielen bei der Sicherung ohnehin an und mussten nur festgehalten werden; eines — der Entropie-Indikator — verlangte einen Eingriff in die Engine.
| Signal | Herkunft | Untergrenze |
|---|---|---|
| Neu abgelegte Datenmenge | backups.unique_bytes |
100 MiB |
| Geänderte Objekte | Zusatzsicherung: Changes.ChangedFileCount(); Vollsicherung: alle Dateien |
20 Objekte |
| Verschwundene Objekte | Changes.DeletedPaths |
20 Objekte |
| Anteil nicht verkleinerbarer Blöcke | Kompressionsmarker der Engine | 10 Prozentpunkte |
| Neue Dateiendungen | extension_distribution (JSONB) |
25 % der Objekte |
| Größe des Laufs | backups.logical_bytes |
100 MiB |
Der Entropie-Indikator kostet nichts, weil die Engine ihn ohnehin bildet.
Ob ein Block sich komprimieren ließ, entscheidet ChunkTransformer.Transform
bei jedem Block. Bislang verschwand diese Erkenntnis im Marker-Byte; jetzt gibt
Transform sie zusätzlich zurück. Verschlüsselte Daten sind nicht komprimierbar
— ein Sprung von „5 % der Blöcke unkomprimierbar" auf „100 %" ist das
verlässlichste technische Anzeichen massenhafter Verschlüsselung, das eine
Sicherungssoftware überhaupt sehen kann. Eine eigene Entropiemessung wäre
derselbe Rechenaufwand ein zweites Mal.
Gezählt werden nur neue Blöcke. Ein deduplizierter Block wurde in einem früheren Lauf schon bewertet; ihn erneut mitzuzählen verwässerte den Anteil genau in dem Lauf, in dem er aussagekräftig wird.
Die Endungsverteilung ist auf 20 Einträge gedeckelt, der Rest fällt in einen
Sammelposten (weitere). Ohne Deckel wüchse die JSONB-Spalte mit jeder
Zufallsendung, die eine Schadsoftware erzeugt — ausgerechnet der Angriff bliese
die Datenbank auf. Der Sammelposten ist vom Signal ausgenommen: Er ist per
Konstruktion in jedem Lauf „neu".
Warum Median und mittlere absolute Abweichung
Der Basiswert entsteht aus den letzten Läufen derselben Kette, nicht aus einer festen Schwelle. Eine feste Schwelle kann es nicht geben: Ein Dateiserver mit 2 geänderten Dateien je Tag und ein Buildserver mit 40 000 sind beide normal.
Gerechnet wird mit Median und mittlerer absoluter Abweichung, nicht mit Mittelwert und Standardabweichung. Der Grund ist der Kern der ganzen Sache:
Ein einziger Ausreißer ist genau der Fall, den wir erkennen wollen. Würde er den Basiswert mitbestimmen, höbe er die Schwelle an, gegen die er gemessen wird.
Bei fünf normalen Läufen (~100) und einem Angriff (50 000) läge der Mittelwert
über 8000 — der nächste Angriff derselben Größe fiele nicht mehr auf. Der Median
bleibt bei 100. TestMedianResistsSingleOutlier hält das fest.
Weitere Festlegungen:
- Mindestens fünf Läufe. Mit dreien ist ein Median eine Formalität und die
Streuung Zufall. Darunter lautet die Einstufung
unknown— ausdrücklich getrennt vonnone. Wer nicht messen kann, hat nichts gemessen und darf nicht so tun, als sei alles in Ordnung. - Höchstens zwanzig Läufe. Ein Basiswert aus einem Jahr beschriebe eine Anlage, die es so nicht mehr gibt.
- Nur nach oben geprüft. Weniger geänderte Dateien als sonst sind kein Angriffszeichen; eine zweiseitige Prüfung erzeugte an jedem ruhigen Wochenende einen Befund.
- Zwei Bedingungen zugleich — drei mittlere Abweichungen und 50 % mehr. Der Faktor allein schlüge bei sehr gleichmäßigen Werten schon bei Geringfügigkeiten an; die relative Änderung allein übersähe eine Quelle, die ohnehin stark schwankt.
- Streuung null (eine Quelle, die sich nie ändert) hat keinen Faktor. Dann zählt allein die relative Änderung.
Die absolute Untergrenze ist keine Feinheit
Sie kam durch einen Fehlalarm im Test hinzu. Eine Quelle mit zwei geänderten Dateien je Lauf, jetzt drei: eine Steigerung um fünfzig Prozent, Streuung null — formal ein Befund, tatsächlich vollkommen belanglos. Deshalb hat jedes Signal eine eigene Untergrenze. Zwanzig Dateien mehr sind ein Ereignis, zwanzig Bytes mehr sind Rauschen; eine gemeinsame Grenze für beides gibt es nicht.
Die Erklärung nennt die Untergrenze, statt sie zu verschweigen. Ein Satz wie „der Wert stieg von 336 auf 3 004 350, das liegt unter der Größenordnung" liest sich bei einem tausendfachen Anstieg wie ein Fehler des Werkzeugs — und wer dem Werkzeug einmal misstraut, liest auch den echten Befund nicht mehr.
Einstufung
| Stufe | Bedingung | Schweregrad der Meldung |
|---|---|---|
unknown |
weniger als fünf Vergleichsläufe, oder keine Signale erhoben | keine Meldung |
none |
kein Signal auffällig | keine Meldung |
elevated |
ein Signal auffällig | warning |
high |
zwei oder mehr Signale auffällig | high |
Zwei, nicht eins, für die höhere Stufe: Ein einzelnes auffälliges Signal hat viele harmlose Ursachen — ein großes Update, ein Umzug, ein neuer Datenbestand. Zwei zugleich sind das Muster, das massenhafte Verschlüsselung hinterlässt: viele geänderte Dateien und kaum noch komprimierbare Daten.
Backups aus der Zeit vor dieser Phase tragen die Kennzahlen nicht. Sie fließen
nicht als Nullwerte in den Basiswert ein — das zöge ihn nach unten und ließe
jeden neuen Lauf auffällig erscheinen. Sie werden übersprungen, und solange zu
wenige verwertbare Läufe übrig sind, lautet die Einstufung unknown.
Anbindung
- Meldungswesen: Die Regel
unusual_change_ratenutzt seit dieser Phase den Detektor statt einer festen Schwelle. Die Meldung nennt die auffälligen Signale mit Namen und Erklärung. - API:
GET /api/v1/backups/{id}/ransomware-assessment(backups.read) liefert alle sechs Signale einzeln. Ohne diesen Endpunkt bliebe die Meldung „4 von 6 Signalen sind auffällig" eine Behauptung: Ihre Empfehlung lautet „Prüfen Sie die Quelle" — wer aber nicht sehen kann, welche vier Signale gemeint sind, hat keinen Anfang. - Die Bewertung wird bei jedem Aufruf neu berechnet, nicht gespeichert. Der Basiswert wandert mit den letzten Läufen; eine eingefrorene Bewertung beschriebe einen Vergleich, den es so nicht mehr gibt. Dieselbe Entscheidung wie bei der Recovery Assurance (Phase 10).
Die Empfehlung bei high lautet wörtlich:
Prüfen Sie die Quelle, bevor Sie ältere Wiederherstellungspunkte löschen oder eine Aufbewahrungsregel anwenden. Die Anlage unternimmt von sich aus nichts.
Das ist die einzige Handlung, die die Heuristik überhaupt nahelegt — und sie ist eine Unterlassung. Wer nach einem Verschlüsselungsangriff die Aufbewahrung laufen lässt, vernichtet die letzten sauberen Wiederherstellungspunkte.
Nachweis
Geführt gegen den laufenden Dienst, in beide Richtungen. Beide Richtungen sind nötig: Ein Detektor, der jeden Angriff erkennt, aber auch jeden großen Arbeitstag meldet, wird nach einer Woche ignoriert.
Gegentest — harmloser großer Lauf. 200 neue, gut komprimierbare Dokumente zu einer Quelle mit sonst drei geänderten Dateien:
Einstufung: elevated
Auffällig: 1 von 6 Signalen
⚠ Geaenderte Objekte Bisher lag der Wert stets bei 3.0, jetzt bei 200.0 (6567 Prozent mehr).
Richtig: Die Zahl der Dateien stieg sprunghaft — das ist auffällig und wird
gesagt. Der Entropie-Indikator blieb bei 0 %, es verschwand nichts, es kam keine
neue Endung hinzu. Genau ein Signal, also elevated und ein warning, kein
Alarm.
Angriff — simulierte Verschlüsselung. 150 Dateien durch Zufallsdaten
ersetzt, mit der Endung .locked abgelegt, die Originale gelöscht:
Einstufung: HIGH
Auffällig: 4 von 6 Signalen
⚠ Geaenderte Objekte Bisher lag der Wert stets bei 3.0, jetzt bei 150.0 (4900 Prozent mehr).
⚠ Verschwundene Objekte Bisher lag der Wert stets bei 0.0, jetzt bei 150.0 (15000 Prozent mehr).
⚠ Anteil nicht verkleinerbarer Bloecke Bisher lag der Wert stets bei 0.0, jetzt bei 100.0 (10000 Prozent mehr).
⚠ Neue Dateiendungen 1 neue Dateiendungen ([.locked]) betreffen 58 Prozent der Objekte.
Der Anteil nicht verkleinerbarer Blöcke sprang von 0 % auf 100 % — das ist der
Fingerabdruck, den nur Verschlüsselung hinterlässt. Beide Meldungen standen
korrekt abgestuft im Meldungswesen (high und warning), und das Repository
blieb unangetastet: Es wurde nichts gelöscht, nichts gesperrt, nichts angehalten.
Bekannte Grenzen
- Die beiden Byte-Signale tragen bei kleinen Quellen nichts bei. Ihre Untergrenze liegt bei 100 MiB; im Nachweis oben blieben sie deshalb stumm, obwohl die Datenmenge um das Achttausendfache stieg. Das ist gewollt — unter hundert Megabyte ist eine Verschlüsselungswelle weder wirtschaftlich noch bemerkbar —, bedeutet aber: Bei einer kleinen Quelle stützt sich die Erkennung auf vier Signale, nicht auf sechs.
- Ein langsamer Angriff entgeht der Erkennung. Wer über Wochen täglich ein Prozent des Bestands verschlüsselt, verschiebt den Basiswert mit sich. Gegen diesen Fall hilft keine Abweichungsstatistik, sondern die Unveränderlichkeit aus Phase 11.
- Die Zahl geänderter Objekte einer Vollsicherung ist die Zahl aller
Dateien. Ein Wechsel von Zusatz- auf Vollsicherung erzeugt deshalb einen
Ausschlag. Er ist harmlos und wird als
elevatedgemeldet — nicht alshigh, solange die übrigen Signale ruhig bleiben. - Ein Kettenwechsel setzt den Basiswert zurück. Nach einem neuen Repository
oder einer neuen Quelle lautet die Einstufung fünf Läufe lang
unknown. - Keine Erkennung im laufenden Betrieb. Bewertet wird ein abgeschlossener Sicherungslauf. Zwischen Angriff und Meldung liegt bestenfalls ein Sicherungsintervall. Diese Heuristik ist kein Ersatz für einen Endpunktschutz; sie ist die letzte Instanz, die den Schaden bemerkt, bevor die Aufbewahrung die sauberen Wiederherstellungspunkte entfernt.