333 lines
14 KiB
Markdown
333 lines
14 KiB
Markdown
# Bad-Signature-Toolkit
|
||
|
||
Werkzeuge zum Aufspüren und Beheben von **"Bad Signature"-Fehlern** der
|
||
Nextcloud Server-Side-Encryption (Dateien, die sich wegen einer
|
||
fehlerhaften Verschlüsselungs-Signatur nicht mehr öffnen lassen).
|
||
|
||
Alle Scripte laufen als **root** auf dem jeweiligen Nextcloud-Server und
|
||
können auch **ganz ohne Parameter** aufgerufen werden – `-s <website>`
|
||
ist optional, nicht Pflicht. Fehlt es, ermittelt das Script alle
|
||
konfigurierten Instanzen anhand der `.conf`-Dateien im `conf/`-
|
||
Verzeichnis neben den Scripten. Gibt es davon **mehrere** (mehrere
|
||
Nextcloud-Instanzen auf demselben Server), wird interaktiv eine
|
||
Auswahlliste angezeigt, aus der die gewünschte Website ausgewählt wird.
|
||
Das gilt für alle sechs Scripte gleichermaßen.
|
||
|
||
## Der Ablauf auf einen Blick
|
||
|
||
```
|
||
1. scan_bad_signature.sh Betroffene Dateien FINDEN (read-only)
|
||
2. recover_bad_signature.sh Dateien probeweise ENTSCHLÜSSELN (read-only,
|
||
schreibt nur außerhalb von Nextcloud)
|
||
3. restore_bad_signature.sh Geprüfte Dateien ZURÜCKSCHREIBEN (live-Schreibzugriff)
|
||
4. recreate_bad_signature.sh Fallback für die Fälle, die (3) (live-Schreibzugriff,
|
||
nicht reparieren kann bricht Freigaben!)
|
||
5. delete_bad_signature.sh Nicht rettbare Dateien LÖSCHEN (Dateisystem-Bypass +
|
||
(letzter Ausweg nach 3 und 4) direktes DB-Cleanup,
|
||
kein Papierkorb!)
|
||
delete_files.sh Explizite Dateiliste LÖSCHEN (live-Schreibzugriff,
|
||
(unabhängig vom obigen Ablauf) -> Papierkorb)
|
||
```
|
||
|
||
Jeder Schritt liest den Report des vorherigen Schritts. Reports landen
|
||
alle unter `reports/` (Dateiname verrät den Schritt: `bad_signature_…`,
|
||
`recovery_…`, `restore_…`, `recreate_…`, `delete_…`).
|
||
|
||
---
|
||
|
||
## 1. `scan_bad_signature.sh` – Betroffene Dateien finden
|
||
|
||
Liest einmal jede verschlüsselte Datei eines/mehrerer/aller Accounts und
|
||
protokolliert, welche dabei mit einem Signaturfehler scheitert. **Rein
|
||
lesend** – verändert, verschiebt oder löscht nichts.
|
||
|
||
```bash
|
||
./scan_bad_signature.sh -s <website>
|
||
# oder ganz ohne Parameter - Website wird interaktiv abgefragt
|
||
# (bei mehreren konfigurierten Instanzen als Auswahlliste):
|
||
./scan_bad_signature.sh
|
||
```
|
||
|
||
→ Ergebnis: `reports/bad_signature_<website>_<datum>.tsv`
|
||
|
||
---
|
||
|
||
## 2. `recover_bad_signature.sh` – Versuchsweise entschlüsseln
|
||
|
||
Schaltet die Signaturprüfung *instanzweit, nur für die Laufzeit des
|
||
Scripts* ab (`encryption_skip_signature_check`) und versucht, die
|
||
betroffenen Dateien trotzdem zu entschlüsseln. Funktioniert nur, wenn
|
||
die Signaturprüfung selbst das Problem ist – nicht bei tatsächlich
|
||
beschädigtem Chiffretext. Jede gewonnene Datei wird automatisch geprüft
|
||
(Dateityp-Signatur, PDF-/ZIP-Integrität, Plausibilität der Dateigröße
|
||
o. Ä.) und als `VALID`, `UNVERIFIED` ("Nicht prüfbar") oder `INVALID`
|
||
("Datenmüll") eingestuft.
|
||
|
||
**Wichtig:** Original-Dateien in Nextcloud werden nie angefasst. Alles
|
||
landet in einem separaten Verzeichnis außerhalb von Nextclouds eigener
|
||
Ablage (`/var/nc-recovery/<website>/…`) – dort liegen danach
|
||
**unverschlüsselte** Daten, also nach Gebrauch aufräumen.
|
||
|
||
```bash
|
||
./recover_bad_signature.sh -s <website>
|
||
# oder ganz ohne Parameter - Website wird interaktiv abgefragt:
|
||
./recover_bad_signature.sh
|
||
|
||
# Nur erneut validieren (z. B. nach einem Script-Update mit neuen
|
||
# Prüfregeln), ohne nochmal zu entschlüsseln:
|
||
./recover_bad_signature.sh -V -s <website>
|
||
```
|
||
|
||
→ Ergebnis: `reports/recovery_<website>_<datum>.tsv`
|
||
|
||
---
|
||
|
||
## 3. `restore_bad_signature.sh` – Zurückschreiben (Regelfall)
|
||
|
||
Schreibt die in Schritt 2 gewonnenen Dateien über die **normale
|
||
Nextcloud-Files-API** an ihren ursprünglichen Pfad zurück – der einzige
|
||
Weg, der Datei-ID und bestehende Freigaben erhält. Danach ist die Datei
|
||
wieder ganz normal verschlüsselt, mit frischer, korrekter Signatur.
|
||
|
||
**Seit dem letzten Update werden standardmäßig zwei Kategorien
|
||
zurückgeschrieben**, klar unterscheidbar im Report (Spalte `origin`):
|
||
|
||
| validation im Recovery-Report | Bedeutung | wird restauriert |
|
||
|---|---|---|
|
||
| `VALID` | dedizierte Strukturprüfung hat den Inhalt bestätigt | ja |
|
||
| `UNVERIFIED`, Größe plausibel | kein dedizierter Check, aber nichts sieht falsch aus | ja |
|
||
| `UNVERIFIED`, Größe "LOOKS OFF" | Größenverhältnis auffällig – echtes Warnsignal | **nein** |
|
||
| `INVALID` ("Datenmüll") | Strukturprüfung fehlgeschlagen | **nein** |
|
||
|
||
```bash
|
||
./restore_bad_signature.sh -s <website>
|
||
# oder ganz ohne Parameter - Website wird interaktiv abgefragt:
|
||
./restore_bad_signature.sh
|
||
# nur Dry-Run (nichts wird geschrieben):
|
||
./restore_bad_signature.sh -n -s <website>
|
||
```
|
||
|
||
Fragt danach interaktiv: welcher Recovery-Report, welche(r) Account(s).
|
||
|
||
**Sicherheit:** Neuvalidierung direkt vor jedem Schreiben · aktueller
|
||
(noch kaputter) Chiffretext wird vorher byte-genau gesichert
|
||
(`/var/nc-restore-backup/<website>`) · jede Datei wird nach dem
|
||
Schreiben normal zurückgelesen und per SHA-256 verglichen · Dry-Run ist
|
||
Default, echter Lauf braucht eine ausdrückliche `YES`-Bestätigung.
|
||
|
||
⚠️ **Ein erneuter Lauf wählt wieder *alle* passenden Einträge des
|
||
gewählten Accounts aus dem Report** – auch bereits erfolgreich
|
||
restaurierte, nicht nur neue. Für ein gezieltes Nachziehen einzelner,
|
||
noch offener Dateien lieber einen auf diese Dateien reduzierten
|
||
Mini-Report verwenden, statt den ganzen Account-Bestand erneut zu
|
||
überschreiben.
|
||
|
||
→ Ergebnis: `reports/restore_<website>_<datum>.tsv`
|
||
|
||
---
|
||
|
||
## 4. `recreate_bad_signature.sh` – Fallback für Schlüsselmaterial-Fehler
|
||
|
||
Nur nötig, wenn `restore_bad_signature.sh` bei einer Datei mit einem
|
||
**Schlüsselmaterial-Fehler** scheitert (`MultiKeyDecryptException` /
|
||
"probably this is a shared file…") statt mit "Bad Signature". Löscht
|
||
die kaputte Datei auf reiner Dateisystem-Ebene (inkl. altem
|
||
Schlüssel-Verzeichnis) und legt sie komplett neu an, mit frischem
|
||
Schlüssel.
|
||
|
||
⚠️ **Invasiver als restore:** Die Datei bekommt eine **neue Datei-ID**
|
||
– bestehende Freigaben, Kommentare, Tags und Versionshistorie dieser
|
||
Datei gehen dabei verloren und müssten danach manuell neu eingerichtet
|
||
werden. Nur verwenden, wenn Schritt 3 tatsächlich mit diesem
|
||
spezifischen Fehler gescheitert ist.
|
||
|
||
```bash
|
||
./recreate_bad_signature.sh -s <website>
|
||
# oder ganz ohne Parameter - Website wird interaktiv abgefragt:
|
||
./recreate_bad_signature.sh
|
||
# Dateien mit aktiven Freigaben standardmäßig übersprungen,
|
||
# nur mit Bedacht einschließen:
|
||
./recreate_bad_signature.sh -f -s <website>
|
||
```
|
||
|
||
**Sicherheit:** Nur Dateien mit passendem Fehler aus dem
|
||
restore-Report werden angefasst · Chiffretext UND Schlüssel-Verzeichnis
|
||
werden vorher gesichert und die Sicherung vor dem Löschen verifiziert
|
||
(`/var/nc-recreate-backup/<website>`) · Dateien mit aktiven Freigaben
|
||
werden standardmäßig übersprungen · Verifikation nach dem Schreiben wie
|
||
bei restore.
|
||
|
||
→ Ergebnis: `reports/recreate_<website>_<datum>.tsv`
|
||
|
||
---
|
||
|
||
## 5. `delete_bad_signature.sh` – Letzter Ausweg für nicht rettbare Dateien
|
||
|
||
Für Dateien, bei denen weder `restore_bad_signature.sh` noch
|
||
`recreate_bad_signature.sh` geholfen hat und die **nicht mehr
|
||
erhaltenswert sind**: löscht sie vollständig, indem die
|
||
Verschlüsselungsschicht vollständig umgangen wird.
|
||
|
||
**Hintergrund:** Dateien mit kaputten Signaturen können nicht über die
|
||
normale Nextcloud-API oder WebDAV gelöscht werden – auch ein normaler
|
||
`rm` im Dateisystem reicht nicht, weil der Filecache-Eintrag in der
|
||
Datenbank bestehen bleibt und Nextcloud die Datei weiterhin anzeigt.
|
||
Außerdem blockieren solche Dateien die Archiv-/Download-Funktion
|
||
(Nextcloud wirft bei jedem Versuch, sie einzuschließen, eine
|
||
`DecryptionFailedException`). Dieses Script erledigt daher drei Dinge:
|
||
|
||
1. Rohen Chiffretext per `rm -f` vom Dateisystem entfernen
|
||
2. Schlüsselmaterial-Verzeichnis per `rm -rf` entfernen
|
||
3. Filecache-Eintrag, Freigabe-Einträge und Sperren direkt per
|
||
MySQL-Abfragen aus der Datenbank löschen
|
||
|
||
Das Script benötigt **kein** `INSTALL_DIR`, `HTTP_USER` oder PHP –
|
||
das Datenbank-Cleanup erfolgt direkt über den MySQL-Client.
|
||
|
||
**Standardverhalten (sicher):** Alle `recreate_<website>_*.tsv`-Reports
|
||
im `reports/`-Verzeichnis werden automatisch ausgewertet. Dateien, die
|
||
dort bereits als `OK` oder `WRITTEN_UNVERIFIED` stehen (erfolgreich
|
||
wiederhergestellt), werden **nicht** gelöscht. So werden nur Dateien
|
||
entfernt, die tatsächlich nicht gerettet werden konnten.
|
||
|
||
**`DATA_DIR`-Erkennung:** Wenn `DATA_DIR` in der conf-Datei nicht
|
||
gesetzt ist, versucht das Script es automatisch aus `WEB_BASE_DIR/data`
|
||
oder `/var/www/<website>/data` abzuleiten – mit interaktiver
|
||
Bestätigung, bevor fortgefahren wird.
|
||
|
||
```bash
|
||
./delete_bad_signature.sh -s <website>
|
||
# oder ganz ohne Parameter - Website wird interaktiv abgefragt:
|
||
./delete_bad_signature.sh
|
||
|
||
# Dry-Run: zeigt, was gelöscht würde, ohne etwas zu verändern:
|
||
./delete_bad_signature.sh -n -s <website>
|
||
|
||
# Alle kaputten Signaturdateien löschen, auch bereits recreatete
|
||
# (Vorsicht!):
|
||
./delete_bad_signature.sh -a -s <website>
|
||
|
||
# Zusätzlichen recreate-Report für den Ausschluss angeben:
|
||
./delete_bad_signature.sh -x reports/recreate_<website>_<datum>.tsv -s <website>
|
||
```
|
||
|
||
**Pflicht-Variablen in der conf-Datei:**
|
||
|
||
| Variable | Beschreibung |
|
||
|---|---|
|
||
| `DATABASE_NAME` | Name der Nextcloud-Datenbank |
|
||
| `DATABASE_TYPE` | Muss `mysql` sein (PostgreSQL noch nicht unterstützt) |
|
||
| `MYSQL_CREDENTIALS` | MySQL-Client-Argumente, z. B. `-u root -S /run/mysqld/mysqld.sock` |
|
||
|
||
**Optionale Variablen (werden auto-erkannt oder haben Defaults):**
|
||
|
||
| Variable | Beschreibung | Default |
|
||
|---|---|---|
|
||
| `DATA_DIR` | Nextcloud-Datenverzeichnis | auto-erkannt aus `WEB_BASE_DIR/data` oder `/var/www/<website>/data` |
|
||
| `WEB_BASE_DIR` | Nextcloud-Webroot | – |
|
||
| `DB_TABLE_PREFIX` | Datenbank-Tabellenpräfix | `oc_` |
|
||
| `DELETE_BACKUP_BASE_DIR` | Backup-Verzeichnis vor dem Löschen | ein Verzeichnis über `DATA_DIR` |
|
||
|
||
⚠️ **Kein Papierkorb.** Die Dateien werden unwiderruflich entfernt –
|
||
lediglich ein Backup des Chiffretexts und des Schlüssel-Verzeichnisses
|
||
wird unter `DELETE_BACKUP_BASE_DIR` angelegt, bevor gelöscht wird. Das
|
||
ermöglicht ein manuelles Wiederherstellen auf Dateisystem-Ebene, aber
|
||
kein automatisches "Rückgängig" innerhalb von Nextcloud.
|
||
|
||
→ Ergebnis: `reports/delete_<website>_<datum>.tsv`
|
||
|
||
---
|
||
|
||
## `delete_files.sh` – Gezielt nicht benötigte Dateien löschen
|
||
|
||
Generisches, von Account und Site unabhängiges Script für den zweiten
|
||
Teil des Aufräum-Workflows: eine **von Hand geprüfte** Liste an
|
||
Dateien entfernen, die nicht erhaltenswert sind (z. B. macOS-Spotlight-
|
||
Indexdateien, Fragmente aus "Webseite speichern"). Kein Scannen, kein
|
||
automatisches Erraten – jede Zeile in der Liste ist eine bewusste
|
||
Entscheidung.
|
||
|
||
Pfadliste: einfache Textdatei, ein Pfad pro Zeile (`#`-Kommentare und
|
||
Leerzeilen erlaubt), Account wird automatisch aus dem Pfad erkannt:
|
||
|
||
```
|
||
/inge/files/Ordner/Datei.ext
|
||
/anderer-account/files/Anderer/Pfad/datei2.ext
|
||
```
|
||
|
||
```bash
|
||
./delete_files.sh -s <website> -f <pfadliste.txt>
|
||
# oder ganz ohne Parameter - Website UND Pfad zur Liste werden
|
||
# interaktiv abgefragt:
|
||
./delete_files.sh
|
||
# nur Dry-Run:
|
||
./delete_files.sh -n -s <website> -f <pfadliste.txt>
|
||
```
|
||
|
||
Löscht über die normale Files-API (→ **Papierkorb**, sofern
|
||
`files_trashbin` aktiv ist) und sichert den Chiffretext zusätzlich
|
||
byte-genau vorher (`/var/nc-delete-backup/<website>`). Ein bereits
|
||
nicht mehr existierender Pfad wird als `NOT_FOUND` gemeldet, nicht als
|
||
Fehler.
|
||
|
||
→ Ergebnis: `reports/delete_<website>_<datum>.tsv`
|
||
|
||
---
|
||
|
||
## Typischer Ablauf
|
||
|
||
```bash
|
||
./scan_bad_signature.sh -s cloud-01.oopen.de # betroffene Dateien finden
|
||
./recover_bad_signature.sh -s cloud-01.oopen.de # entschlüsseln + prüfen
|
||
./restore_bad_signature.sh -s cloud-01.oopen.de # VALID + plausible zurückschreiben
|
||
|
||
# nur bei einzelnen WRITE_ERROR mit Schlüsselmaterial-Fehler nötig:
|
||
./recreate_bad_signature.sh -s cloud-01.oopen.de
|
||
|
||
# letzter Ausweg: nicht rettbare Dateien bereinigen
|
||
# (schließt automatisch alle erfolgreich recreateten aus):
|
||
./delete_bad_signature.sh -s cloud-01.oopen.de
|
||
|
||
# optional: von Hand geprüfte, nicht erhaltenswerte Dateien entfernen
|
||
./delete_files.sh -s cloud-01.oopen.de -f nicht_benoetigt.txt
|
||
|
||
# zur Kontrolle: sollte jetzt (für erledigte Accounts) 0 melden
|
||
./scan_bad_signature.sh -s cloud-01.oopen.de
|
||
```
|
||
|
||
## Verzeichnisse
|
||
|
||
| Zweck | Standardpfad | Override (conf-Datei) |
|
||
|---|---|---|
|
||
| Recovery-Kopien (unverschlüsselt!) | `/var/nc-recovery/<website>` | `RECOVERY_BASE_DIR` |
|
||
| Backup vor restore-Überschreiben | `/var/nc-restore-backup/<website>` | `RESTORE_BACKUP_BASE_DIR` |
|
||
| Backup vor recreate-Löschen | `/var/nc-recreate-backup/<website>` | `RECREATE_BACKUP_BASE_DIR` |
|
||
| Backup vor delete_bad_sig.-Löschen | ein Verzeichnis über `DATA_DIR` | `DELETE_BACKUP_BASE_DIR` |
|
||
| Backup vor delete_files-Löschen | `/var/nc-delete-backup/<website>` | `DELETE_BACKUP_BASE_DIR` |
|
||
| Reports aller Scripte | `reports/` (neben den Scripten) | – |
|
||
|
||
## Sicherheitsprinzipien (gelten für alle schreibenden Scripte)
|
||
|
||
- **Dry-Run ist Standard** – ein echter Lauf braucht eine ausdrückliche `YES`-Bestätigung.
|
||
- **Immer zuerst sichern**, dann erst schreiben/löschen – byte-genaue Kopie, unabhängig von Nextcloud.
|
||
- **Immer neu validieren** unmittelbar vor dem Zugriff, nicht blind aus einem alten Report übernehmen.
|
||
- **Immer verifizieren** nach dem Schreiben (Rücklesen + SHA-256-Vergleich).
|
||
- Jedes Script kann per `Strg-C` sicher unterbrochen werden – kein halb geschriebener Report.
|
||
|
||
## Kurzreferenz aller Flags
|
||
|
||
`-s <website>` ist bei **allen** Scripten optional – fehlt es, wird die
|
||
Website interaktiv abgefragt (Auswahlliste bei mehreren konfigurierten
|
||
Instanzen).
|
||
|
||
| Script | `-s` (optional) | weitere Optionen |
|
||
|---|---|---|
|
||
| `scan_bad_signature.sh` | Website | – |
|
||
| `recover_bad_signature.sh` | Website | `-V` nur revalidieren |
|
||
| `restore_bad_signature.sh` | Website | `-n` Dry-Run erzwingen |
|
||
| `recreate_bad_signature.sh` | Website | `-n` Dry-Run erzwingen · `-f` Dateien mit aktiven Freigaben einschließen |
|
||
| `delete_bad_signature.sh` | Website | `-n` Dry-Run erzwingen · `-a` alle löschen (auch recreatete) · `-x <report>` zusätzlichen recreate-Report für Ausschluss angeben |
|
||
| `delete_files.sh` | Website | `-n` Dry-Run erzwingen · `-f <datei>` Pfadliste (ohne Angabe interaktiv abgefragt) |
|
||
|
||
`-h` zeigt bei jedem Script die ausführliche Hilfe.
|