unzip -tq can block indefinitely on very large or partially corrupt ZIP archives (stalls in I/O rather than exiting with a CRC error). All three scripts that call validate_recovered_file() are affected: recover_, restore_, recreate_bad_signature.sh. Both the quick check (unzip -tq) and the verbose error pass (unzip -t) are now wrapped with `timeout 120`. Exit code 124 (timed out) is reported as UNVERIFIED with a hint for manual follow-up; any other non-zero exit is still reported as INVALID with the first error line.
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 fünf 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!)
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.
./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.
./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 |
./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.
./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
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
./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
./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
# 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_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-Csicher 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_files.sh |
Website | -n Dry-Run erzwingen · -f <datei> Pfadliste (ohne Angabe interaktiv abgefragt) |
-h zeigt bei jedem Script die ausführliche Hilfe.