Einstellungen -> "Sicherungen holen": die fertigen Archive mit Datum, Groesse
und einem Knopf. Der erste Schritt, der eine Kopie VON DIESEM RECHNER HERUNTER
bringt -- bisher haette man sich dafuer per Fernwartung auf den Server klicken
muessen, und genau daran hat es gelegen. Nicht Unwille, sondern
Umstaendlichkeit.
Der Ordner haengt NUR LESEND in den Container. Ein Dienst, der seine eigenen
Sicherungen loeschen kann, ist genau das Werkzeug, das man einem uebernommenen
Dienst nicht in die Hand geben will. Nachgemessen im Container:
touch /sicherungen/probe -> Read-only file system
Und es gibt NUR EINE FORM VON NAMEN -- nicht "alles ausser .. und /", sondern
ein Muster, das genau auf die eigenen Archive passt. Wer einen Pfad
hineinschmuggeln will, muesste ihn erst so benennen. Das ist der Unterschied
zwischen dicht gemacht und dicht gebaut:
../../etc/passwd -> 404
..%2f..%2fdata%2fmedia.db -> 400
media.db -> 400
<archiv>.tar.gz.evil -> 400
ohne Anmeldung -> 401
Der ganze Weg einmal wirklich gegangen, nicht nur die Kopfzeilen: 336 MB in
15,9 s durch den Proxy, sha256 auf der Platte gleich sha256 heruntergeladen,
tar tzf zeigt 4639 Eintraege. Gestroemt und nicht in den Speicher gelesen --
sonst haetten Dienst UND Proxy die 336 MB gleichzeitig im Arbeitsspeicher.
Jeder Griff steht im Verwaltungs-Verlauf. Geloggt wird der GRIFF und nicht der
Erfolg: ein abgebrochener Download taucht ebenfalls auf, und das ist gewollt --
wer spaeter fragt, wer sich den Bestand geholt hat, will die Anfrage sehen.
Die fuenf neuen Pruefungen sind in tools/rundgang.py mit drin; der steht jetzt
bei 29 in Ordnung, 0 nicht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
254 lines
11 KiB
Markdown
254 lines
11 KiB
Markdown
# Was noch ginge
|
||
|
||
Stand 12.08.2026. Diese Liste ist **nicht** eine Sammlung von allem, was
|
||
denkbar wäre — sie ist das, was beim Bauen und Messen wirklich aufgefallen ist.
|
||
Was hier steht, hat einen Grund; was keinen hatte, steht am Ende unter
|
||
„Verworfen, mit Begründung".
|
||
|
||
Sortiert nach dem, was ich zuerst täte.
|
||
|
||
---
|
||
|
||
## 1 · Sicher wertvoll
|
||
|
||
### ~~Die Oberfläche auf dem Telefon~~ — abgelehnt am 12.08.2026
|
||
|
||
> Vom Betreiber verworfen: das Dashboard wird nicht mobil benutzt. Der Rest des
|
||
> Abschnitts bleibt stehen, damit die Messung nicht verlorengeht, falls sich das
|
||
> je ändert.
|
||
|
||
**Gemessen:** 18 Umbruchpunkte (`sm:`/`lg:`/`xl:`) im ganzen Frontend. Die
|
||
Galerie ist ein Raster und passt sich an — die **vier Tabellen** in Verlauf,
|
||
Token, Konten und Papierkorb nicht. Auf einem Telefon laufen sie seitlich
|
||
heraus.
|
||
|
||
Der Umbau ist keine Kosmetik: Karten statt Tabellenzeilen unterhalb einer
|
||
Breite, so wie es die Galerie schon macht. Betrifft vier Dateien.
|
||
|
||
**Lohnt sich nur, wenn du das Dashboard mobil aufmachst.** Sonst ist es
|
||
Arbeit für einen Bildschirm, den niemand benutzt.
|
||
|
||
### Sitzungen beenden können
|
||
|
||
**Gemessen:** 86 offene Sitzungen, davon 82 von `admin` — meine Testanmeldungen
|
||
von heute. Sie laufen nach 30 Tagen aus, und `pruneSessions` räumt stündlich
|
||
die abgelaufenen weg. Was fehlt, ist ein Knopf **„alle anderen Sitzungen
|
||
beenden"** im Kontomenü.
|
||
|
||
Das ist mehr als Ordnung: wer sich an einem fremden Rechner angemeldet hat und
|
||
es später merkt, hat heute keine Möglichkeit, das zurückzunehmen — außer das
|
||
Passwort zu ändern und zu hoffen, dass das die Sitzungen mitnimmt (tut es
|
||
nicht, sie hängen an einer eigenen Tabelle).
|
||
|
||
### Was der Verlauf nicht sieht
|
||
|
||
**Gemessen:** `events` kennt `upload`, `replace`, `delete`, `move`, `rename` —
|
||
alles über **Dateien**. Nichts über **Einstellungen**. Wer den Discord-Webhook
|
||
geändert hat, wer einen Token angelegt oder gelöscht hat, wer ein Konto
|
||
entfernt hat: steht nirgends.
|
||
|
||
Bei zwei Konten ist das verschmerzbar. Sobald ein drittes dazukommt — und über
|
||
die Discord-Rolle entsteht es von selbst — ist es die erste Frage, die man
|
||
stellt, wenn etwas anders ist als gestern.
|
||
|
||
---
|
||
|
||
## 2 · Nützlich, wenn der Fall eintritt
|
||
|
||
### Massen-Umbenennen
|
||
|
||
Suchen und Ersetzen über Pfade, mit Vorschau vor dem Zuschlagen. Bei 3578 Items
|
||
ist eine Umbenennung von Hand keine.
|
||
|
||
Der Anlass wäre etwa: `items/` nach `inventar/` verschieben, oder eine
|
||
Namenskonvention ändern. Heute geht das nur Datei für Datei oder gar nicht.
|
||
|
||
**Die Warnung wäre dieselbe wie beim Ordner-Umbenennen** — jede alte Adresse
|
||
gibt danach 404 —, nur mal tausend.
|
||
|
||
### Bilder beim Ablegen verkleinern
|
||
|
||
Eine Obergrenze für die Kantenlänge, einstellbar je Token. Wer ein 6000 × 4000
|
||
großes Foto hochlädt, bekommt es auf, sagen wir, 2048 gerechnet.
|
||
|
||
**Gemessen und deshalb keine Dringlichkeit:** ein 12000 × 12000 großes PNG hat
|
||
den Dienst *nicht* in Verlegenheit gebracht — Vorschau in 374 ms, Speicher bei
|
||
47 MB von 31 GB. libvips arbeitet kachelweise und dekodiert nie das ganze Bild.
|
||
Es geht also um Plattenplatz und Ladezeit beim Ausliefern, nicht um Stabilität.
|
||
|
||
### Fehlende Bilder finden
|
||
|
||
Eine Liste hereinreichen (Fahrzeugmodelle, Item-Namen) und beantwortet
|
||
bekommen: **wozu fehlt ein Bild?** Heute beantwortet das niemand — das
|
||
Fotostudio weiß, was es aufgenommen hat, der Dienst weiß, was liegt, und die
|
||
Differenz rechnet niemand aus.
|
||
|
||
Das wäre ein Endpunkt, der eine Liste entgegennimmt und die fehlenden
|
||
zurückgibt. Klein, und die Antwort auf „warum zeigt das Handy bei manchen
|
||
Autos kein Bild".
|
||
|
||
### Einstellungen aus- und einlesen
|
||
|
||
Discord-Zugang, Sicherungsziel, Vorlagen, Meldungsanlässe — alles steht in
|
||
`settings` und ist beim Neuaufsetzen von Hand nachzutragen. Ein Export als JSON
|
||
(**ohne** die Geheimnisse, oder mit einer ausdrücklichen Ansage) macht aus
|
||
einer Stunde Klickerei fünf Minuten.
|
||
|
||
---
|
||
|
||
## 3 · Wäre schön, drängt nicht
|
||
|
||
### ~~Verlauf als CSV~~ — gebaut am 12.08.2026
|
||
|
||
`GET /api/dash/verlauf/export`, wahlweise `?was=verwaltung`. Der Knopf sitzt in
|
||
der Reiterleiste und holt **den Verlauf, der gerade offen ist** — zwei Knöpfe
|
||
nebeneinander wären die Frage „welchen von beiden?" an einer Stelle, wo die
|
||
Antwort schon auf dem Bildschirm steht.
|
||
|
||
Semikolon und CRLF wie beim Bestands-Export, und aus demselben Grund: Excel in
|
||
deutscher Einstellung nimmt bei Komma alles in eine Spalte und bei nacktem LF
|
||
die halbe Datei in eine Zelle. Gemessen an der ausgelieferten Datei: 5364
|
||
Zeilen, 5364 CRLF, **kein einziges nacktes LF**.
|
||
|
||
### ~~Meldung bei Upload~~ — gebaut am 12.08.2026
|
||
|
||
Mit Drossel, und die ist der eigentliche Inhalt. Jeder Upload schiebt eine
|
||
Frist von zwei Minuten nach hinten; erst nach der Ruhe geht **eine** Nachricht
|
||
raus, mit Anzahl, Summe, Absendern und den ersten fünf Pfaden.
|
||
|
||
Ohne das wäre die Funktion ein Schaden statt eines Nutzens: 900 Fahrzeugbilder
|
||
ergäben 900 Nachrichten, Discord drosselt Webhooks, und wer danach eine echte
|
||
Meldung bekommt, sieht sie nicht mehr. Ein Serienlauf ergibt jetzt eine Zeile,
|
||
ein einzelnes Bildschirmfoto ergibt eine Zeile — beide sagen dasselbe, nur mit
|
||
anderen Zahlen.
|
||
|
||
Der Anlass heißt `upload` und ist **abschaltbar wie die anderen drei**. Die
|
||
Liste steht an zwei Stellen (Server und Oberfläche) — genau die Verdopplung,
|
||
die bei `platte` schon einmal ein Kreuzchen verschluckt hat; deshalb steht
|
||
jetzt in beiden ein Verweis auf die andere. Nachgemessen: vier geschickt, vier
|
||
gespeichert.
|
||
|
||
### ~~Papierkorb mit Größendeckel~~ — gebaut am 12.08.2026
|
||
|
||
20 GB. Beim Ausleeren wird erst nach Alter geräumt (30 Tage) und dann nach
|
||
Größe, **das Älteste zuerst** — dessen Versehen wäre am ehesten schon
|
||
aufgefallen. Die Grenze steht in der Antwort von `/api/dash/papierkorb`, damit
|
||
die Oberfläche sie nicht ein zweites Mal hinschreibt.
|
||
|
||
Bei 910 GB frei ist das heute keine Grenze, sondern eine Zusicherung: der
|
||
Papierkorb kann nicht mehr unbemerkt zur zweiten Ablage werden.
|
||
|
||
### Ein Ziel AUSSERHALB dieser Maschine — offen, aber der Weg steht fest
|
||
|
||
Nachgemessen am 12.08.2026: **es verlässt heute nichts diesen Rechner.** Auch
|
||
die Nextcloud nicht — sie läuft hier, in denselben Docker-Volumes, auf derselben
|
||
Platte 0 wie die Daten. Details in der ROADMAP.
|
||
|
||
**Wo dieser Rechner steht, ist dabei der entscheidende Punkt**, und er ist mir
|
||
zuerst durchgerutscht: es ist ein Windows-Root-Server **im Rechenzentrum**. Der
|
||
Betreiber sitzt zu Hause und ist per mRemoteNG verbunden. Das dreht die
|
||
Bewertung um — eine Platte zu Hause ist nicht „dasselbe Haus", sondern zwei
|
||
Gebäude, zwei Netze, zwei Stromkreise, zwei Anbieter. Besser wird ein
|
||
Sicherungsziel kaum.
|
||
|
||
| Weg | deckt ab | Haken |
|
||
|---|---|---|
|
||
| **Rechner zu Hause holt ab** | Platte, Rechner, Rechenzentrum, übernommener Server | muss laufen, wenn geholt wird |
|
||
| **5-TB-Platte am Router**, vom Heimrechner beschrieben | dasselbe | Router-USB ist langsam; für 337 MB je Nacht reicht es |
|
||
| **Discord-Kanal** (nur der Bot) | dasselbe | 9 MB je Datei — für d4rk_media mit 336 MB unbrauchbar |
|
||
| 5-TB-Platte **am Server** | nur Plattenausfall | dritte Platte im selben Gehäuse — `D:` kann das schon |
|
||
|
||
### Der erste Schritt ist gemacht: von Hand holen
|
||
|
||
Einstellungen → **Sicherungen holen** listet die Archive und gibt sie heraus
|
||
(nur lesend eingehängt, Namensmuster statt Filter, jeder Griff im
|
||
Verwaltungs-Verlauf). Das ersetzt keine geplante Abholung — aber es macht die
|
||
Auswärtskopie zu etwas, das man im Vorbeigehen erledigt, statt zu einem
|
||
Vorhaben. Was noch fehlt, ist, dass es **von allein** passiert.
|
||
|
||
### Warum HOLEN und nicht SCHICKEN
|
||
|
||
Ein Ziel, in das der Server selbst schreiben darf, ist auch eines, das ein
|
||
übernommener Server löschen kann. Wer vom anderen Ende abholt, hält **keine
|
||
Zugangsdaten auf der Maschine, die geschützt werden soll**. Das ist der eine
|
||
Unterschied, der im Ernstfall zählt.
|
||
|
||
### Was dafür schon dasteht
|
||
|
||
```
|
||
sshd Running, Automatic, lauscht auf 0.0.0.0:22 und [::]:22
|
||
Firewall "OpenSSH SSH Server (sshd)" -> Allow
|
||
sshd_config Subsystem sftp sftp-server.exe
|
||
AllowGroups administrators "openssh users" sshusers
|
||
AuthorizedKeysFile .ssh/authorized_keys
|
||
je Nacht d4rk_media 335,9 MB + d4rkbot 0,9 MB = 336,9 MB
|
||
```
|
||
|
||
**Auf der Serverseite fehlt also nichts** außer einem Konto, das nur lesen darf.
|
||
Der Rest ist ein Skript auf dem Heimrechner, das per SFTP zieht und N Stände
|
||
behält.
|
||
|
||
### Ein Fund am Rande, der dazugehört
|
||
|
||
In `sshd_config` steht **kein** `PasswordAuthentication no`. Der Standard von
|
||
OpenSSH ist `yes` — auf Port 22, offen ins Internet, auf einem Server, dessen
|
||
`AllowGroups` die **Administratoren** einschließt. Wer ohnehin ein
|
||
Sicherungskonto mit Schlüssel anlegt, sollte bei der Gelegenheit auf
|
||
Schlüssel-only umstellen.
|
||
|
||
---
|
||
|
||
### ~~Mehrere Sicherungsziele~~ — gebaut am 12.08.2026
|
||
|
||
Ein **zweites Laufwerk**, einstellbar im Panel unter Einstellungen → Sicherung.
|
||
Damit liegt jedes Archiv an drei Orten: `C:ackup`, das zweite Laufwerk und
|
||
die Nextcloud.
|
||
|
||
Die drei sind nicht dreimal dasselbe. Die Nextcloud hilft, wenn der ganze
|
||
Rechner weg ist — aber wer 335 MB (oder später 100 GB) zurückholen muss, lädt
|
||
sie über die Leitung. Das zweite Laufwerk ist in Minuten zurückgespielt.
|
||
|
||
**Und es warnt, wenn es dieselbe Platte ist.** Das ist der eigentliche Inhalt:
|
||
ein zweiter Ordner auf C: sieht im Panel genauso grün aus wie eine echte zweite
|
||
Platte und hilft gegen gar nichts. Verglichen wird die *physische* Platte, nicht
|
||
der Laufwerksbuchstabe — zwei Partitionen derselben NVMe sterben zusammen.
|
||
Nachgemessen in beide Richtungen: `C:` gegen `D:` ergibt Nr. 0 gegen Nr. 1 und
|
||
ein „andere Platte"; `C:` gegen `C:` ergibt zweimal Nr. 0 und die Warnung.
|
||
|
||
Ein echter Lauf: 4630 Einträge, 335,9 MB, auf beiden Zielen die Prüfsumme
|
||
`FFCE4D0A7310…` — identisch. Die Statusseite sagt seitdem
|
||
`sicherung ok an 3 Orten` statt nur `ok`.
|
||
|
||
---
|
||
|
||
## Verworfen, mit Begründung
|
||
|
||
Diese standen auf der Liste und sind **gemessen** wieder heruntergefallen. Sie
|
||
stehen hier, damit sie nicht beim nächsten Mal wieder aufschlagen.
|
||
|
||
| Idee | Warum nicht |
|
||
|---|---|
|
||
| Doppelte Dateien zusammenführen | 5 Gruppen, **0,0 MB** verschwendet. Es gibt nichts zu holen. |
|
||
| Aufräumen nach Alter | Alle vier Altersstufen im Bericht stehen auf **0 Dateien**. Es ist nichts alt. |
|
||
| Grenze für Bildmaße als *Schutz* | 12000 × 12000 → 374 ms, 47 MB. libvips streamt, die Gefahr gibt es nicht. |
|
||
| Plattenplatz-Wächter | **Gebaut.** 80/90/95 %, meldet nach Discord. |
|
||
| Kontingent je Token | **Gebaut**, auf beiden Upload-Wegen geprüft. |
|
||
| Eigene Statusseite bauen | `/status` reicht — der d4rkbot zeigt sie schon an. |
|
||
|
||
---
|
||
|
||
## Und was heute noch schnell repariert wurde
|
||
|
||
**`pruneEvents` lief nie von selbst.** Die Funktion gibt es seit dem ersten Tag
|
||
und sie räumt Ereignisse älter als 180 Tage weg — aufgerufen wurde sie aber nur
|
||
von `/maintenance/prune-sessions`, einem Weg, den nicht einmal die Oberfläche
|
||
anbietet. Die dokumentierte Aufbewahrung griff damit **nie**, und die Tabelle
|
||
wuchs für immer.
|
||
|
||
Zum Vergleich: `pruneSessions` hängt seit jeher an einem stündlichen Takt. Das
|
||
eine war verdrahtet, das andere nicht, und der Unterschied fiel niemandem auf,
|
||
weil beide in derselben Zeile stehen.
|
||
|
||
Gemessen: nach **einem** Tag mit Umzug und Serienlauf standen 5355 Zeilen in
|
||
`events`. Läuft jetzt täglich, mit zwei Minuten Verzögerung nach dem Start.
|