Archive stale documentation
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# AI Handoff 2026-05-06
|
||||
|
||||
Kompakte Quelle fuer einen neuen Chat. Ziel: nicht das ganze Repo neu auditieren, sondern mit dem bekannten Stand weiterarbeiten.
|
||||
|
||||
## Aktueller Stand
|
||||
|
||||
- Repo: `G:\Gitea_Clone\homelab-infra`
|
||||
- Remote: `https://git.kaleschke.info/Micha/homelab-infra.git`
|
||||
- Branch: `master`
|
||||
- Letzter bekannter Commit: `e0e12f1 Document stale Komodo webhook cleanup`
|
||||
- Unraid-Host: `ssh root@192.168.178.58`
|
||||
- Push-Befehl, der zuverlaessig funktioniert: `git -C "G:\Gitea_Clone\homelab-infra" push origin master`
|
||||
- Nicht anfassen ohne explizite Freigabe: untracked `Homelab_Audit_2026-05-05.pdf` und untracked `ops/hermes-agent/services.yaml`.
|
||||
|
||||
## Audit-Arbeit Erledigt
|
||||
|
||||
- K1: ungueltige Digests fuer Authelia, ntfy und borg-ui korrigiert und smoke-getestet.
|
||||
- K2: Authelia nutzt bewusst kein Redis; Doku entsprechend korrigiert.
|
||||
- K3/M1/M2 alt: Authelia Repo-Baseline geklaert, Homepage/Komodo ACL-Drift bereinigt.
|
||||
- M3a/M3b: Digest-Pinning fuer stateful/Tier-1 und weitere versionierte Apps umgesetzt; Redis-Caches bewusst ohne Digest, Nextcloud bewusst offen.
|
||||
- M5/N5: `.gitignore` eingefuehrt, Hermes `stack.env` zu `stack.env.example`.
|
||||
- M6/M7/M8: Hermes-Domain, Grafana/Influx `user: "0"` und Tailscale-Capabilities dokumentiert.
|
||||
- M9: Backup Scope / Restore Matrix erledigt.
|
||||
- N-Aufraeumen: alte Compose-`version:` Felder, leere Env-Beispiele und `.keep`-Platzhalter bereinigt.
|
||||
- Mail Archiver: `mail.kaleschke.info` liegt hinter `authelia@file,secure-headers@file`; Smoke-Test war 302 zu Authelia.
|
||||
- Hermes: Restore/DR-Doku ergaenzt.
|
||||
- Authelia SMTP: GMX SMTP eingerichtet, validiert, deployed und smoke-getestet.
|
||||
- M10: `KOMODO_WEBHOOK_SECRET` ist von `KOMODO_SECRET_KEY` getrennt.
|
||||
|
||||
## Wichtige Runtime-Details
|
||||
|
||||
### Authelia SMTP
|
||||
|
||||
- Adresse: `submission://mail.gmx.net:587`
|
||||
- Mailkonto: `michideheld@gmx.de`
|
||||
- SMTP-Passwort liegt nur auf dem Host: `/mnt/user/appdata/secrets/authelia_smtp_password.txt`
|
||||
- Host-Config wurde vor Umstellung gesichert: `/mnt/user/appdata/authelia/config/configuration.yml.bak-20260506-smtp`
|
||||
- Authelia-Compose nutzt explizite DNS-Server, weil der SMTP-Startup-Check externe Namen aufloesen muss.
|
||||
- Nach Deploy war `authelia` healthy; `auth.kaleschke.info` antwortete 200, geschuetzte Routen 302 zu Authelia.
|
||||
|
||||
### Komodo / M10
|
||||
|
||||
- Komodo-Runtime nur gemeinsam mit dem Betreiber aendern.
|
||||
- `KOMODO_SECRET_KEY` wurde nicht geaendert.
|
||||
- `KOMODO_WEBHOOK_SECRET` wurde geaendert und ist jetzt eigener 64-Zeichen-Wert.
|
||||
- Neuer Wert liegt nur auf dem Host in `/mnt/user/services/stacks/komodo/.env`.
|
||||
- Komodo Compose auf Host: `/mnt/user/services/stacks/komodo/compose.yaml`.
|
||||
- Backups vom M10-Sprint:
|
||||
- `/mnt/user/appdata/komodo/_m10_backup_20260506-184838`
|
||||
- `/mnt/user/services/gitea/data/gitea/_m10_backup_20260506-184838/gitea.db.bak`
|
||||
- `komodo-core` wurde gezielt recreated.
|
||||
- `komodo-mongo` wurde nicht neu gestartet.
|
||||
- `komodo-periphery` lief durch und meldete sich wieder am Core-Websocket an.
|
||||
- Gitea-Komodo-Webhooks: 29 aktive Hooks, 29 zuletzt erfolgreich, 0 aktiv fehlgeschlagen.
|
||||
- Ein stale Gitea-Webhook auf eine nicht mehr existierende Komodo-Stack-ID wurde deaktiviert, nicht geloescht.
|
||||
- Eine Warnung `request branch does not match expected` ist ein Branch-Filter-Skip, kein Secret-/Auth-Fehler.
|
||||
- Fuer neue Gitea-Webhooks im Standardfall den globalen `KOMODO_WEBHOOK_SECRET` aus der Komodo-Host-`.env` nutzen, ausser Komodo zeigt fuer den Stack explizit ein eigenes per-Stack-Secret.
|
||||
|
||||
## Sicherheitsregeln Fuer Weitere Arbeit
|
||||
|
||||
- Keine Secret-Werte im Chat oder Git ausgeben.
|
||||
- Bei Host-Pruefungen nur SET/MISSING, Laengen und Pfade zeigen.
|
||||
- Komodo-Compose, Komodo-Secrets und Komodo-Runtime nur bewusst und kleinschrittig aendern.
|
||||
- Bei jedem Deploy pro Stack smoke-testen; nicht mehrere kritische Stacks parallel veraendern.
|
||||
- Untracked Dateien nicht automatisch committen.
|
||||
- Bei Authelia-Aenderungen: Host-Config sichern, `authelia validate-config` ausfuehren, dann erst neu starten.
|
||||
- Bei Komodo-Aenderungen: Gitea-Webhooks und Komodo-Core-Secret-Seite zusammen betrachten.
|
||||
|
||||
## Naechste Sinnvolle Next-Level-Themen
|
||||
|
||||
- Grafana/Influx rootless betreiben statt `user: "0"`; eigener Sprint wegen Volume-Rechten.
|
||||
- Restore-Test fuer Vaultwarden und Paperless dokumentiert durchfuehren.
|
||||
- Komodo Periphery von Legacy-Passkey auf Public-Key-Modell haerten.
|
||||
- Monitoring/Alerting reifer machen: externe Alarme, Restore-Test-Reminder, Backup-Erfolg sichtbar.
|
||||
- Gitea/Komodo Webhook-Landschaft weiter aufraeumen und per-Stack-Secret-Strategie dokumentieren.
|
||||
- DR-Test fuer `backend_net`/externe Docker-Netze explizit aufnehmen.
|
||||
|
||||
## Startprompt Fuer Neuen Chat
|
||||
|
||||
Bitte zuerst `docs/archive/2026-05/AI_HANDOFF_2026-05-06.md` lesen und als aktuelle Arbeitsquelle verwenden. Nicht das ganze Repo neu auditieren, ausser ich fordere es an. Beachte besonders: Komodo nur gemeinsam und kleinschrittig aendern, keine Secret-Werte ausgeben, untracked PDF und `ops/hermes-agent/services.yaml` nicht anfassen. Wir starten jetzt mit Next-Level-Hardening.
|
||||
@@ -0,0 +1,369 @@
|
||||
# Homelab Audit - 2026-05-23
|
||||
|
||||
Stand: 2026-05-23, repo-basiert. Erstellt nach `docs/WORKFLOW.md` und `docs/GITOPS_DRIFT_RUNBOOK.md`. Quellebasis: `origin/master` plus lokaler Clone, ohne Schreibbefehle, ohne Deploy.
|
||||
|
||||
Dieser Audit ist eine punktuelle Sollzustands-Bewertung, kein Live-Status. Die Live-Verifikations-Schritte stehen am Ende in Abschnitt 9; alle dortigen Outputs ersetzen Vermutungen durch Messwerte.
|
||||
|
||||
## 0. Executive Summary
|
||||
|
||||
Ampel-Bewertung pro Bereich:
|
||||
|
||||
| Bereich | Ampel | Kernaussage |
|
||||
|---|---|---|
|
||||
| GitOps-Konsistenz (lokal/Gitea) | 🟡 | Lokaler Clone ist **1 Commit voraus** auf `master` (`cd650b1`, Haertungs-Commit). Bis zum Push existiert dieser Stand nur lokal, nicht in Gitea — bei einem Clone-Verlust ist er weg. |
|
||||
| GitOps-Konsistenz (Working Tree) | 🟢* | Keine echten Inhaltsaenderungen offen. Die 47 "modified files" aus `git status` im Linux-Mount sind voraussichtlich CRLF/LF-Mount-Artefakte (durch `git diff -w --stat` auf Stichprobe bestaetigt leer). Bitte am Windows-Host gegenpruefen. |
|
||||
| Hardening-Sprint (Mai 2026) | 🟢 | Alle vier Post-Restore-Sprint-Items sind im Repo umgesetzt (Filebrowser-Mounts, Authelia Argon2id, Gitea Webhook-Allowlist, Backup-Dump-Konsistenz). |
|
||||
| Backup/Restore-Readiness | 🟢 | `pre-backup-dumps.sh` deckt alle relevanten SQLite/PostgreSQL/Mongo-Quellen ab. Borg-UI-Scope umfasst `/mnt/user/services`, `homelab-infra`, `stacks`, `posture-check`. Live-Frische ist offen (Abschnitt 9). |
|
||||
| Monitoring-Migration | 🟡 | `monitoring/` Stack im Repo komplett, aber Live-Deploy laut `docs/archive/2026-05/NEXT_SPRINT_TODO_2026-05-16.md` noch ausstehend. Alte Stacks `ops/grafana-influxdb` und `ops/loki` sollen erst nach Live-Smoke-Test gestoppt werden. |
|
||||
| Doku-Drift Repo vs. Master-Doku | 🟠 | `apps/jellyfin/`, `host-services/plex/` und einige andere existieren produktiv als Compose-Stacks, sind aber in `HOMELAB_ARCHITECTURE_MASTER_V2.md`, `docs/SERVICE_CATALOG.md` und `docs/REPO_MAP.md` **nicht aufgefuehrt**. Authelia-ACL kennt `jellyfin.kaleschke.info` als bypass, im Masterdoku-Hostkatalog steht es nicht. |
|
||||
| Repo-Hygiene | 🟡 | 8 leere Verzeichnisse im Working Tree (siehe 4.3). `.serena/` ist untracked und nicht in `.gitignore`. Drei `ops/windows-reinstall/*.ps1` sind untracked. |
|
||||
| Bekannte Ausnahmen | 🟢 | Alle Ausnahmen aus `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 10 sind weiterhin dokumentiert und durch den Policy-Check abgedeckt (0 Critical, 4 Warnings, 9 Info – alles dokumentierte Ausnahmen). |
|
||||
|
||||
**Kernfazit:** Das Homelab ist sehr nah an der "Endstufe". Es gibt keine kritischen Befunde. Die einzige Pflichtaktion vor dem naechsten geplanten Schritt ist der **Push des lokalen Commits `cd650b1` nach Gitea**, damit `origin/master` wieder die Quelle der Wahrheit ist. Danach sind nur noch zwei priorisierte Pakete offen: Monitoring-Stack live finalisieren und Doku auf den Stand der neuen Stacks (Jellyfin/Plex/...) nachziehen.
|
||||
|
||||
---
|
||||
|
||||
## 1. Methodik und Quellen
|
||||
|
||||
Diese Audit-Quellen wurden gelesen (repo-seitig):
|
||||
|
||||
- `HOMELAB_ARCHITECTURE_MASTER_V2.md`
|
||||
- `docs/WORKFLOW.md`
|
||||
- `docs/REPO_MAP.md`
|
||||
- `docs/SERVICE_CATALOG.md`
|
||||
- `docs/RESTORE_MATRIX.md`
|
||||
- `docs/GITOPS_DRIFT_RUNBOOK.md`
|
||||
- `docs/archive/2026-05/NEXT_SPRINT_TODO_2026-05-16.md`
|
||||
- `ops/borg-ui/scripts/pre-backup-dumps.sh`
|
||||
- `ops/borg-ui/docker-compose.yml`
|
||||
- `ops/borg-ui/all-important-sources.txt`
|
||||
- `ops/filebrowser/docker-compose.yml`
|
||||
- `security/authelia/configuration.yml`
|
||||
- `core/gitea/docker-compose.yml`
|
||||
- `apps/jellyfin/docker-compose.yml`
|
||||
- `host-services/plex/docker-compose.yml`
|
||||
- `ops/policy-checks/last-report.md`
|
||||
|
||||
Schreibbefehle: keine. Deploys: keine. Containerlaufzeit, Komodo-Webhook-Status, Borg-Lauf-Frische und Host-Listener wurden bewusst nicht angetastet — dafuer steht der Live-Daten-Block in Abschnitt 9.
|
||||
|
||||
---
|
||||
|
||||
## 2. Schicht A — GitOps und Konsistenz
|
||||
|
||||
### 2.1 Lokaler Clone vs. `origin/master`
|
||||
|
||||
```
|
||||
## master...origin/master [ahead 1]
|
||||
HEAD = cd650b19ac057a1b74ac63503e5dba50eaf5b8ea
|
||||
origin/master = af231dd4e835b19005cc0842509199d480af00d9
|
||||
```
|
||||
|
||||
- **Befund:** Lokaler Clone ist 1 Commit voraus.
|
||||
- **Commit:** `cd650b1 Close Gitea signup, dedup posture-check alerts, extend Borg scope` (Sat May 23 11:01:24 2026 +0200).
|
||||
- **Inhalt** (laut Commit-Message und betroffenen Dateien):
|
||||
- Gitea: `DISABLE_REGISTRATION=true`, `ENABLE_OPENID_SIGNIN=false`, `ENABLE_OPENID_SIGNUP=false`
|
||||
- Repo-Pflicht-Doku ergaenzt: Komodo-Stack-Webhook-Pflicht in `CLAUDE.md`, `AI_CONTEXT.md`, `WORKFLOW.md`
|
||||
- `posture-check.sh`: Disk1-NTFS-Funktion ausgelagert, Inode-Check auf NTFS uebersprungen, ntfy-Dedup via Fingerprint-State + `ALERT_REPEAT_SECONDS`
|
||||
- `docker-critical-events.sh`: JSON-Parsing, `die exit=0` gefiltert, strukturierte ntfy-Message
|
||||
- `borg-ui`: `/mnt/user/services` als `/local/services:ro` gemountet, `all-important-sources.txt` ergaenzt
|
||||
- Unraid User Scripts dokumentiert (daily report)
|
||||
- `MIGRATION_LOG.md`, `RESTORE_MATRIX.md`, `DISASTER_RECOVERY.md` aktualisiert
|
||||
- **Risiko:** Bei Verlust des Windows-Clones (Reinstall, Diskcrash) ist dieser Stand verloren, weil er nicht in Gitea liegt. Komodo deployt ausserdem aus Gitea und kennt diese Aenderungen noch nicht.
|
||||
- **Empfohlene Aktion (Pflicht vor weiterer Arbeit):** In GitHub Desktop `Push origin` ausfuehren. Danach Komodo-Reaktion fuer die betroffenen Stacks (`gitea`, `borg-ui`) pruefen und Smoke-Tests laufen lassen.
|
||||
|
||||
### 2.2 Working-Tree-Status
|
||||
|
||||
```
|
||||
$ git status --short
|
||||
M CLAUDE.md
|
||||
M HOMELAB_ARCHITECTURE_MASTER_V2.md
|
||||
M apps/homepage/docker-compose.yml
|
||||
...
|
||||
(47 Dateien als modified gemeldet, plus 4 Untracked)
|
||||
```
|
||||
|
||||
- **Bewertung:** Die 47 "modified files" sind mit hoher Wahrscheinlichkeit **Mount-Artefakte** durch CRLF/LF zwischen Windows-Clone und Linux-Mount. Stichprobe `git diff -w --stat CLAUDE.md HOMELAB_ARCHITECTURE_MASTER_V2.md` lieferte leer — d. h. keine inhaltlichen Diffs.
|
||||
- **Aktion:** Bitte am Windows-Host in GitHub Desktop `git status --short` ausfuehren. Wenn dort der Tree leer ist (nur die 4 Untracked), gibt es keinen echten Working-Tree-Drift. Wenn dort echte Diffs erscheinen, hier bitte zurueckmelden — dann ist das ein eigener Befund.
|
||||
- **Optional (nicht Pflicht):** `.gitattributes` mit `* text=auto eol=lf` haerten, damit dieser Mount-Effekt fuer KI-Audits aus dem Weg geht. Das ist ein eigener kleiner Commit, kein Audit-Output.
|
||||
|
||||
### 2.3 Untracked Files
|
||||
|
||||
```
|
||||
?? .serena/
|
||||
?? ops/windows-reinstall/backup-delta-after-2026-05-07.ps1
|
||||
?? ops/windows-reinstall/cleanup-dualboot-bcd.ps1
|
||||
?? ops/windows-reinstall/repair-disk0-boot-to-new-windows.ps1
|
||||
```
|
||||
|
||||
- `.serena/` ist das Working-Directory des Serena Code-Search-Tools. Hat eigene `.gitignore` intern, aber das `.serena/`-Verzeichnis selbst ist nicht in der Repo-`.gitignore`.
|
||||
- **Aktion (klein):** `.serena/` in `.gitignore` aufnehmen, damit es nicht versehentlich committet wird.
|
||||
- Die drei PowerShell-Scripts unter `ops/windows-reinstall/` sind Windows-Reinstall-Helfer. Entscheidung offen: ins Repo aufnehmen (mit Kontextkommentar warum sie dort liegen) oder lokal halten und in `.gitignore` aufnehmen. Vorschlag: aufnehmen, weil `ops/` der dokumentierte Ort fuer Ops-Skripte ist.
|
||||
|
||||
### 2.4 Letzte Commit-Historie (Top 10)
|
||||
|
||||
```
|
||||
cd650b1 Close Gitea signup, dedup posture-check alerts, extend Borg scope [LOKAL, NICHT GEPUSHT]
|
||||
af231dd Fix zero-count noise pattern handling
|
||||
428223d Mark posture report scripts executable
|
||||
b6d3ed4 Tune homelab availability alerts
|
||||
9e7bebb Add daily operations report with hardened log-noise filtering
|
||||
b7cbbe5 Fix Jellyfin external DNS
|
||||
71ac18b Fix Jellyfin native auth routing
|
||||
90f270b Fix Jellyfin config permissions
|
||||
e28f8da Add Jellyfin media server stack
|
||||
edfec5b Add Plex media server stack
|
||||
```
|
||||
|
||||
- Die letzten Tage waren sichtbar: Jellyfin/Plex hinzugefuegt, Availability-Alerts feinjustiert, Posture-Check-Skripte produktiv gemacht, dann der grosse Haertungs-Commit gestern (2026-05-23 11:01).
|
||||
|
||||
### 2.5 Compose-Inventar vs. Doku
|
||||
|
||||
Repo hat folgende Compose-Stacks, die in den Doku-Quellen (`HOMELAB_ARCHITECTURE_MASTER_V2.md`, `docs/SERVICE_CATALOG.md`, `docs/REPO_MAP.md`) **nicht oder nur teilweise** aufgefuehrt sind:
|
||||
|
||||
| Stack | Status im Repo | Status in Master-Doku |
|
||||
|---|---|---|
|
||||
| `apps/jellyfin/docker-compose.yml` | produktiv vorhanden, gepinnt `jellyfin:10.11.8@sha256:...`, Traefik `jellyfin.kaleschke.info`, `secure-headers@file`, native Auth, `/mnt/user/media:ro` + `/mnt/user/photos:ro` | **fehlt** in 7.4 Apps; Authelia-ACL kennt aber bereits `jellyfin.kaleschke.info` als bypass — Doku hinkt hinterher |
|
||||
| `host-services/plex/docker-compose.yml` | produktiv vorhanden, gepinnt `plexinc/pms-docker:1.43.1.10611-1e34174b1@sha256:...`, `network_mode: host`, `/mnt/user/media:ro` + `/mnt/user/photos:ro` | Master-Doku sagt explizit "Plex-Media-Server ist historischer Host-Sonderfall, nicht als Repo-Compose-Stack enthalten" — **das stimmt nicht mehr**, Plex ist jetzt ein Repo-Compose-Stack |
|
||||
| `host-services/docker/` | leeres Verzeichnis | nicht erwaehnt |
|
||||
| `infra/dns/` | leeres Verzeichnis | nicht erwaehnt |
|
||||
| `ops/Semaphore/` | Skripten/Playbooks aber kein Compose | nicht erwaehnt |
|
||||
| `ops/backrest/` | leeres Verzeichnis (Stack laut Master-Doku am 2026-05-15 entfernt) | korrekt als entfernt dokumentiert; Verzeichnis sollte leer bleiben oder weg |
|
||||
| `apps/firefly/`, `apps/firefly-fints/` | leere Verzeichnisse | nicht erwaehnt |
|
||||
| `apps/stirling-pdf/` | leeres Verzeichnis (durch `bentopdf` abgeloest) | korrekt als abgeloest dokumentiert |
|
||||
|
||||
- **Aktion (Doku-Synchronisierung):** `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 7 (Container-Zielbild), `docs/SERVICE_CATALOG.md` und `docs/REPO_MAP.md` um Jellyfin und Plex erweitern. Plex-Doku im Master umschreiben: nicht mehr "historisch ausserhalb Repo", sondern "Compose-Stack mit `network_mode: host` als VPN-Discovery-Ausnahme".
|
||||
- **Aktion (Repo-Hygiene):** Die leeren Verzeichnisse `apps/firefly`, `apps/firefly-fints`, `apps/stirling-pdf`, `host-services/docker`, `infra/dns`, `ops/backrest`, `ops/grafana-influxdb/scripts`, `ops/Semaphore/playbooks`, `ops/Semaphore/Scripts` aufraeumen — Master-Doku sagt: "Leere `.keep`-Platzhalter wurden entfernt; neue Verzeichnisse sollen erst mit konkretem Inhalt ins Repo." Diese Verzeichnisse verletzen diese Regel passiv.
|
||||
|
||||
### 2.6 Image-Pinning
|
||||
|
||||
Lt. `docs/archive/2026-05/NEXT_SPRINT_TODO_2026-05-16.md` sind diese Stacks noch nicht voll versioniert gepinnt:
|
||||
- `ddns-updater` — `latest...@sha256`
|
||||
- `glances` — `latest-full@sha256`
|
||||
- `scrutiny` — `latest-omnibus@sha256`
|
||||
|
||||
Das ist bewusst dokumentiert und kein Audit-Befund.
|
||||
|
||||
---
|
||||
|
||||
## 3. Schicht B — Hardening-Sprint 2026-05 (Sitrep)
|
||||
|
||||
Dies war der Sprint, der nach dem 2026-05 Restore explizit gesetzt wurde. Stand im Repo:
|
||||
|
||||
| Sprint-Item | Stand 2026-05-16 (Plan) | Stand 2026-05-23 (Repo) | Beleg |
|
||||
|---|---|---|---|
|
||||
| **(1) Backup-Konsistenz** — `dump_sqlite_container` fuer Gitea/Vaultwarden/Uptime-Kuma/Speedtest/Filebrowser + `pg_dump` Nextcloud | offen | ✅ erledigt | `ops/borg-ui/scripts/pre-backup-dumps.sh` Z. 97–139 (`dump_sqlite_container`), Z. 253–258 (Nextcloud `pg_dump`), Z. 261–264 (alle SQLite-Container mit Host-Fallback), Z. 267 (Filebrowser BoltDB). Borg-Scope erweitert um `/mnt/user/services` (Borg-UI Compose Z. 26 + `all-important-sources.txt` Z. 23–25). |
|
||||
| **(2) Filebrowser entschaerfen** — `/mnt/user/appdata:/srv/appdata` weg, gezielte RW-Subpfade | offen | ✅ erledigt | `ops/filebrowser/docker-compose.yml` Z. 11–16. Keine Appdata-Mounts mehr. Nur noch `/mnt/user/documents`, `/mnt/user/photos`, `/mnt/user/projekte` als Datenmounts plus eigener `/database` und `/config`. |
|
||||
| **(3) Authelia Argon2id haerten** — iterations 3, memory 65536, parallelism 4 | offen | ✅ erledigt | `security/authelia/configuration.yml` Z. 17–25. Exakt die geplanten Parameter sind aktiv. |
|
||||
| **(4) Gitea Webhook-Allowlist** — `ALLOWED_HOST_LIST=*` einschraenken | offen | ✅ erledigt | `core/gitea/docker-compose.yml` Z. 18: `GITEA__webhook__ALLOWED_HOST_LIST=komodo-core,localhost,127.0.0.1,192.168.178.0/24`. Zusatz aus heutigem Commit: Public Registration und OpenID-Signup/Signin sind deaktiviert. |
|
||||
|
||||
Alle vier Items sind **im Repo abgeschlossen**. Live-Wirksamkeit haengt am Komodo-Deploy aus Gitea — und genau da haengt aktuell der ungepushte Commit `cd650b1` davor (siehe 2.1). Solange er nicht in Gitea ist, ist insbesondere die Gitea-Signup-Schliessung im Live-Stand nicht garantiert.
|
||||
|
||||
**Bewusst nicht angefasste Liste (Operator-Entscheidung 2026-05-16) ist weiterhin gueltig:**
|
||||
- Hermes — bleibt VM-seitig offen, NAS-Stack bewusst nicht starten
|
||||
- Disk1 NTFS — Phase-2-Migration nach Plan
|
||||
- Komodo native Auth ohne ForwardAuth
|
||||
- Grafana/Influxdb3-core `user: "0"`
|
||||
- Image-Pinning-Vereinheitlichung (`:latest@sha256:`) fuer ddns-updater/glances/scrutiny
|
||||
|
||||
---
|
||||
|
||||
## 4. Schicht C — "Endstufe?"-Bewertung
|
||||
|
||||
### 4.1 Backup/Restore-Readiness
|
||||
|
||||
- **Dump-Coverage:** `pre-backup-dumps.sh` deckt 14 Quellen ab: PostgreSQL-Globals + 3 Shared-DBs + 3 dedizierte Postgres (mealie, immich, nextcloud) + 4 SQLite (gitea, vaultwarden, uptime-kuma, speedtest-tracker) + Filebrowser-BoltDB + Borg-UI + Grafana + Komodo-Mongo. Deckt 1:1 die Restore-Matrix-Eintraege ab.
|
||||
- **Borg-Scope:** `all-important-sources.txt` enthaelt 27 Eintraege inkl. neuer `services/homelab-infra`, `services/stacks`, `services/posture-check` und `secrets`.
|
||||
- **Restore-Validierungen:** Laut `docs/RESTORE_MATRIX.md` sind am 2026-05-07 Mini-Restores fuer `gitea`, `vaultwarden` und `paperless` validiert worden — dokumentierter Stand.
|
||||
- **Live offen:** Wann lief der letzte Borg-Lauf? Sind alle Dumps unter `/mnt/user/backups/borg/dumps/latest` frischer als 24h? Siehe Live-Checkliste 9.4.
|
||||
|
||||
### 4.2 Monitoring-Migration
|
||||
|
||||
- Repo-Zielzustand `monitoring/docker-compose.yml` (337 Zeilen Compose) existiert mit Prometheus, Alertmanager, ntfy-Bridge, Blackbox-Exporter, Loki, Promtail, Grafana, node-exporter, cAdvisor, InfluxDB3 Core.
|
||||
- Provisioning unter `monitoring/grafana/provisioning/` und `monitoring/prometheus/`, `monitoring/loki/`, `monitoring/promtail/`, `monitoring/alertmanager/`, `monitoring/blackbox/` vollstaendig vorhanden.
|
||||
- Alte Stacks `ops/grafana-influxdb/` und `ops/loki/` bewusst noch im Repo (dokumentierter Altstand, Rollback-Referenz).
|
||||
- **Live offen:** Ist `monitoring` schon als Komodo-Stack deployed? Laufen die Container? Sind die Secret-Dateien `monitoring_grafana_admin_password.txt`, `monitoring_grafana_influxdb_token.txt`, `influxdb3_admin_token.json` auf dem Host? Siehe Live-Checkliste 9.5.
|
||||
|
||||
### 4.3 Repo-Hygiene
|
||||
|
||||
| Befund | Schwere | Aktion |
|
||||
|---|---|---|
|
||||
| 8 leere Verzeichnisse (`apps/firefly`, `apps/firefly-fints`, `apps/stirling-pdf`, `host-services/docker`, `infra/dns`, `ops/backrest`, `ops/grafana-influxdb/scripts`, `ops/Semaphore/playbooks`, `ops/Semaphore/Scripts`) | klein | Aufraeumen, danach committen |
|
||||
| `.serena/` untracked, nicht in `.gitignore` | klein | `.serena/` zu `.gitignore` hinzufuegen |
|
||||
| 3 `ops/windows-reinstall/*.ps1` untracked | klein | Entscheidung treffen: ins Repo oder ignorieren |
|
||||
|
||||
### 4.4 Bekannte dokumentierte Ausnahmen
|
||||
|
||||
Aus `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 10 — alle weiterhin gueltig und durch den Policy-Check abgedeckt (`ops/policy-checks/last-report.md` 0 Critical):
|
||||
|
||||
- Traefik 80/443
|
||||
- Tailscale Host-Netz + Capabilities
|
||||
- AdGuard Port 53 + 8082 (Admin-Port LAN-only, dokumentiert; **offener Punkt im Master:** "Traefik-Absicherung ausstehend (Block F)" — bewusst spaeter)
|
||||
- Plex Host-Netz (aber Master-Doku-Eintrag jetzt falsch, siehe 2.5)
|
||||
- Scrutiny `privileged: true`
|
||||
- Komodo Docker-Socket + keine pauschale Middleware
|
||||
- glance-docker-socket-proxy Read-only Socket
|
||||
- Gitea SSH 222
|
||||
- ddns-updater `frontend_net`
|
||||
- mail-archiver Hybrid-Netze
|
||||
- `traefik/dynamic/*` manueller Host-Sync
|
||||
- nextcloud native Auth
|
||||
- monitoring-influxdb3-core LAN 8181 + `user: "0"`
|
||||
- monitoring-promtail Docker-Socket read-only
|
||||
|
||||
Keine ungeplanten neuen Ausnahmen.
|
||||
|
||||
### 4.5 Endstufen-Definition
|
||||
|
||||
"Endstufe" ist erreicht, wenn alle folgenden Punkte gruen sind:
|
||||
|
||||
1. **Gitea = Quelle der Wahrheit** — kein lokaler Commit ohne Push 🟡 (heute: `cd650b1` ungepusht)
|
||||
2. **Hardening-Sprint im Repo abgeschlossen** 🟢
|
||||
3. **Backup-Konsistenz live verifiziert (Borg laeuft, Dumps frisch)** ❓ Live
|
||||
4. **Monitoring-Stack live, alte Altstaende gestoppt** 🟡
|
||||
5. **Doku synchron mit Repo (Jellyfin/Plex, leere Verzeichnisse, ...)** 🟠
|
||||
6. **Policy-Check 0 Critical** 🟢 (4 Warnings sind dokumentierte Ausnahmen)
|
||||
7. **Restore-Lab gepflegt (`mail-archiver` als naechste Uebung empfohlen)** 🟡 dokumentiert offen
|
||||
|
||||
Sechs der sieben Punkte sind in Reichweite ohne neue Architekturentscheidungen. Punkt 3 und 4 brauchen Live-Daten (Abschnitt 9). Punkt 1 ist 1 Push entfernt.
|
||||
|
||||
---
|
||||
|
||||
## 5. Priorisierte Restliste
|
||||
|
||||
| Prio | Aktion | Begruendung | Aufwand |
|
||||
|---|---|---|---|
|
||||
| **P0** | `cd650b1` nach Gitea pushen | GitOps-Quelle-der-Wahrheit, Voraussetzung fuer alles weitere | 30 Sekunden |
|
||||
| **P0** | Live-Daten aus Abschnitt 9 einholen | Ohne Live-Frische ist Endstufen-Bewertung unvollstaendig | 5 Minuten |
|
||||
| **P1** | Monitoring-Stack live finalisieren (Secrets pruefen, deployen, Smoke-Test, alte Altstaende stoppen) | Aus `docs/archive/2026-05/NEXT_SPRINT_TODO_2026-05-16.md` der naechste produktive Schritt | 1–2 Stunden mit Tests |
|
||||
| **P2** | Doku-Drift schliessen: Jellyfin und Plex in `HOMELAB_ARCHITECTURE_MASTER_V2.md` 7.4 + 7.1, `docs/SERVICE_CATALOG.md`, `docs/REPO_MAP.md` ergaenzen; Plex-Eintrag in Abschnitt 7.7 "noch offene Sonderfaelle" entfernen (ist umgesetzt) | Doku ist Source of Truth fuer KI-Audits und Nachfolge | 30 Minuten |
|
||||
| **P2** | Home Assistant -> InfluxDB final testen, HA-Dashboard in `monitoring-grafana` anlegen | aus NEXT_SPRINT_TODO | 1–2 Stunden |
|
||||
| **P3** | Repo-Hygiene: 8 leere Verzeichnisse loeschen, `.serena/` in `.gitignore`, Entscheidung zu `ops/windows-reinstall/*.ps1` | minor, aber dokumentiert | 15 Minuten |
|
||||
| **P3** | Naechster Restore-Lab-Lauf: `mail-archiver` (empfohlen in `RESTORE_MATRIX.md`) | Restore-Routine ueben, bevor sie gebraucht wird | 1 Stunde |
|
||||
| **P4** | `.gitattributes` mit `* text=auto eol=lf` hinzufuegen, um CRLF/LF-Mount-Effekte bei KI-Audits zu vermeiden | klein, kosmetisch fuer kuenftige Audits | 5 Minuten |
|
||||
| **bleibt** | Hermes VM-Seite, Disk1-NTFS Phase 2, AdGuard Admin-Port hinter Traefik (Block F), Image-Pinning ddns/glances/scrutiny | bewusste Operator-Entscheidung, kein Audit-Beduerfnis | nicht jetzt |
|
||||
|
||||
---
|
||||
|
||||
## 6. Was bewusst NICHT angetastet wurde (Audit-Verzicht)
|
||||
|
||||
Konsistent mit der bekannten Nicht-Anfassen-Liste:
|
||||
|
||||
- Hermes (VM-seitig offen)
|
||||
- Disk1 NTFS (Phase-2-Migration nach Plan)
|
||||
- Komodo native Auth ohne ForwardAuth
|
||||
- Grafana / influxdb3-core `user: "0"` Uebergangsausnahme
|
||||
- Image-Pinning-Vereinheitlichung fuer ddns-updater/glances/scrutiny
|
||||
|
||||
---
|
||||
|
||||
## 7. Risiken und Drift-Indikatoren
|
||||
|
||||
| Risiko | Wahrscheinlichkeit | Wirkung | Migitation |
|
||||
|---|---|---|---|
|
||||
| Lokaler Clone-Verlust (Disk, Reinstall) bevor `cd650b1` gepusht wurde | gering, aber real (Du bist im Reinstall-Kontext, siehe `ops/windows-reinstall/`!) | Verlust von Gitea-Signup-Closure und Posture-Check-Verbesserungen | **Sofort pushen** |
|
||||
| Komodo deployt aus Gitea, `gitea` und `borg-ui` laufen aktuell ohne die heutigen Verbesserungen | mittel | Gitea Signup steht noch offen, Borg-Scope umfasst `/mnt/user/services` noch nicht | Push + Komodo-Reaktion pruefen |
|
||||
| 47 vermeintlich modified files koennten doch echte Diffs sein, wenn der Windows-Host etwas anderes zeigt | gering | falsche Audit-Aussage | Punkt 9.1 auf dem Windows-Host pruefen |
|
||||
| Doku-Drift wird groesser, wenn weitere Stacks ohne Doku-Update hinzukommen | mittel | KI-Audits und Onboarding leiden | P2-Doku-Sync nicht aufschieben |
|
||||
| Monitoring-Stack-Migration unfertig, alter und neuer Stack koennten parallel werden | mittel | Doppelte Metric-/Log-Pipeline, Verwirrung bei Diagnose | Live-Status klaeren bevor Deploy |
|
||||
|
||||
---
|
||||
|
||||
## 8. Sources of Truth — Schnellzugriff
|
||||
|
||||
- Operative Quelle der Wahrheit: Gitea `origin/master` (https://git.kaleschke.info/Micha/homelab-infra)
|
||||
- Architektur-Master: `HOMELAB_ARCHITECTURE_MASTER_V2.md`
|
||||
- Workflow / GitOps-Regeln: `docs/WORKFLOW.md`
|
||||
- Drift-Runbook: `docs/GITOPS_DRIFT_RUNBOOK.md`
|
||||
- Restore-Quellen: `docs/RESTORE_MATRIX.md`, `docs/DISASTER_RECOVERY.md`
|
||||
- Letzter Policy-Check: `ops/policy-checks/last-report.md` (0 Critical)
|
||||
- Letzte Sprint-Restliste: `docs/archive/2026-05/NEXT_SPRINT_TODO_2026-05-16.md`
|
||||
|
||||
---
|
||||
|
||||
## 9. Live-Daten-Checkliste — bitte ausfuehren und zurueckspielen
|
||||
|
||||
Fuehre die folgenden Bloecke am Unraid-Host (per SSH oder Web-Terminal) und am Windows-Host (Git Bash / PowerShell in `G:\Gitea_Clone\homelab-infra`) aus und pastiere die Outputs zurueck. Ich integriere sie dann in diesen Report.
|
||||
|
||||
### 9.1 Windows-Host: Echter Working-Tree-Status
|
||||
|
||||
```powershell
|
||||
cd G:\Gitea_Clone\homelab-infra
|
||||
git status --short
|
||||
git log origin/master..HEAD --oneline
|
||||
```
|
||||
|
||||
Erwartet: Working tree leer (oder nur die 4 Untracked). `cd650b1` als einziger lokaler Commit.
|
||||
|
||||
### 9.2 Unraid-Host: Gitea online
|
||||
|
||||
```bash
|
||||
curl -sI --max-time 5 https://git.kaleschke.info/ | head -5
|
||||
docker exec gitea sh -lc 'gitea --version'
|
||||
```
|
||||
|
||||
Erwartet: `HTTP/2 200` (oder ein Auth-Code, der den Erreichbarkeitstest erfuellt). Gitea-Version stimmt mit Image-Tag `1.25.4` ueberein.
|
||||
|
||||
### 9.3 Unraid-Host: Komodo-Webhook-Status
|
||||
|
||||
In Komodo UI fuer jeden produktiven Stack aus `Micha/homelab-infra` pruefen:
|
||||
- `webhook_enabled: true`
|
||||
- Gitea-Hook auf `http://komodo-core:9120/listener/github/stack/<stack-id>/deploy` aktiv
|
||||
- `last_status` der letzten Webhook-Delivery in Gitea (Repository -> Settings -> Webhooks)
|
||||
|
||||
Pflicht-Stacks zum Pruefen: `traefik`, `gitea`, `authelia`, `vaultwarden`, `postgresql17`, `redis`, `paperless-ngx`, `immich`, `nextcloud`, `mealie`, `mail-archiver`, `ntfy`, `homepage`, `paperless-gpt`, `borg-ui`, `filebrowser`, `code-server`, `uptime-kuma`, `glance`, `glances`, `scrutiny`, `speedtest-tracker`, `bentopdf`, `ddns-updater`, `komodo`, `jellyfin`, `plex`, `adguard`, `tailscale`, `monitoring`, `hermes-agent` (sofern produktiv).
|
||||
|
||||
Bei Stacks **ohne** aktiven Webhook bitte den Grund vermerken (dokumentierte Ausnahme oder Nachholbedarf).
|
||||
|
||||
### 9.4 Unraid-Host: Borg-Lauf-Frische und Dump-Coverage
|
||||
|
||||
```bash
|
||||
ls -lah /mnt/user/backups/borg/dumps/latest/
|
||||
stat -c '%y %n' /mnt/user/backups/borg/dumps/latest/*.dump /mnt/user/backups/borg/dumps/latest/*.sql /mnt/user/backups/borg/dumps/latest/*.archive.gz /mnt/user/backups/borg/dumps/latest/*.sqlite 2>/dev/null | sort
|
||||
docker exec borg-ui borg list --short 2>&1 | tail -10
|
||||
```
|
||||
|
||||
Erwartet: Alle 14 Artefakte aus 4.1 sind vorhanden, mtime juenger als 24h. Borg-Archive-Liste zeigt regelmaessige Laeufe.
|
||||
|
||||
### 9.5 Unraid-Host: Monitoring-Stack live?
|
||||
|
||||
```bash
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | grep monitoring
|
||||
ls -la /mnt/user/appdata/secrets/ | grep -E 'monitoring|influxdb3'
|
||||
curl -sI --max-time 5 https://monitoring.kaleschke.info/ | head -5
|
||||
ss -ltnp 2>/dev/null | grep -E ':8181|:9090|:3100' | head -10
|
||||
```
|
||||
|
||||
Erwartet: Entweder alle `monitoring-*` Container laufen (dann ist 4.2 🟢) oder gar nicht (dann ist 4.2 🟡 wie aktuell bewertet). Halb-Zustand ist ein Audit-Befund.
|
||||
|
||||
### 9.6 Unraid-Host: GitOps-Pflichtmatrix Spot-Check fuer einen Stack
|
||||
|
||||
Beispiel `gitea` (weil der heutige Commit ihn betrifft):
|
||||
|
||||
```bash
|
||||
cd /mnt/user/services/stacks/gitea
|
||||
git rev-parse --short HEAD
|
||||
git status -sb
|
||||
docker inspect gitea --format '{{.Image}}'
|
||||
docker exec gitea sh -lc 'env | grep -E "ALLOWED_HOST_LIST|DISABLE_REGISTRATION|ENABLE_OPENID"'
|
||||
```
|
||||
|
||||
Erwartet: Komodo-Workspace `HEAD` zeigt entweder auf `cd650b1` (wenn Push schon erfolgt + Komodo deployed) oder auf `af231dd` (vor dem Push). ENV-Vars in der Live-Runtime spiegeln den Commit, der Komodo zuletzt deployed hat.
|
||||
|
||||
### 9.7 Unraid-Host: Host-Listener-Spot-Check
|
||||
|
||||
```bash
|
||||
ss -ltnp 2>/dev/null | grep -E ':80|:443|:53|:222|:8082|:8181' | sort
|
||||
```
|
||||
|
||||
Erwartet exakt die dokumentierten Ausnahmen aus `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 10. Andere Listener = Befund.
|
||||
|
||||
---
|
||||
|
||||
## 10. Nachhalte-Vorschlag
|
||||
|
||||
Wenn Du moechtest, halte ich diesen Audit in zwei Schritten zu Ende:
|
||||
|
||||
1. Du fuehrst Abschnitt 9 aus und pastierst die Outputs zurueck.
|
||||
2. Ich aktualisiere diesen Report mit den Live-Ergebnissen, ergaenze die Ampel und schliesse die offenen 🟡/🟠 Punkte oder benenne sie als echte Restliste.
|
||||
|
||||
Bis dahin gilt der Stand dieses Reports als Repo-Audit, nicht als Endstufen-Zertifikat.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Homelab Audit Final - 2026-05-23
|
||||
|
||||
Stand: 2026-05-25 07:33 CEST. Ergebnis nach Push, Live-Messung, Doku-Sync, Repo-Hygiene und erneuter Live-Nachmessung.
|
||||
|
||||
| Punkt | Ampel | Beleg |
|
||||
|---|---|---|
|
||||
| P0 `cd650b1` nach Gitea pushen | gruen | Push `af231dd..cd650b1 master -> master`; produktiver Runtime-Stand `66ee10c` enthaelt `cd650b1`. Die abschliessenden Audit-Doku-Commits liegen in Gitea; der runtime-relevante Stack-Inhalt fuer `gitea`, `borg-ui` und `monitoring` ist seit `66ee10c` unveraendert. |
|
||||
| P0 Live-Daten ablegen | gruen | `docs/archive/2026-05/AUDIT_2026-05-23_LIVE.md` angelegt, keine Secret-Werte dokumentiert. |
|
||||
| P1 Monitoring live / Altstaende down | gruen | 10 `monitoring-*` Container laufen, `0` unhealthy, `0` starting, `0` stopped; alte `grafana`/`influxdb3-core`/`loki`/`alloy` Container sind nicht vorhanden. `monitoring.kaleschke.info` liefert 302 zu Authelia, Prometheus ist bereit, Loki `/ready` liefert `ready`. |
|
||||
| P1 Jellyfin/Plex Doku | gruen | `HOMELAB_ARCHITECTURE_MASTER_V2.md`, `docs/SERVICE_CATALOG.md` und `docs/REPO_MAP.md` ergaenzt; Plex ist als Repo-Compose-Stack dokumentiert, nicht mehr als nicht migrierter Dockerman-Sonderfall. |
|
||||
| P2 Borg-Frische | gruen | Borg-UI DB: letzter Backup-Job `completed`, Archiv `Taegliche-Sicherung-2026-05-25T05:52:44.157`, `nfiles=100221`; 15 kanonische Dump-/Archive-Artefakte von 2026-05-25 06:09/06:10 CEST und damit juenger als 24 h. |
|
||||
| P3 Repo-Hygiene | gruen | `.serena/` in `.gitignore`; leere Verzeichnisse entfernt; `ops/windows-reinstall/*.ps1` bewusst ins Repo aufgenommen. |
|
||||
| Policy-Check | gruen | `ops/policy-checks/check_repo.ps1`: 0 Critical, dokumentierte Warnings zu Plex Host-Netz, InfluxDB/Grafana `user: "0"` und bekannten mutable-tag-Ausnahmen. |
|
||||
|
||||
## Bewusst offen
|
||||
|
||||
- Keine offenen Punkte aus der Audit-Restliste.
|
||||
- Nicht Teil des Audits: Nach Disk1 Phase 2 laeuft seit 2026-05-25 eine nicht korrigierende Parity-Pruefung (`NOCORRECT`) im Hintergrund; Zwischenstand der Nachmessung: `mdResyncAction=check P`, `mdResyncCorr=0`.
|
||||
|
||||
## Schlussbewertung
|
||||
|
||||
Das Homelab ist fuer die Audit-Restliste in der Endstufe. Es gibt keine kritischen Repo-, GitOps- oder Live-Befunde aus diesem Audit. Monitoring ist produktiv und ready, alte Altstaende sind down, Backups und Dumps sind frisch.
|
||||
@@ -0,0 +1,88 @@
|
||||
# Homelab Audit Live-Daten - 2026-05-23
|
||||
|
||||
Stand: 2026-05-23 11:27 CEST. Quelle: lokaler Windows-Clone und SSH auf `Kallilabcore`. Secret-Werte wurden nicht ausgelesen oder redaktiert; dokumentiert sind nur Status, Dateinamen, Modi, Env-Key-Namen und nicht geheime Bool-/Host-Werte.
|
||||
|
||||
## 9.1 Windows-Host / Git
|
||||
|
||||
- `git status --short` nach dem initialen Push: keine tracked Modifikationen, untracked waren `.serena/`, `docs/archive/2026-05/AUDIT_2026-05-23.md`, `docs/archive/2026-05/CODEX_ENDSTUFE_PROMPT_2026-05-23.md` und drei `ops/windows-reinstall/*.ps1`.
|
||||
- `cd650b1` wurde nach `origin/master` gepusht: `af231dd..cd650b1 master -> master`.
|
||||
|
||||
## 9.2 Gitea online
|
||||
|
||||
- `curl -sI https://git.kaleschke.info/`: `HTTP/2 200`.
|
||||
- `docker exec gitea gitea --version`: `1.25.4`.
|
||||
- Signup-Smoke: `/user/sign_up` meldet Registration disabled.
|
||||
|
||||
## 9.3 Komodo / Workspace-Reaktion
|
||||
|
||||
| Stack | Workspace HEAD | Status | Live-Beleg |
|
||||
|---|---:|---|---|
|
||||
| `gitea` | `cd650b1` | `## master...origin/master` | Container neu gestartet, Env-Keys aktiv |
|
||||
| `borg-ui` | `cd650b1` | `## master...origin/master` | Container healthy, `/mnt/user/services -> /local/services` gemountet |
|
||||
| `monitoring` | `cd650b1` | `## master...origin/master`, untracked Host-Backup `monitoring/prometheus/alerts.yml.bak-20260520-incident` | Stack laeuft seit 4 Tagen |
|
||||
|
||||
Gitea Live-Env ohne Secrets:
|
||||
|
||||
```text
|
||||
GITEA__service__DISABLE_REGISTRATION=true
|
||||
GITEA__openid__ENABLE_OPENID_SIGNIN=false
|
||||
GITEA__openid__ENABLE_OPENID_SIGNUP=false
|
||||
GITEA__webhook__ALLOWED_HOST_LIST=komodo-core,localhost,127.0.0.1,192.168.178.0/24
|
||||
```
|
||||
|
||||
## 9.4 Borg-Lauf-Frische und Dump-Coverage
|
||||
|
||||
- Borg UI DB: Repository `appdata-critical`, `last_backup=2026-05-23 02:30:12 UTC`, `archive_count=30`, letzter Job `completed`, `nfiles=100056`.
|
||||
- Schedule: `Taegliche Sicherung` enabled, letzter Lauf `2026-05-23 02:30:11 UTC`, naechster Lauf `2026-05-24 02:30:00 UTC`.
|
||||
- Hinweis: `docker exec borg-ui borg list --short` funktioniert ohne Repository-Parameter/Env nicht (`Invalid location format: ""`). Der Borg-UI-Status wurde deshalb ueber die lokale Borg-UI-Datenbank ohne Secret-Spalten ausgewertet.
|
||||
|
||||
Frische Artefakte in `/mnt/user/backups/borg/dumps/latest`:
|
||||
|
||||
```text
|
||||
2026-05-23 04:00 postgresql17-globals.sql
|
||||
2026-05-23 04:00 postgresql17-mailarchiver.dump
|
||||
2026-05-23 04:00 postgresql17-paperless.dump
|
||||
2026-05-23 04:01 postgresql17-authelia.dump
|
||||
2026-05-23 04:01 mealie.dump
|
||||
2026-05-23 04:01 gitea.sqlite.dump
|
||||
2026-05-23 04:01 immich.dump
|
||||
2026-05-23 04:01 nextcloud.dump
|
||||
2026-05-23 04:01 uptime-kuma.sqlite.dump
|
||||
2026-05-23 04:01 vaultwarden.sqlite.dump
|
||||
2026-05-23 04:01 speedtest-tracker.sqlite.dump
|
||||
2026-05-23 04:01 filebrowser.bolt.dump
|
||||
2026-05-23 04:01 borg-ui.sqlite
|
||||
2026-05-23 04:01 grafana.sqlite
|
||||
2026-05-23 04:01 komodo-mongo.archive.gz
|
||||
```
|
||||
|
||||
Bewertung: 15 aktuelle Dump-/Archive-Artefakte sind juenger als 24 h. Aeltere nackte `.sqlite`-Dateien vom 2026-05-16 liegen noch im Verzeichnis, sind aber Legacy-Kopien ohne `.dump`-Suffix und nicht Teil der aktuellen Dump-Serie.
|
||||
|
||||
## 9.5 Monitoring-Stack
|
||||
|
||||
- Aktive Container: `monitoring-grafana`, `monitoring-promtail`, `monitoring-prometheus`, `monitoring-cadvisor`, `monitoring-influxdb3-core`, `monitoring-loki`, `monitoring-blackbox-exporter`, `monitoring-alertmanager-ntfy-bridge`, `monitoring-alertmanager`, `monitoring-node-exporter`.
|
||||
- Alte Altcontainer `grafana`, `influxdb3-core`, `loki`, `alloy`: nicht vorhanden in `docker ps -a`.
|
||||
- Secret-Dateien vorhanden und mode `600`: `monitoring_grafana_admin_password.txt`, `monitoring_grafana_influxdb_token.txt`, `influxdb3_admin_token.json`.
|
||||
- `https://monitoring.kaleschke.info/`: `HTTP/2 302` zu Authelia, wie erwartet.
|
||||
- Host-Listener fuer Monitoring: nur `127.0.0.1:8181`; keine Host-Listener fuer `:9090` oder `:3100`.
|
||||
- Prometheus readiness: `Prometheus Server is Ready.`
|
||||
- Grafana health: `database=ok`, Version `12.4.3`.
|
||||
- Loki: Container laeuft und API/metrics liefert `loki_build_info`; `/ready` liefert aktuell `503 Service Unavailable`, waehrend Query-/Metrics-Endpunkte 200-Zaehler zeigen. Kein Reparaturversuch gestartet, weil der produktive Logpfad nachweislich Daten annimmt und die Stop-Regel keine blinden Eingriffe erlaubt.
|
||||
|
||||
## 9.6 GitOps Spot-Check Gitea
|
||||
|
||||
- `/mnt/user/services/stacks/gitea`: `cd650b1`, `## master...origin/master`.
|
||||
- Docker-Image: `docker.gitea.com/gitea:1.25.4`.
|
||||
- Live-ENV spiegelt `cd650b1` fuer Registrierung, OpenID und Webhook-Allowlist.
|
||||
|
||||
## 9.7 Host-Listener
|
||||
|
||||
Dokumentierte Listener gefunden:
|
||||
|
||||
- `:80`, `:443` Traefik
|
||||
- `:53` AdGuard DNS
|
||||
- `:222` Gitea SSH
|
||||
- `:8082` AdGuard Admin
|
||||
- `127.0.0.1:8181` Monitoring InfluxDB
|
||||
|
||||
Zusaetzlich sichtbar: mehrere `wsdd2` Listener auf `:5355` je Interface. Das ist Host-/Unraid-Service-Discovery, kein Compose-Webdienst und kein GitOps-Stack-Port.
|
||||
@@ -0,0 +1,895 @@
|
||||
# Homelab-Audit KalliLab CORE
|
||||
|
||||
Stand: 2026-05-25
|
||||
Methode: Repo-basierter Audit auf `master` (lokaler Clone). Keine Live-Messung gegen den Host. Querverweise auf Audit-Live-Daten aus `docs/archive/2026-05/AUDIT_2026-05-23_LIVE.md`, wo verfuegbar.
|
||||
Auftrag: externer, kritischer Audit-Blick zusaetzlich zur internen `docs/archive/2026-05/STRATEGISCHE_BEWERTUNG_2026-05-23.md`.
|
||||
|
||||
## Wichtige Vorbemerkung
|
||||
|
||||
Es gibt seit dem 23.05. eine fundierte interne Bewertung (`docs/archive/2026-05/STRATEGISCHE_BEWERTUNG_2026-05-23.md`) und eine konsolidierte Hausaufgabenliste (`docs/archive/2026-05/CODEX_KONSOLIDIERUNG_2026-05-23.md`). Davon wurden seit dem 25.05. bereits umgesetzt:
|
||||
|
||||
- Jellyfin entfernt (MASTER 7.8)
|
||||
- Homepage entfernt (MASTER 7.8)
|
||||
- Uptime-Kuma entfernt (MASTER 7.8, SECRETS_MAP 29)
|
||||
- Monitoring-Stack produktiv (AUDIT_FINAL 9), Altstaende-Container down
|
||||
- Disk1 NTFS -> XFS Phase 2 abgeschlossen am 2026-05-25 (STORAGE_LAYOUT 3)
|
||||
- Unraid-Flash-Backup live (`unraid-flash-config.tar.gz` im Borg-Lauf)
|
||||
- GitHub-Push-Mirror `michaelkaleschke-spec/homelab-infra` aktiv (DR 10, MASTER 7.1)
|
||||
|
||||
Diese geloesten Punkte werden hier nicht wiederholt. Dieser Audit konzentriert sich auf das, was nach dem 23.05.-Sprint **noch offen ist** und auf das, was die strategische Bewertung **nicht oder nur kurz angerissen** hat.
|
||||
|
||||
---
|
||||
|
||||
# Phase 1: Repo-Inventar
|
||||
|
||||
## Ordnerstruktur (Ist-Zustand)
|
||||
|
||||
```
|
||||
homelab-infra/
|
||||
├── apps/ 9 Stacks (bentopdf, immich, mail-archiver, mealie, nextcloud, ntfy, paperless, paperless-gpt, unbound)
|
||||
├── core/ 1 Stack (gitea)
|
||||
├── docs/ 28 Markdown-Dokumente
|
||||
├── env/ 2 *.example
|
||||
├── host-services/ 3 Stacks (Adguard, plex, tailscale)
|
||||
├── infra/ 3 Stacks (ddns-updater, postgresql17, redis)
|
||||
├── monitoring/ 1 Compose mit 10 Services + Provisioning
|
||||
├── ops/ 17 Verzeichnisse (Semaphore, borg-ui, code-server, filebrowser, glance, glances, grafana-influxdb [Altstand], hermes-agent, komodo, loki [Altstand], policy-checks, restore-tests, scrutiny, speedtest, uptime-kuma [Altrest], windows-reinstall)
|
||||
├── security/ 2 Stacks (authelia, vaultwarden)
|
||||
├── services/ 1 posture-check (Host-Skripte)
|
||||
└── traefik/ 1 Compose + dynamic/ (3 Files)
|
||||
```
|
||||
|
||||
**Inventar-Befund:**
|
||||
|
||||
- ~30 Compose-Dateien, 1 zentraler Compose-Multi-Service (`monitoring/`).
|
||||
- 29 Composes wurden vom Policy-Checker validiert (`ops/policy-checks/last-report.md`): **0 Critical, 4 Warnings, 9 Info**.
|
||||
- Doku-Dichte ist hoch (REPO_MAP, SERVICE_CATALOG, RESTORE_MATRIX, DISASTER_RECOVERY, SECRETS_MAP, WORKFLOW, STORAGE_LAYOUT, GITOPS_DRIFT_RUNBOOK, ALERTING_MAP).
|
||||
- Restore-Tests sind als echte Scripts versioniert (`ops/restore-tests/`). Ueberdurchschnittlich.
|
||||
|
||||
## Gut dokumentierte Bereiche (Belegt)
|
||||
|
||||
| Bereich | Quelle |
|
||||
|---|---|
|
||||
| Architektur, Netze, Ausnahmen | `HOMELAB_ARCHITECTURE_MASTER_V2.md` |
|
||||
| GitOps-Workflow, Drift | `docs/WORKFLOW.md`, `docs/GITOPS_DRIFT_RUNBOOK.md` |
|
||||
| Backup-Scope, Restore-Wege, Tier-Modell | `docs/RESTORE_MATRIX.md`, `docs/DISASTER_RECOVERY.md`, `ops/borg-ui/BACKUP_SCOPE.md` |
|
||||
| Storage / Cache-Policy / FS / Posture | `docs/STORAGE_LAYOUT.md` (zum Audit-Zeitpunkt noch `docs/STORAGE_LAYOUT.draft.md`) |
|
||||
| Secret-Inventur | `docs/SECRETS_MAP.md` |
|
||||
| Alert-Pfade | `docs/ALERTING_MAP.md` |
|
||||
|
||||
## Luecken / Unklar (vermutet bzw. Rueckfrage noetig)
|
||||
|
||||
| Luecke | Warum es ein Audit-Loch ist |
|
||||
|---|---|
|
||||
| `docs/STORAGE_LAYOUT.draft.md` ist `Draft 1.3`, nicht `Active` | Stand zum Audit-Zeitpunkt 2026-05-25: mehrere Hard Rules (12 Constitution) galten formal noch nicht. Hard Rule 11 (kein Stack ohne Restore-Pfad in RESTORE_MATRIX) wurde schon eingehalten — also nur Formal-Luecke. Folgearbeit: als `docs/STORAGE_LAYOUT.md` Active heben. |
|
||||
| `docs/SERVICES_RECOVERY.md` ist als verbindlich angekuendigt (STORAGE_LAYOUT 4), aber nicht im Repo | Konkrete Mirror-Mechanik fuer `services/gitea/git/repositories/` ≤ 6 h ist nirgends spezifiziert. |
|
||||
| Hardware-Inventar: kein zentrales Dokument | Keine Stelle im Repo nennt CPU-Modell, RAM-Groesse, NIC-Speed, Mainboard, Parity-Disk-Groessen — nur "Samsung 970 EVO Plus 2 TB" steht in STORAGE_LAYOUT 3. |
|
||||
| USV: keine Erwaehnung | Keine Datei nennt eine USV. Unklar, ob vorhanden. |
|
||||
| Familien-/User-Onboarding-Doku | Keine Doku, die deine Frau/Kinder lesen muessten ("So loggst du dich in Nextcloud ein"). Aktuell ist alles Operator-Doku. |
|
||||
|
||||
## Fuer den Audit besonders wichtige Dateien (verwendet)
|
||||
|
||||
- `HOMELAB_ARCHITECTURE_MASTER_V2.md` — komplett
|
||||
- `docs/WORKFLOW.md`, `docs/REPO_MAP.md`, `docs/SERVICE_CATALOG.md` — komplett
|
||||
- `docs/DISASTER_RECOVERY.md`, `docs/RESTORE_MATRIX.md`, `docs/SECRETS_MAP.md` — komplett
|
||||
- `docs/STORAGE_LAYOUT.md` (zum Audit-Zeitpunkt `docs/STORAGE_LAYOUT.draft.md`), `docs/archive/2026-05/STRATEGISCHE_BEWERTUNG_2026-05-23.md` — komplett
|
||||
- `docs/archive/2026-05/AUDIT_2026-05-23_LIVE.md`, `docs/archive/2026-05/AUDIT_2026-05-23_FINAL.md`
|
||||
- `ops/policy-checks/last-report.md`
|
||||
- `monitoring/docker-compose.yml`, `monitoring/prometheus/alerts.yml`
|
||||
- `traefik/docker-compose.yml`, `traefik/dynamic/middlewares.yml`
|
||||
- `security/authelia/configuration.yml`, `security/authelia/docker-compose.yml`
|
||||
- `apps/paperless/docker-compose.yml`, `apps/immich/docker-compose.yml`, `apps/nextcloud/docker-compose.yml`
|
||||
- `host-services/Adguard/docker-compose.yml`
|
||||
|
||||
---
|
||||
|
||||
# A. Executive Summary
|
||||
|
||||
**Was schon stark ist:**
|
||||
|
||||
- GitOps-Disziplin: Gitea als Sollzustand, Komodo als Consumer, dokumentierter Drift-Runbook, Stop-Regel ("zwei Fehlversuche -> Pflichtmatrix"). Seltene Reife.
|
||||
- Backup-Architektur: Pre-Backup-Dumps + Borg + Restore-Tests mit echtem Smoke-Test-Kriterium ("Container startet ≠ Erfolg"). 15 frische Dumps < 24 h alt (`AUDIT_LIVE 9.4`).
|
||||
- Architektur-Klarheit: `frontend_net` / `backend_net` / app-interne Netze, keine Sammelnetze, dokumentierte Ausnahmen.
|
||||
- Image-Pinning: Tier-1-Stateful mit `<minor>@sha256:...`. Konsequent durchgezogen.
|
||||
- Secrets-Hygiene: Keine Secret-Werte im Repo, `_FILE`-Mounts + Komodo Stack ENV, explizit dokumentierte Ausnahmen.
|
||||
- Policy-as-Code: `check_repo.ps1` mit 0 Critical und sauber dokumentierten Exceptions.
|
||||
|
||||
**Was kritisch ist:**
|
||||
|
||||
- **AdGuard Admin-Port 8082 ohne Authelia/2FA am LAN gebunden** (`host-services/Adguard/docker-compose.yml:16`) — dokumentierte "Operator-Entscheidung" 2026-05-25. Im Heim-LAN tolerierbar, mit IoT/Gaeste-WLAN potenziell ein Pfad zur DNS-Manipulation. Niedrigster Aufwand: Bind nur auf Tailscale-Interface.
|
||||
- **Authelia ACL: 2FA nur fuer `files.kaleschke.info` und `scrutiny.kaleschke.info`** (`security/authelia/configuration.yml:44-48`). Borg-UI, Code-Server, Filebrowser, Glance — alles nur `one_factor`. Bei Pwd-Kompromittierung des Operator-Accounts ist Borg-UI + Code-Server der direkteste Pfad zur Datenexfiltration.
|
||||
- **Authelia-Repo-Baseline ↔ Host-Config-Drift "by design"** (`docs/REPO_MAP.md:48`, `SERVICE_CATALOG 23`). User-DB, OIDC-Clients und Secrets sind hostseitig, Manual-Merge-Pflicht. Stelle, an der Drift mit Anlauf passiert.
|
||||
- **Komodo Self-Bootstrap-Problem ist nur dokumentiert, nicht geloest** (MASTER 13: Self-Stack Drift-Recovery 2026-05-04). Bei Recovery vom kalten Host musst du Komodo aus `compose.yaml` neu erzeugen — dafuer brauchst du die `.env` mit `KOMODO_*`-Secrets, die nur auf Host und ggf. Vaultwarden liegen.
|
||||
- **Backup-Off-Site-Diversitaet:** BorgBase Hetzner ist Single-Provider; Borg-Passphrase analog gesichert ist als TODO markiert (`docs/DISASTER_RECOVERY.md:64,401`). Wenn Hetzner-Account verloren geht, ist das halbe DR-Versprechen weg.
|
||||
|
||||
**Was unnoetig komplex ist:**
|
||||
|
||||
- Drei dokumentierte Monitoring-/Logging-Pfade gleichzeitig im Repo: `ops/grafana-influxdb` (Altstand), `ops/loki` (Altstand), `monitoring/` (Ziel). Die Altstaende sind als Container down, aber **Verzeichnisse noch im Repo** — Doppelpflege-Risiko. Der versprochene Repo-Cleanup (`git rm`) fehlt.
|
||||
- Hermes-Agent: NAS-Stack bewusst deaktiviert ("VM-seitig offen"), aber Stack-Verzeichnis und Compose mit Dashboard-Domain bleiben im Repo. Mehr "Schwebezustand" als operativer Wert.
|
||||
- BentoPDF: "vorbereitet", noch nie produktiv abgenommen (`SERVICE_CATALOG 52`, `MASTER 7.5`).
|
||||
- `infra/redis` ist als shared Cache deklariert, wird de facto nur von Paperless genutzt (Authelia nicht, Immich/Nextcloud/Mealie haben eigene Redis). Das "shared" stimmt im Repo nicht mit der Realitaet ueberein.
|
||||
|
||||
**Groesster Hebel:**
|
||||
|
||||
**Authelia OIDC-Provider aktivieren** — wenn Nextcloud, Immich, Grafana (und perspektivisch Mealie via OIDC-Bridge) per SSO laufen, gewinnst du gleichzeitig:
|
||||
|
||||
- (a) Familien-Onboarding-Komfort (ein Login),
|
||||
- (b) zentrale Brute-Force-Regulation und Audit,
|
||||
- (c) Voraussetzung fuer sinnvolles CrowdSec/Fail2Ban,
|
||||
- (d) zentrale 2FA-Pflicht statt App-by-App.
|
||||
|
||||
Das ist ein Sprint, nicht ein Quartal, und macht aus deinem "Admin-Authelia" ein echtes Identity-System.
|
||||
|
||||
**Was ein erfahrener Homelabber sofort aendern wuerde:**
|
||||
|
||||
1. AdGuard-Admin-Port nur auf Tailscale-Interface binden (5 Min, Compose-Edit).
|
||||
2. Borg-Passphrase auf Papier in Bankschliessfach (15 Min, off-system).
|
||||
3. `scrutiny` und `ddns-updater` `no-new-privileges` Warning aufraeumen (10 Min) — kosmetisch, aber Policy-Check sollte clean sein.
|
||||
4. Altstaende `ops/grafana-influxdb/` und `ops/loki/` aus Repo entfernen (Backup-Branch dann `git rm`).
|
||||
5. Renovate-Bot gegen Gitea einrichten — beendet manuelle Digest-Pflicht.
|
||||
|
||||
---
|
||||
|
||||
# B. Scorecard (1 = exzellent, 10 = ungenuegend)
|
||||
|
||||
| Bereich | Note | Begruendung |
|
||||
|---|---:|---|
|
||||
| Hardware | **nicht bewertbar** | Keine Inventar-Doku im Repo. Nur Cache-NVMe genannt. Siehe Phase H. |
|
||||
| Ordnerstruktur | **2** | Klare Trennung apps/infra/ops/security/core; konsistente Namenskonvention (mit Migrationsplan in STORAGE_LAYOUT 6). Kleinerer Haenger: `host-services/Adguard/` mit Grossbuchstabe. |
|
||||
| Storage | **3** (Repo-Stand) / **2** (mit STORAGE_LAYOUT Active) | Cache-XFS, Disk1-XFS jetzt erreicht. Pfad-Disziplin via `/mnt/user/...`. Posture-Check etabliert. Note durch Draft-Status und fehlendes `SERVICES_RECOVERY.md` gedrueckt. |
|
||||
| Docker-Architektur | **2** | Netzmodell klar, Healthchecks fehlen grossflaechig, `latest@sha256` als bewusster Kompromiss bei einigen Images dokumentiert. Keine Memory-Limits. |
|
||||
| Reverse Proxy / Zugriff | **2** | DNS-Challenge, Wildcard-faehig, Authelia ForwardAuth, dynamic config sauber getrennt. Manuelle Host-Sync-Ausnahme ist pragmatisch. |
|
||||
| Security | **3** | Solides Fundament (Authelia Argon2id, no-new-privileges-Standard, Webhook-Allowlist, `cloudflare_dns_api_token` als Docker Secret), aber: nur 2 Domains mit 2FA, AdGuard-Admin direkt am LAN, kein WAF/Bouncer, Authelia Regulation 5-Min-Ban ist gentil. |
|
||||
| Netzwerk / DNS | **2** | AdGuard + Unbound + Tailscale-Trias ist Best-of-Class-Homelab. FritzBox als Router nicht im Repo dokumentiert, daher Note nicht 1. |
|
||||
| Backup | **2** | Borg, Pre-Dumps, Tier-Modell, dokumentierter Scope. Punkt-Abzug: Single-Provider Off-Site, Passphrase nicht analog, Komodo-Mongo-Dump-Verifikation nicht im Auto-Cron. |
|
||||
| Restore-Faehigkeit | **2** | RESTORE_MATRIX mit Smoke-Test je Dienst, Restore-Test-Schedule + Validierungen fuer Vaultwarden/Gitea/Paperless dokumentiert. Punkt-Abzug: Immich-Restore noch nie geuebt — groesster Datentopf. |
|
||||
| GitOps | **1-2** | Webhook-Pflicht fuer neue Stacks, Source-of-Truth-Hierarchie, Drift-Runbook. Self-Bootstrap-Problem von Komodo zieht von 1 auf 2. |
|
||||
| Monitoring | **3** | Stack produktiv, aber Altstaende noch im Repo, Family-View-Dashboard fehlt, Alerts (`alerts.yml`) sehr knapp (5 Regeln), keine Cert-Expiry-Alert auf Prometheus-Ebene (Cert-Token-Check laeuft separat). |
|
||||
| Dokumentation | **1** | Aussergewoehnlich. SERVICE_CATALOG ist Gold. Einziger Punkt: kein End-User-/Familien-Onboarding. |
|
||||
| Automatisierung | **3** | Borg-Dumps automatisiert, posture-check Host-Cron, Alert->ntfy-Pipe. Aber: keine CI gegen Repo, kein Renovate, kein automatisches Image-Update-Tracking. |
|
||||
| Wartbarkeit | **2** | Doku traegt; Sprintpflege-Disziplin sichtbar (MIGRATION_LOG, AUDIT_FINAL). Risiko: Authelia-Drift, Hermes-Schwebezustand. |
|
||||
| Nerd-Faktor | **2-** | Komodo + Borg-UI + ntfy-Bridge + Posture-Check + Restore-Lab + Hermes-Experiment + Push-Mirror + Digest-Pinning. Liegt zwischen "Solider Senior" und "Spielwiese halten lernen". |
|
||||
|
||||
**Gesamteindruck: 2 (gut).** Strukturell weit ueber durchschnittlichem Homelab; konkrete Luecken sind klar benennbar und nicht systemisch.
|
||||
|
||||
---
|
||||
|
||||
# C. Top-20 Findings
|
||||
|
||||
> Format: priorisiert nach Risiko-zu-Aufwand-Hebel. Jeder Eintrag hat Fundstelle, Empfehlung und Prio.
|
||||
|
||||
### F-01 · AdGuard-Admin am LAN ohne Auth
|
||||
|
||||
- **Kategorie:** Security / Zugriff
|
||||
- **Fundstelle:** `host-services/Adguard/docker-compose.yml:16`, `MASTER 10`, `docs/SERVICE_CATALOG.md:14`
|
||||
- **Beobachtung:** Port `8082:80` direkt auf alle Interfaces. Bewusste Operator-Entscheidung 2026-05-25.
|
||||
- **Risiko:** Jedes Geraet im LAN kann DNS-Filterregeln, Upstream und Logging manipulieren. IoT-Kompromittierung oder Gast-WLAN -> DNS-Hijack moeglich.
|
||||
- **Best Practice:** Admin-UIs nicht im LAN ohne Auth. Entweder hinter Traefik+Authelia mit `two_factor` oder Bind auf Tailscale-Interface (z. B. `100.x.y.z:8082:80`).
|
||||
- **Empfehlung:** Schritt 1 — Bind auf Tailscale-IP (S, 5 Min). Schritt 2 — optional spaeter Traefik-Route hinter Authelia.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** `ss -ltnp | grep :8082` zeigt nur Tailscale-IP; LAN-Browser-Zugriff schlaegt fehl.
|
||||
- **Rollback:** Compose-Diff zurueck, Komodo redeploy.
|
||||
|
||||
### F-02 · Borg-Passphrase nicht analog gesichert
|
||||
|
||||
- **Kategorie:** Backup / DR
|
||||
- **Fundstelle:** `docs/DISASTER_RECOVERY.md:64,401`, `docs/SECRETS_MAP.md:48`
|
||||
- **Beobachtung:** `borg_repo_passphrase.txt` liegt im Host-Filesystem unter `/mnt/user/appdata/secrets/`. Doku weist explizit darauf hin, dass eine externe analoge Sicherung Operator-Aufgabe ist.
|
||||
- **Risiko:** Wenn Unraid-Host und ggf. Vaultwarden gleichzeitig defekt sind, ist das verschluesselte Borg-Repo bei Hetzner nutzlos.
|
||||
- **Empfehlung:** Auf Papier ausdrucken, in Bankschliessfach oder bei vertrauter Person versiegelt. Zusaetzlich in Vaultwarden hinterlegen (aber Vaultwarden hilft nicht, wenn es selbst restauriert werden muss).
|
||||
- **Prioritaet:** Muss sofort
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** Du kannst den Wert ohne Host wiederherstellen.
|
||||
|
||||
### F-03 · Single-Provider Off-Site Backup
|
||||
|
||||
- **Kategorie:** Backup
|
||||
- **Fundstelle:** `ops/borg-ui/BACKUP_SCOPE.md`, `docs/RESTORE_MATRIX.md:77-96`, `STORAGE_LAYOUT 8.1`
|
||||
- **Beobachtung:** Hetzner Storage Box als alleiniges Off-Site-Borg-Ziel. STORAGE_LAYOUT 8.1 sieht zusaetzlich lokales Borg-Repo auf `/mnt/user/backups/borg/` vor (gleicher Host) und eine externe Wechselplatte (manuell rotiert).
|
||||
- **Risiko:** Hetzner-Account-Verlust (Payment-Issue, Account-Hack, Provider-Outage) = halbes 3-2-1.
|
||||
- **Best Practice:** Zweites Off-Site-Ziel mit unterschiedlichem Provider oder Cold-Wechselplatte mit fester Rotationskadenz.
|
||||
- **Empfehlung:** (a) Wechselplatten-Rotation in fester Kadenz dokumentieren (zwei Platten, monatlicher Tausch). Oder (b) zweites Borg-Repo bei rsync.net / BorgBase EU2 / privatem 2. Standort.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** M
|
||||
- **Validierung:** `borg list` gegen beide Repos, beide < 7 Tage alt.
|
||||
|
||||
### F-04 · Authelia 2FA-Pflicht zu schmal
|
||||
|
||||
- **Kategorie:** Security
|
||||
- **Fundstelle:** `security/authelia/configuration.yml:44-53`
|
||||
- **Beobachtung:** Nur `files.kaleschke.info` und `scrutiny.kaleschke.info` sind `two_factor`. Tier-1-Operator-UIs wie Borg-UI, Code-Server, Filebrowser (zweite Route?), Komodo (eigene Auth), Glance, Grafana laufen mit `one_factor`.
|
||||
- **Risiko:** Operator-Passwort-Kompromittierung (Phishing, Keylogger, Browser-Save-Leak) gibt ohne 2FA Vollzugriff auf Code-Server (Repo + Workspace), Borg-UI (Restore-Pfade), Filebrowser (Documents/Photos).
|
||||
- **Empfehlung:** ACL erweitern: `two_factor` fuer `borg.kaleschke.info`, `code.kaleschke.info`, `files.kaleschke.info` (schon), `glance.kaleschke.info` (debattierbar), `traefik.kaleschke.info`. Komodo bleibt Ausnahme.
|
||||
- **Prioritaet:** Muss sofort
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** Nach Login auf `borg.kaleschke.info` wird 2FA-Prompt erzwungen.
|
||||
- **Rollback:** ACL-Block zurueck.
|
||||
|
||||
### F-05 · Repo-Altstaende `ops/grafana-influxdb/` und `ops/loki/` nicht entfernt
|
||||
|
||||
- **Kategorie:** Wartbarkeit / GitOps
|
||||
- **Fundstelle:** Repo-Wurzeln `ops/grafana-influxdb/`, `ops/loki/`; `MASTER 7.6`, `SERVICE_CATALOG 68-70,80-81`, `AUDIT_FINAL 9`
|
||||
- **Beobachtung:** Container down, aber Compose-Dateien + Provisioning bleiben im Repo. Doku referenziert beide gleichzeitig. Risiko: jemand (zukuenftiges Ich, KI) deployt versehentlich den Altstand.
|
||||
- **Empfehlung:** `git rm` der beiden Verzeichnisse, Tag `pre-monitoring-cleanup` fuer Rollback, MIGRATION_LOG-Eintrag.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** `policy-checks` laeuft clean, Repo enthaelt nur noch `monitoring/`.
|
||||
|
||||
### F-06 · Hermes-Agent im Schwebezustand
|
||||
|
||||
- **Kategorie:** App-Landschaft / Wartbarkeit
|
||||
- **Fundstelle:** `ops/hermes-agent/docker-compose.yml`, `MASTER 7.5`, `SERVICE_CATALOG 82-83`
|
||||
- **Beobachtung:** "NAS-Stack bewusst deaktiviert" wegen offener VM-Seite. Dashboard-Domain (`hermes.kaleschke.info`) + Authelia-ACL + Secret-Pfade dokumentiert.
|
||||
- **Risiko:** Schleichender Verfall — in 6 Monaten verstehst du Model-C nicht mehr ohne `ops/hermes-agent/README.md`. Bei jeder Authelia-/Compose-Aenderung musst du Hermes mitpruefen, obwohl es nichts tut.
|
||||
- **Empfehlung:** Operator-Entscheidung mit 60-Tage-Deadline ehrlich treffen. Wenn nicht produktiv bis 2026-07-25: `git rm ops/hermes-agent/`, Domain aus DNS, ACL-Eintrag raus.
|
||||
- **Prioritaet:** Sollte zeitnah (Entscheidung)
|
||||
- **Aufwand:** S (Entfernen) / L (echte Produktiv-Aktivierung)
|
||||
- **Validierung:** Entweder Smoke-Test auf `hermes.kaleschke.info` mit funktionalem Use-Case-Beleg, oder Repo-clean.
|
||||
|
||||
### F-07 · Monitoring-Stack ohne Digest-Pin
|
||||
|
||||
- **Kategorie:** Reproduzierbarkeit / GitOps
|
||||
- **Fundstelle:** `monitoring/docker-compose.yml:3,28,66,84,100,118,276,296`
|
||||
- **Beobachtung:** Prometheus, Alertmanager, Blackbox, Loki, Promtail, Grafana, node-exporter, cAdvisor sind alle nur per Tag gepinnt (`prom/prometheus:v3.7.3`, `grafana/grafana:12.4.3`, ...). Nur `influxdb3-core` hat `@sha256:`. Das widerspricht der Image-Versionierungs-Disziplin der Tier-1-Stateful-Dienste.
|
||||
- **Risiko:** Wenn upstream einen Tag erneut pushed (Versionsdrift, Supply Chain), wird beim Rebuild ein anderer Container deployed — gerade Monitoring sollte stabil sein.
|
||||
- **Empfehlung:** Beim naechsten Komodo-Redeploy aktuellen Digest auslesen und einpinnen. Vorbereitung fuer Renovate (F-12).
|
||||
- **Prioritaet:** Nice to have
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** `grep '@sha256' monitoring/docker-compose.yml` listet alle 10 Services.
|
||||
|
||||
### F-08 · Alert-Regeln zu duenn
|
||||
|
||||
- **Kategorie:** Monitoring
|
||||
- **Fundstelle:** `monitoring/prometheus/alerts.yml`
|
||||
- **Beobachtung:** Exakt 5 Regeln: ExternalConnectivityDown, EndpointDown, EndpointSlow, DiskAlmostFull, MemoryHighUsage, Traefik5xx. Es fehlen:
|
||||
- Borg-Lauf-Frische (ueber `node_exporter` textfile collector oder Pushgateway).
|
||||
- Zertifikatslaufzeit (Blackbox kann `probe_ssl_earliest_cert_expiry`, aber keine Alert-Regel dafuer).
|
||||
- Container-down-Alert (cAdvisor liefert `container_last_seen`).
|
||||
- PostgreSQL-Connection-Saturation.
|
||||
- Loki ingestion-rate / log-volume spike.
|
||||
- InfluxDB-Disk-Pressure.
|
||||
- Backup-Job-Failure.
|
||||
- **Risiko:** Du siehst Probleme nicht, bevor sie weh tun. Cert-Expiry und Borg-Stale sind die schmerzhaftesten Blind-Spots.
|
||||
- **Empfehlung:** Mindestens zwei Regeln nachziehen: `BorgArchiveStale` (>30 h, Pushgateway oder textfile) und `TLSCertExpiryNear` (<14 Tage). Rest als Folge-Sprint.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** M
|
||||
- **Validierung:** Alerts feuern in Test-Bedingung (Borg-Dump-File touch -d backwards).
|
||||
|
||||
### F-09 · Komodo-Self-Bootstrap-Problem
|
||||
|
||||
- **Kategorie:** GitOps / DR
|
||||
- **Fundstelle:** `MASTER 13: Komodo Self-Stack Drift-Recovery 2026-05-04`
|
||||
- **Beobachtung:** Du hattest schon einen Drift-Vorfall (Komodo-Core ran aus `/tmp/*repair.yml`, Mongo-Pfad fehlte). Recovery-ENV liegt als "temporaeres Tier-1-Secret-Material" unter `/mnt/user/appdata/secrets/_komodo_stack_env_recovery_2026-05-04.env` (Doku-Stand).
|
||||
- **Risiko:** Bei Totalausfall musst du Komodo aus Compose-Datei wiederbeleben, dafuer brauchst du die Stack-ENV mit `KOMODO_SECRET_KEY`, `KOMODO_MONGO_PASSWORD`, `KOMODO_PERIPHERY_PASSKEY` etc., die nur als Komodo Stack ENV existieren. Klassisches Henne-Ei.
|
||||
- **Empfehlung:** Komodo-Self-Stack aus Komodos eigener Verwaltung herausnehmen und als handgepflegten `docker compose`-Service in `services/komodo-bootstrap/` halten. Stack-ENV als versiegelte Datei unter `/mnt/user/appdata/secrets/` mit deterministischem Restore-Pfad in RESTORE_MATRIX.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** M
|
||||
- **Validierung:** Komodo-Stack-Datei lebt im Repo unter `services/`, nicht in Komodos eigener Workspace-Sicht.
|
||||
|
||||
### F-10 · Authelia Repo↔Host Drift "by design"
|
||||
|
||||
- **Kategorie:** GitOps / Security
|
||||
- **Fundstelle:** `docs/REPO_MAP.md:48`, `security/authelia/configuration.yml`, `SERVICE_CATALOG 23`
|
||||
- **Beobachtung:** Repo enthaelt Baseline ohne Secrets, OIDC, Users-DB. Manuelles Merge auf den Host noetig. Es gibt keine automatische Konsistenz-Pruefung.
|
||||
- **Risiko:** Repo-Aenderung (z. B. neue ACL-Regel) wird gepusht, aber nie auf den Host gemerged -> Drift, Authelia hinkt der Wahrheit hinterher.
|
||||
- **Empfehlung:** Symmetrisch zum Traefik-Dynamic-Workflow (manueller Sync explizit als Pflicht in WORKFLOW.md). Zusaetzlich ein einfaches Diff-Script `services/authelia-diff.sh`, das `diff` zwischen Repo-Baseline und Host-Datei zeigt, und das im posture-check als Warning auftaucht, wenn die ACL-Sektion differiert.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** Script laeuft, posture-check kennt einen neuen Check `authelia_config_drift`.
|
||||
|
||||
### F-11 · Immich-Restore noch nie geuebt
|
||||
|
||||
- **Kategorie:** Backup / Restore
|
||||
- **Fundstelle:** `docs/RESTORE_MATRIX.md:49`, Restore-Test-Schedule
|
||||
- **Beobachtung:** Vaultwarden / Gitea / Paperless haben Mini-Restore-Tests (2026-05-07). Immich nicht. Immich ist der groesste Datentopf (Familien-Fotos).
|
||||
- **Risiko:** Silent Corruption in Postgres-pgvecto-rs-Daten bemerkst du erst beim Restore-Versuch.
|
||||
- **Empfehlung:** Eigener Sprint: Immich-Restore-Test gegen `/mnt/user/backups/restore-lab/immich/` mit Sub-Set der `immich.dump` und einem Foto-Sample. Smoke-Test = "10 Fotos im Browser sichtbar nach Restore".
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** M
|
||||
- **Validierung:** Report unter `/mnt/user/backups/restore-reports/immich-<datum>.json`.
|
||||
|
||||
### F-12 · Keine Image-Update-Automatik (Renovate o. ae.)
|
||||
|
||||
- **Kategorie:** Wartbarkeit
|
||||
- **Fundstelle:** Repo-weit; `docs/WORKFLOW.md:282-288` (Image-Versionierung)
|
||||
- **Beobachtung:** Digest-Pinning ist konsequent, aber rein manuell. Bei ~30 Images bedeutet das, du musst monatlich fuer Patch-Updates manuell Digests auslesen — oder es bleibt liegen.
|
||||
- **Risiko:** CVE-Patches werden nicht eingespielt, weil "der laufende Stand ist stabil".
|
||||
- **Empfehlung:** Renovate Bot (self-hosted, gegen Gitea), Gitea-Actions-Runner. Renovate oeffnet PRs fuer Patch-/Minor-Updates; Major-Updates werden mit Labels separiert.
|
||||
- **Prioritaet:** Sollte zeitnah (oder Nice to have, je nach Schmerz)
|
||||
- **Aufwand:** M (Initial-Setup ist substantiell)
|
||||
- **Validierung:** Renovate hat erste PRs in Gitea geoeffnet, du mergst eines davon kontrolliert.
|
||||
|
||||
### F-13 · Keine OIDC-SSO fuer User-Apps
|
||||
|
||||
- **Kategorie:** Security / UX
|
||||
- **Fundstelle:** `security/authelia/configuration.yml`, `docs/SECRETS_MAP.md`
|
||||
- **Beobachtung:** Authelia kann OIDC, ist aber nur als ForwardAuth konfiguriert. Nextcloud, Immich, Grafana, Mealie laufen mit eigenen User-DBs.
|
||||
- **Risiko:** N getrennte Passwortspeicher, N getrennte 2FA-Setups, keine zentrale Sperrung bei Account-Kompromittierung. Familie hat keinen einfachen Onboarding-Pfad.
|
||||
- **Empfehlung:** OIDC-Provider in Authelia aktivieren, Nextcloud (via Plugin), Immich (nativer OIDC-Support), Grafana (nativer OIDC-Support) als Clients konfigurieren. Vaultwarden via OIDC-Bridge nur, wenn der Aufwand klar mehrwertig ist — sonst bewusst auslassen.
|
||||
- **Prioritaet:** Sollte zeitnah (groesster Hebel laut Executive)
|
||||
- **Aufwand:** L
|
||||
- **Validierung:** Familienkonto kann sich mit einem Login bei Nextcloud + Immich + Grafana anmelden.
|
||||
|
||||
### F-14 · Kein WAF / Bouncer vor oeffentlichen Apps
|
||||
|
||||
- **Kategorie:** Security
|
||||
- **Fundstelle:** `traefik/docker-compose.yml`, oeffentliche Hosts in `docs/REPO_MAP.md:127-152`
|
||||
- **Beobachtung:** Sechs oeffentliche Apps mit nativer Auth (vault, paperless, mealie, ntfy, git, immich, cloud) ohne IP-Bouncer. Authelia-Regulation greift nur fuer die ForwardAuth-Pfade; Apps mit eigener Auth bekommen den vollen Traffic.
|
||||
- **Risiko:** Credential-Stuffing-Bot-Wellen treffen die App selbst (Nextcloud, Immich) — Logs sind im Loki, aber kein Sperr-Mechanismus.
|
||||
- **Empfehlung:** CrowdSec als Bouncer fuer Traefik (`crowdsecurity/traefik-bouncer`). Nutzt Loki/Logs fuer Erkennung, sperrt IPs auf Traefik-Ebene, bevor sie die Apps treffen.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** M
|
||||
- **Validierung:** CrowdSec-Dashboard zeigt erste Sperren; Test-Brute-Force gegen `nextcloud.kaleschke.info` wird bei N Versuchen geblockt.
|
||||
|
||||
### F-15 · Healthchecks fehlen grossflaechig
|
||||
|
||||
- **Kategorie:** Docker / Operations
|
||||
- **Fundstelle:** Spot-checks: `apps/paperless/docker-compose.yml`, `apps/immich/docker-compose.yml`, `security/authelia/docker-compose.yml`, `traefik/docker-compose.yml` — keiner hat `healthcheck:`-Block.
|
||||
- **Beobachtung:** Restart-Policy ist ueberall `unless-stopped`, aber ohne Healthcheck kann Docker keinen Crash-Loop bei "Container laeuft, aber App tot" erkennen.
|
||||
- **Risiko:** Bei Soft-Failure (Postgres-Connection-Pool tot, Authelia haengt im Storage-Connect) merkst du nichts, weil Container "running" bleibt.
|
||||
- **Empfehlung:** Fuer Tier-1 (Traefik `wget /ping`, Authelia `/api/health`, PostgreSQL `pg_isready`, Komodo `wget /api/healthcheck`) Healthchecks ergaenzen. Fuer Tier-2 schrittweise.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** M (pro Stack 5–15 Min)
|
||||
- **Validierung:** `docker ps` zeigt `(healthy)` neben den Tier-1-Containern.
|
||||
|
||||
### F-16 · `infra/redis` als "shared" deklariert, faktisch nur Paperless
|
||||
|
||||
- **Kategorie:** Architektur-Konsistenz
|
||||
- **Fundstelle:** `infra/redis/docker-compose.yml`, `docs/SERVICE_CATALOG.md:31` ("shared Redis Cache")
|
||||
- **Beobachtung:** Immich, Nextcloud, Mealie haben jeweils eigene Redis-Instanzen. Authelia nutzt bewusst kein Redis (MASTER 13). Paperless nutzt es laut Compose. Effektiv "Paperless-Redis im Frack des shared-Caches".
|
||||
- **Risiko:** Niedrig. Aber: Wenn du `infra/redis` fuer etwas anderes wegnimmst, denkst du, es kostet Paperless was — und das waere der Fall.
|
||||
- **Empfehlung:** Doku-Update: SERVICE_CATALOG 31 praezisieren ("dediziertes Redis fuer Paperless; andere Stacks haben eigene Redis-Instanzen"). Architektur bleibt, nur Etikett ehrlich machen. Alternativ: in `apps/paperless/` als App-internes Netz konsolidieren wie Mealie.
|
||||
- **Prioritaet:** Nice to have
|
||||
- **Aufwand:** S (Doku) / M (Architektur)
|
||||
|
||||
### F-17 · Plex bleibt als Host-Net-Stack
|
||||
|
||||
- **Kategorie:** Security / Architektur
|
||||
- **Fundstelle:** `host-services/plex/docker-compose.yml`, `MASTER 7.4`
|
||||
- **Beobachtung:** Plex laeuft als Host-Net wegen Discovery/GDM. Dokumentierte Ausnahme.
|
||||
- **Risiko:** Plex hat hoehere Angriffsoberflaeche als Apps mit Traefik. Plex-Login wurde mehrfach Ziel von Account-Uebernahmen (Plex.tv-Auth-Issues 2024/25). Bei Plex.tv-Kompromittierung greift Authelia nicht — Plex authentifiziert gegen Plex.tv.
|
||||
- **Empfehlung:** Plex bewusst beibehalten (Doku stuetzt), aber: (a) "Remote Access" in Plex-UI deaktivieren, wenn nur lokal/Tailscale genutzt. (b) Plex-Server nicht in `frontend_net` (waere schaedlich) — bleibt Host-Net, korrekt.
|
||||
- **Prioritaet:** Nice to have
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** Plex `Remote Access` UI zeigt "disabled".
|
||||
|
||||
### F-18 · Nextcloud ohne ForwardAuth, ohne dedizierte Brute-Force-Doku
|
||||
|
||||
- **Kategorie:** Security
|
||||
- **Fundstelle:** `apps/nextcloud/docker-compose.yml`, `MASTER 13: Nextcloud-Entscheidung`
|
||||
- **Beobachtung:** Bewusste Ausnahme (WebDAV/CardDAV). In Nextcloud selbst sind Brute-Force-Schutz, 2FA-Pflicht und App-Passwords konfigurierbar, aber nicht im Repo dokumentiert.
|
||||
- **Risiko:** Familien-Konto mit schwachem Passwort + Nextcloud oeffentlich = direkter Pfad zu Dokumenten/Fotos.
|
||||
- **Empfehlung:** `apps/nextcloud/POST_INSTALL.md` mit Pflicht-Checkliste: Brute-Force-Plugin aktiv, 2FA-Provider TOTP installiert, Admin-Account hat 2FA, "Enforce 2FA for admin group" gesetzt. Optional: `OCC`-Befehle als Skript in `services/nextcloud-policy/`.
|
||||
- **Prioritaet:** Sollte zeitnah
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** Test-Login ohne 2FA als Admin schlaegt fehl.
|
||||
|
||||
### F-19 · Keine Container-Memory-Limits
|
||||
|
||||
- **Kategorie:** Docker / Hardware-Schutz
|
||||
- **Fundstelle:** Spot-checks aller Composes
|
||||
- **Beobachtung:** Keine `mem_limit:` oder `deploy.resources.limits` Sektion in Tier-1- oder Tier-2-Stacks.
|
||||
- **Risiko:** Bei Image-Bug oder Memory-Leak (z. B. Immich-ML, Paperless-OCR-Loop) kann ein Container den Host in OOM treiben. Posture-Check + Docker-Critical-Events sehen das nachher, aber praeventiver waere Container-Limit + Docker-OOM-Kill fuer den richtigen Prozess.
|
||||
- **Empfehlung:** Fuer Tier-1 (Postgres, Authelia, Traefik, Komodo) sanfte Limits setzen (z. B. Postgres 2 GB, Authelia 256 MB, Traefik 256 MB). Fuer Immich-ML-Container ein hartes Limit, das Verhungern verhindert.
|
||||
- **Prioritaet:** Nice to have
|
||||
- **Aufwand:** M
|
||||
- **Validierung:** `docker stats` zeigt `MEM USAGE / LIMIT` ungleich `unlimited`.
|
||||
|
||||
### F-20 · Paperless-DBPass weiter als Stack-ENV (dokumentierte Ausnahme)
|
||||
|
||||
- **Kategorie:** Secrets
|
||||
- **Fundstelle:** `MASTER 13: Secrets in Komodo Stacks`, `docs/SECRETS_MAP.md:25`
|
||||
- **Beobachtung:** Paperless unterstuetzt `_FILE` nicht fuer DB-Pass. Bewusste Ausnahme.
|
||||
- **Risiko:** Stack-ENV liegt in Komodo-DB (Mongo), nicht im Repo. Bei Komodo-Mongo-Backup-Luecke fehlt das Passwort beim Restore.
|
||||
- **Empfehlung:** Erweiterung der Disaster-Recovery-Doku: explizite Liste aller "Stack-ENV-only"-Secrets mit Zeiger, dass `komodo-mongo.archive.gz` fuer Restore zwingend ist, oder die ENV manuell vorgehalten werden muss (in Vaultwarden + externer Notiz).
|
||||
- **Prioritaet:** Nice to have
|
||||
- **Aufwand:** S
|
||||
- **Validierung:** DR-Doc Abschnitt "Stack-ENV-Werte" referenziert konkrete Restore-Pfade.
|
||||
|
||||
---
|
||||
|
||||
# D. Risiko-Matrix
|
||||
|
||||
| Risiko | Bereich | Wahrscheinlichkeit | Auswirkung | Prioritaet | Massnahme |
|
||||
|---|---|---|---|---|---|
|
||||
| Borg-Passphrase weg -> Restore unmoeglich | Backup | niedrig | katastrophal | P0 | F-02 analoge Sicherung |
|
||||
| Hetzner-Account-Verlust -> halbes 3-2-1 | Backup | niedrig-mittel | hoch | P0/P1 | F-03 Zweitziel |
|
||||
| AdGuard-Admin-Manipulation aus LAN | Security | niedrig | hoch (DNS-Hijack) | P0 | F-01 Bind auf Tailscale |
|
||||
| Operator-Pwd-Leak -> 2FA fehlt fuer Borg-UI/Code-Server | Security | mittel | hoch | P0 | F-04 2FA-ACL erweitern |
|
||||
| Komodo-Self-Bootstrap-Failure nach Totalausfall | DR | niedrig | hoch | P1 | F-09 Bootstrap-Datei in `services/` |
|
||||
| Authelia Repo↔Host Drift unbemerkt | GitOps/Security | mittel | mittel | P1 | F-10 Diff-Check |
|
||||
| Immich Silent Corruption -> kein Restore-Test belegt | Backup | niedrig | sehr hoch (Familien-Fotos) | P1 | F-11 Restore-Test |
|
||||
| Cert-Expiry unbemerkt -> Public Apps down | Operations | niedrig | mittel | P1 | F-08 Alert-Regel |
|
||||
| Nextcloud Brute-Force ohne Bouncer | Security | mittel | mittel-hoch | P1 | F-14 CrowdSec / F-18 Nextcloud-Haerten |
|
||||
| Image-Update-Stillstand -> CVE bleibt | Security | mittel | mittel | P1 | F-12 Renovate |
|
||||
| Hermes-Wartungsschuld | Wartbarkeit | hoch | niedrig | P1 | F-06 Entscheidung |
|
||||
| Repo-Altstaende ueberleben -> Doppel-Deploy | GitOps | mittel | niedrig | P1 | F-05 Cleanup |
|
||||
| OOM durch unlimitierte Container | Hardware | niedrig | mittel | P2 | F-19 mem_limit |
|
||||
| Healthcheck-Luecke -> Soft-Failure stumm | Operations | mittel | niedrig | P2 | F-15 Healthchecks |
|
||||
| Monitoring-Stack ohne Digest-Pin | Reproduzierbarkeit | niedrig | niedrig | P2 | F-07 Digests + Renovate |
|
||||
| Hardware-SPOF (kein zweiter Host) | Hardware | niedrig | sehr hoch | P3 | Cold-Standby / 2. Host |
|
||||
|
||||
---
|
||||
|
||||
# E. Zielarchitektur (realistisch fuer privates Homelab)
|
||||
|
||||
**Hardware**
|
||||
|
||||
- 1× Unraid-Host (bestehend) als Production. CPU mit AVX2/AVX-512 fuer Immich-ML. ≥ 32 GB RAM (fuer 2× Postgres + Immich-ML + Loki/Prometheus + 2 VMs).
|
||||
- 2× NVMe als BTRFS-RAID1-Cache, sobald Cache-Auslastung > 70 % (STORAGE_LAYOUT 15.3).
|
||||
- Parity-Disk ≥ groesste Daten-Disk.
|
||||
- USV mit USB-Steuerung (NUT-faehig: APC Back-UPS RS 700+, Eaton 3S, CyberPower CP1500EPFCLCD). Direkter Shutdown bei Power-Loss.
|
||||
- Optional: zweiter alter Mini-PC oder NUC als Cold-Standby mit Tailscale, der den letzten Komodo-Bootstrap + Gitea-Mirror tragen kann.
|
||||
|
||||
**Netzwerk**
|
||||
|
||||
- FritzBox (bestehend) als Router + NAT.
|
||||
- VLANs nur wenn IoT-WLAN dazukommt (FritzBox-Gast-WLAN reicht fuer Anfang).
|
||||
- DNS: AdGuard -> Unbound (bestehend). Admin-UI nur Tailscale.
|
||||
- Tailscale (bestehend): Operator-Pfad. Subnet-Router optional fuer LAN-Devices ueber Tailscale.
|
||||
|
||||
**Storage**
|
||||
|
||||
- Cache `only` fuer `appdata`, `system`, `domains` (bestehend STORAGE_LAYOUT 4).
|
||||
- Disk1 (XFS) fuer `services`, `documents`, `photos`, `backups`, `media`, `finance`, `projekte`.
|
||||
- Externe Wechselplatte (XFS) fuer Cold-Off-Site mit fester monatlicher Rotation.
|
||||
|
||||
**Ordnerstruktur (Repo)**
|
||||
|
||||
- Beibehalten. Nur Cleanup von Altstaenden (F-05). Naming `kebab-case`-Migration aus STORAGE_LAYOUT 6 schrittweise.
|
||||
|
||||
**Docker**
|
||||
|
||||
- Compose-only via Komodo (bestehend).
|
||||
- Digest-Pin fuer alle Images (F-07).
|
||||
- Healthchecks fuer Tier-1 (F-15).
|
||||
- Mem-Limits fuer Tier-1 + Immich-ML (F-19).
|
||||
- App-interne Netze fuer Stack-Isolation (bestehend).
|
||||
|
||||
**Reverse Proxy**
|
||||
|
||||
- Traefik v3 (bestehend), DNS-Challenge, Wildcard.
|
||||
- Dynamic Config nur fuer Middlewares, TLS, Dashboard (bestehend).
|
||||
- CrowdSec-Bouncer (F-14) fuer oeffentliche Apps.
|
||||
|
||||
**Auth**
|
||||
|
||||
- Authelia als ForwardAuth **und** OIDC-Provider (F-13).
|
||||
- Nextcloud, Immich, Grafana via OIDC.
|
||||
- 2FA-Pflicht fuer alle Operator-Dienste (F-04).
|
||||
- Komodo bewusste Ausnahme (bestehend).
|
||||
|
||||
**Backup**
|
||||
|
||||
- Borg lokal (`/mnt/user/backups/borg/`) + Borg Hetzner + Wechselplatte.
|
||||
- Pre-Dump-Hooks (bestehend).
|
||||
- Borg-Passphrase off-system analog (F-02).
|
||||
- Restore-Tests automatisiert (F-11 Immich, dann andere via CI).
|
||||
|
||||
**Monitoring**
|
||||
|
||||
- `monitoring/`-Stack als alleinige Quelle. Altstaende raus (F-05).
|
||||
- Family-View-Dashboard in Grafana (alles gruen, Backup-Frische, Cert-Tage).
|
||||
- Alerts ausgebaut (F-08).
|
||||
- Posture-Check + Docker-Critical-Events -> ntfy `homelab-alerts` (bestehend).
|
||||
|
||||
**Dokumentation**
|
||||
|
||||
- Aktuelle Doku-Tiefe halten.
|
||||
- `SERVICES_RECOVERY.md` und `STORAGE_LAYOUT.md` (Active) finalisieren.
|
||||
- Familien-/User-Onboarding-Doku als eigenes kleines Dokument.
|
||||
|
||||
**GitOps**
|
||||
|
||||
- Gitea + Komodo (bestehend).
|
||||
- GitHub-Push-Mirror (umgesetzt, bestaetigt durch MASTER 7.1).
|
||||
- Renovate-Bot gegen Gitea (F-12).
|
||||
- Optional: Staging-Branch + zweites Komodo-Ziel in Tailscale-VM (Phase 3).
|
||||
|
||||
**Restore**
|
||||
|
||||
- RESTORE_MATRIX bleibt fuehrend.
|
||||
- Restore-Lab unter `/mnt/user/backups/restore-lab/` (bestehend).
|
||||
- Immich-Restore als Luecke schliessen (F-11).
|
||||
- Komodo-Self-Bootstrap raus aus Komodo (F-09).
|
||||
|
||||
---
|
||||
|
||||
# F. Priorisierte Massnahmenliste
|
||||
|
||||
| # | Aufgabe | Warum | Kategorie | Prio | Aufwand | Risiko (bei Nicht-Tun) | Mehrwert | Abhaengigkeiten | Validierung |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 1 | Borg-Passphrase analog sichern | DR-SPOF schliessen | Backup | P0 | S | katastrophal | DR-Sicherheit | — | Wert ohne Host abrufbar |
|
||||
| 2 | AdGuard-Admin auf Tailscale-IP binden | LAN-Angriffsflaeche | Security | P0 | S | hoch | LAN-IoT-Haertung | — | `ss -ltnp` zeigt nur Tailscale |
|
||||
| 3 | 2FA-ACL erweitern (borg, code, files, traefik) | Operator-Pwd-Leak | Security | P0 | S | hoch | 2FA-Coverage | Authelia-TOTP-Setup | Login erzwingt 2FA |
|
||||
| 4 | Altstaende `ops/grafana-influxdb`+`ops/loki` `git rm` | Repo-Hygiene, kein Re-Deploy | GitOps | P0 | S | niedrig | Klarheit | Tag setzen | Policy-Check clean |
|
||||
| 5 | Hermes 60-Tage-Deadline | Wartungsschuld | App | P1 | S/L | mittel | Komplexitaet raus | Operator-Entscheidung | Entweder produktiv oder weg |
|
||||
| 6 | Immich-Restore-Test einrichten | Groesster Datentopf ungeprueft | Backup | P1 | M | hoch | Restore-Vertrauen | Restore-Lab-Pfad | Smoke-Test-Report |
|
||||
| 7 | Renovate-Bot in Gitea | manuelle Digest-Pflege | Wartung | P1 | M | mittel | Update-Hygiene | Gitea-Runner | erste PR offen |
|
||||
| 8 | Alert-Regeln (Borg-Frische, Cert-Expiry) | Blind-Spot Operations | Monitoring | P1 | M | mittel | echte Alerts | Pushgateway o. textfile | Alert in Test |
|
||||
| 9 | Family-View-Dashboard Grafana | Morgens 30 s Check | Monitoring | P1 | M | niedrig | Uebersicht | Datasources stehen | Dashboard funktioniert |
|
||||
| 10 | Komodo-Self-Bootstrap als `services/komodo-bootstrap/` | Henne-Ei-Problem | GitOps/DR | P1 | M | mittel | sauberer Recovery-Pfad | Komodo-Stack-Doku | Bootstrap aus Repo allein moeglich |
|
||||
| 11 | Authelia-Drift-Diff-Check in posture-check | Repo↔Host Drift | GitOps | P1 | S | mittel | Drift-Detektion | posture-check-Erweiterung | neuer Check sichtbar |
|
||||
| 12 | Healthchecks Tier-1 | Soft-Failure-Erkennung | Docker | P1 | M | niedrig | Self-Healing-Trigger | — | `docker ps` zeigt `healthy` |
|
||||
| 13 | CrowdSec-Bouncer vor Traefik | oeffentliche Apps schuetzen | Security | P1 | M | mittel | Brute-Force-Stop | Traefik-Middleware | Test-IP wird geblockt |
|
||||
| 14 | Nextcloud-Haertung dokumentieren | Public App + native Auth | Security | P1 | S | mittel | App-Haertung | Plugin-Install | 2FA-erzwingt |
|
||||
| 15 | Authelia OIDC-Provider + Nextcloud/Immich/Grafana | SSO, Familien-Onboarding | Security/UX | P2 | L | niedrig | hoher Mehrwert | Authelia-OIDC-Setup | SSO-Login funktioniert |
|
||||
| 16 | Immich-Smartphone-Auto-Backup fuer Familie | Killer-App fuer Familie | App | P2 | S | niedrig | hoher Mehrwert | — | Familien-Foto in Immich |
|
||||
| 17 | Monitoring-Stack Digests + Renovate-Pin | Reproduzierbarkeit | GitOps | P2 | S | niedrig | konsistent | Renovate optional | `@sha256` an allen Images |
|
||||
| 18 | Mem-Limits Tier-1 + Immich-ML | OOM-Schutz | Hardware/Docker | P2 | M | niedrig | Schutz | — | `docker stats` zeigt Limits |
|
||||
| 19 | Off-Site-Zweitziel (rsync.net o. Wechselplatte) | Single-Provider | Backup | P2 | M | mittel | 3-2-1 echt | Borg-Config | beide Repos < 7d |
|
||||
| 20 | Staging-Branch + 2. Komodo-Ziel | Risiko-Aenderung testbar | GitOps | P3 | L | niedrig | Reife | 2. VM/Host | Deploy auf staging klappt |
|
||||
|
||||
---
|
||||
|
||||
# G. Refactoring-Plan (Sprints)
|
||||
|
||||
## Sprint 0 — Sicherheitsnetz und Ist-Zustand sichern (1 Tag)
|
||||
|
||||
- **Ziel:** Du kannst danach im schlimmsten Fall alles, was du jetzt aenderst, sicher zurueckrollen.
|
||||
- **Aufgaben:**
|
||||
- Git-Tag `audit-2026-05-25-baseline` auf `master` setzen und nach Gitea + GitHub-Mirror pushen.
|
||||
- Borg-Lauf manuell ausloesen ("freshen up"), Erfolg im Log dokumentieren.
|
||||
- Aktuellen Komodo-Mongo-Dump verifizieren (`mongorestore --dry-run`).
|
||||
- `docs/MIGRATION_LOG.md` Eintrag "Audit-Sprint-Start".
|
||||
- **Erfolgskriterium:** Tag pushed, Borg-Lauf gruen, Mongo-Dump verifiziert.
|
||||
- **Validierung:** `git fetch && git tag | grep audit-2026-05-25-baseline` und `ls /mnt/user/backups/borg/dumps/latest/` zeigt fresh.
|
||||
- **Rollback:** N/A (rein additiv).
|
||||
- **Risiko bei Nichtumsetzung:** Keine Notbremse fuer Sprint 1.
|
||||
|
||||
## Sprint 1 — Offensichtliche Risiken entschaerfen (1 Woche)
|
||||
|
||||
- **Ziel:** P0-Risiken weg, Repo-Hygiene wieder gruen.
|
||||
- **Aufgaben (in dieser Reihenfolge):**
|
||||
1. F-02 Borg-Passphrase analog sichern (off-system, kein Code-Change).
|
||||
2. F-01 AdGuard-Admin-Port auf Tailscale-IP — Edit `host-services/Adguard/docker-compose.yml:16`.
|
||||
3. F-04 Authelia ACL erweitern (`two_factor` fuer borg, code, files, traefik) — Edit `security/authelia/configuration.yml` + Host-Sync.
|
||||
4. F-05 Altstaende `ops/grafana-influxdb/`, `ops/loki/` entfernen — `git rm`, MIGRATION_LOG.
|
||||
5. Policy-Check-Warnings `SEC001` (ddns-updater, scrutiny) aufraeumen.
|
||||
- **Erfolgskriterium:** Policy-Check 0 Warnings fuer SEC001, AdGuard-Admin nur via Tailscale, 2FA-Login auf borg.kaleschke.info.
|
||||
- **Validierung:** Policy-Check-Report; Browser-Test mit/ohne 2FA-Cookie.
|
||||
- **Rollback:** Commit-Revert pro Block.
|
||||
|
||||
## Sprint 2 — GitOps-Robustheit (1–2 Wochen)
|
||||
|
||||
- **Ziel:** Self-Bootstrap-Problem entschaerft, Drift-Detektion automatisiert.
|
||||
- **Aufgaben:**
|
||||
1. F-09 Komodo-Bootstrap-Compose nach `services/komodo-bootstrap/` extrahieren + dokumentierter Standalone-Restore-Pfad.
|
||||
2. F-10 Authelia-Drift-Diff in posture-check ergaenzen.
|
||||
3. F-11 Immich-Restore-Test einrichten (analog zu vaultwarden/gitea/paperless).
|
||||
4. F-06 Hermes-Entscheidung mit 60-Tage-Deadline schriftlich.
|
||||
- **Erfolgskriterium:** Komodo laesst sich aus Repo allein wiederherstellen. Posture-Check zeigt `authelia_config_drift: false`. Immich-Restore-Report unter `/mnt/user/backups/restore-reports/`.
|
||||
- **Validierung:** Trockenversuch (Komodo-Container stoppen, `docker compose up -d` aus `services/komodo-bootstrap/`).
|
||||
- **Rollback:** Bootstrap-Verzeichnis loeschen, Komodo-Self-Stack wie vorher.
|
||||
|
||||
## Sprint 3 — Backup & Restore belastbar machen (2–3 Wochen)
|
||||
|
||||
- **Ziel:** 3-2-1 echt, Restore-Tests breiter, Stack-ENV im DR-Pfad.
|
||||
- **Aufgaben:**
|
||||
1. F-03 Zweitziel: Wechselplatten-Rotation dokumentieren ODER zweites Borg-Repo (rsync.net / BorgBase EU2).
|
||||
2. F-20 Stack-ENV-Liste in DR-Doc explizit machen (Restore-Reihenfolge).
|
||||
3. Borg-Verifikation Cron fuer `borg check --repository-only` weekly (STORAGE_LAYOUT 8.4).
|
||||
4. Quartalsweise End-to-End-Restore-Drill in Schedule aufnehmen.
|
||||
- **Erfolgskriterium:** Beide Off-Site-Ziele < 7 Tage alt; DR-Doc enthaelt "ENV-Restore-Reihenfolge".
|
||||
- **Validierung:** `borg list` gegen beide Repos.
|
||||
|
||||
## Sprint 4 — Monitoring & Alerting ausbauen (2 Wochen)
|
||||
|
||||
- **Ziel:** Sichtbarkeit auf das, was wirklich weh tut.
|
||||
- **Aufgaben:**
|
||||
1. F-08 Alert-Regeln: `BorgArchiveStale`, `TLSCertExpiryNear`, `ContainerDown`, `PostgresConnSaturation`.
|
||||
2. F-15 Healthchecks fuer Traefik, Authelia, Postgres, Komodo, Gitea.
|
||||
3. F-07 Digest-Pin in `monitoring/docker-compose.yml`.
|
||||
4. Family-View-Dashboard in Grafana (1 Panel: Service-Up, 1 Panel: Backup-Frische, 1 Panel: Cert-Tage, 1 Panel: Disk-Fuellung).
|
||||
- **Erfolgskriterium:** Family-View zeigt alles gruen; Cert-Alert feuert in Test (Datum vorgespult).
|
||||
- **Validierung:** Dashboard sichtbar unter `monitoring.kaleschke.info/d/family-view`.
|
||||
|
||||
## Sprint 5 — Auth-Konsolidierung & Frontdoor-Haertung (3–4 Wochen)
|
||||
|
||||
- **Ziel:** SSO fuer die Familie, Brute-Force-Bouncer vor oeffentlichen Apps.
|
||||
- **Aufgaben:**
|
||||
1. F-13 Authelia OIDC-Provider aktivieren.
|
||||
2. Nextcloud OIDC-Plugin + Test-Login.
|
||||
3. Immich OIDC + Test-Login.
|
||||
4. Grafana OIDC + Test-Login.
|
||||
5. F-14 CrowdSec-Bouncer vor Traefik.
|
||||
6. F-18 Nextcloud-Haertung-Dokument + 2FA-Pflicht.
|
||||
- **Erfolgskriterium:** Familien-Konto loggt sich mit einem Login bei drei Apps ein; CrowdSec sperrt Test-IP nach N fehlerhaften Versuchen.
|
||||
- **Validierung:** OIDC-Sequenz im Browser ohne Eingabe-Wiederholung; CrowdSec-Dashboard zeigt Sperre.
|
||||
|
||||
## Sprint 6 — Automatisierung und Nerd-Level (laufend)
|
||||
|
||||
- **Ziel:** Image-Update-Pipeline, optional Staging.
|
||||
- **Aufgaben:**
|
||||
1. F-12 Renovate-Bot gegen Gitea.
|
||||
2. F-19 Mem-Limits Tier-1.
|
||||
3. Restore-Test-CI via Gitea Actions (P3).
|
||||
4. Optional: Staging-Branch + zweites Komodo-Ziel in Tailscale-VM (P3).
|
||||
5. Optional: Firefly III / Actual Budget fuer `/mnt/user/finance`.
|
||||
- **Erfolgskriterium:** Renovate-PRs erscheinen woechentlich; mindestens ein automatisches Patch-Update gemerged.
|
||||
|
||||
---
|
||||
|
||||
# H. Fehlende Informationen
|
||||
|
||||
> Nur, was den Audit konkret schaerfer machen wuerde.
|
||||
|
||||
| Frage | Warum | Bereich | Kommando / Datei |
|
||||
|---|---|---|---|
|
||||
| CPU-Modell, RAM-Groesse, Mainboard | Hardware-Bewertung, OOM-Risiko, Immich-ML-Eignung, AVX-Verfuegbarkeit | Hardware | `cat /proc/cpuinfo \| grep -E 'model name\|flags'`, `free -h`, `dmidecode -t baseboard \| head -20` |
|
||||
| USV vorhanden? Modell? | DR-Beurteilung Power-Loss, Shutdown-Pfad | Hardware/DR | physische Sichtpruefung; `apcaccess` falls APC mit NUT |
|
||||
| Stromverbrauch idle / Last | Betriebskosten, Sizing | Hardware | Smartmeter / Tibber-API |
|
||||
| NIC-Speed (1 GbE? 2.5 GbE?) | Backup-Durchsatz, Plex-Streaming | Netzwerk | `ip -br link`, `ethtool eth0` |
|
||||
| Disk-Inventar (Anzahl, Modelle, Alter) | Storage-Health, Replacement-Plan | Storage | `lsblk -o NAME,SIZE,MODEL,SERIAL`, Scrutiny-UI |
|
||||
| Aktueller Cache-Fuellstand | Wann zweite NVMe? | Storage | `df -h /mnt/cache` |
|
||||
| FritzBox-Modell + Firmware | Net-Sicherheit, VLAN-Faehigkeit | Netzwerk | FritzBox-UI / `fritzconnection` |
|
||||
| Tatsaechlich genutzte Plex- vs. ungenutzte App | Konsolidierungs-Belege | App-Landschaft | Plex-Server-Logs, ggf. Glances-Container-CPU pro Stack |
|
||||
| Existiert `/mnt/user/finance/`-Share schon? | Ist Firefly-Vorbereitung trivial? | Storage | `ls /mnt/user/finance/` |
|
||||
| Authelia Live-User-DB-Tiefe (Anzahl User, 2FA-Status) | 2FA-Coverage-Bewertung | Security | `cat /mnt/user/appdata/authelia/config/users_database.yml` (nur Strukturansicht, keine Hashes hier zitieren) |
|
||||
| Komodo-Mongo-Dump letzter Integrity-Check | F-09-Vorbereitung | Backup | `mongorestore --dry-run --archive=komodo-mongo.archive.gz --gzip` |
|
||||
| Aktuelle Cert-Restlaufzeit | F-08-Test-Vorbereitung | Operations | `openssl s_client -connect git.kaleschke.info:443 -servername git.kaleschke.info < /dev/null \| openssl x509 -noout -dates` |
|
||||
|
||||
---
|
||||
|
||||
# I. Pruefkommandos (Linux / Unraid / Docker / Windows)
|
||||
|
||||
> Strukturiert nach Bereich. Sicher zum Ausfuehren am Host.
|
||||
|
||||
### Hardware
|
||||
|
||||
```bash
|
||||
# CPU + Flags (AVX fuer Immich-ML)
|
||||
cat /proc/cpuinfo | awk '/model name|flags/ {print; if(/flags/) exit}'
|
||||
|
||||
# RAM
|
||||
free -h
|
||||
dmidecode -t memory | grep -E "Size|Speed" | head -20
|
||||
|
||||
# Mainboard
|
||||
dmidecode -t baseboard | head -20
|
||||
|
||||
# PCI / SATA / NVMe
|
||||
lspci
|
||||
nvme list
|
||||
lsblk -o NAME,SIZE,MODEL,SERIAL,FSTYPE,MOUNTPOINT,VENDOR
|
||||
|
||||
# SMART
|
||||
smartctl -a /dev/nvme0n1 | head -40
|
||||
smartctl -a /dev/sdb | head -40
|
||||
|
||||
# Stromverbrauch (Unraid Plugin oder ipmitool falls IPMI)
|
||||
sensors | head -30
|
||||
```
|
||||
|
||||
### Filesystem / Storage / Mounts
|
||||
|
||||
```bash
|
||||
# Filesystem-Typen (Hard Rule 12.1)
|
||||
findmnt -no FSTYPE /mnt/cache /mnt/disk1 /boot
|
||||
mount | grep -E "ntfs3|fuseblk" # darf leer sein
|
||||
|
||||
# Share-Settings
|
||||
ls -la /boot/config/shares/
|
||||
|
||||
# Cache-Fuellstand
|
||||
df -h /mnt/cache /mnt/disk1 /mnt/user
|
||||
du -sh /mnt/user/appdata/* | sort -hr | head -20
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Container-Inventur
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | sort
|
||||
docker ps -a --filter "status=exited" --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
|
||||
|
||||
# Netzwerke
|
||||
docker network ls
|
||||
docker network inspect frontend_net | jq '.[0].Containers | keys'
|
||||
docker network inspect backend_net | jq '.[0].Internal'
|
||||
|
||||
# Volumes ohne Container (Waisen)
|
||||
docker volume ls -qf dangling=true
|
||||
|
||||
# Effektive Ports
|
||||
ss -ltnp | sort -k4
|
||||
|
||||
# Healthchecks
|
||||
docker ps --format "{{.Names}}\t{{.Status}}" | grep -E "healthy|unhealthy|starting"
|
||||
```
|
||||
|
||||
### Security
|
||||
|
||||
```bash
|
||||
# Privileged-Container und Docker-Socket-Mounts
|
||||
for c in $(docker ps -q); do
|
||||
docker inspect "$c" --format '{{.Name}}: priv={{.HostConfig.Privileged}}; sock={{range .HostConfig.Binds}}{{println .}}{{end}}'
|
||||
done | grep -E "priv=true|docker.sock"
|
||||
|
||||
# Direkte Host-Ports
|
||||
docker ps --format "{{.Names}}: {{.Ports}}" | grep -v "^[^:]*: $"
|
||||
|
||||
# Secret-Datei-Rechte
|
||||
ls -la /mnt/user/appdata/secrets/
|
||||
stat -c "%a %n" /mnt/user/appdata/secrets/*.txt
|
||||
```
|
||||
|
||||
### Backup / Restore
|
||||
|
||||
```bash
|
||||
# Borg-Frische
|
||||
ls -lat /mnt/user/backups/borg/dumps/latest/ | head
|
||||
find /mnt/user/backups/borg/dumps/latest -mmin +1440 -type f # aelter 24h
|
||||
|
||||
# Borg-Repo (Passphrase per File)
|
||||
export BORG_PASSPHRASE=$(cat /mnt/user/appdata/secrets/borg_repo_passphrase.txt)
|
||||
borg list ssh://... --short | tail -5
|
||||
borg info ssh://... ::Taegliche-Sicherung-2026-05-25T05:52:44.157
|
||||
|
||||
# Posture-Check
|
||||
cat /mnt/user/services/posture-check/last.json | jq '.warning_count, .critical_count'
|
||||
```
|
||||
|
||||
### Netzwerk / DNS
|
||||
|
||||
```bash
|
||||
# Tailscale
|
||||
tailscale status
|
||||
|
||||
# DNS auf AdGuard testen
|
||||
dig @127.0.0.1 git.kaleschke.info
|
||||
dig @127.0.0.1 example.com # Unbound-Recursion
|
||||
|
||||
# Cert-Restlaufzeit
|
||||
for h in vault git immich cloud paperless mealie ntfy; do
|
||||
echo -n "$h.kaleschke.info: "
|
||||
openssl s_client -connect ${h}.kaleschke.info:443 -servername ${h}.kaleschke.info </dev/null 2>/dev/null \
|
||||
| openssl x509 -noout -dates 2>/dev/null
|
||||
done
|
||||
```
|
||||
|
||||
### GitOps-Konsistenz
|
||||
|
||||
```bash
|
||||
# Komodo Stack-Workspace vs. Repo
|
||||
cd /mnt/user/services/stacks/<stackname>
|
||||
git rev-parse HEAD
|
||||
git status --short
|
||||
|
||||
# Webhook-Liveness
|
||||
docker logs komodo-core 2>&1 | grep -i "webhook\|deploy" | tail -20
|
||||
```
|
||||
|
||||
### Windows (lokal)
|
||||
|
||||
```powershell
|
||||
# Repo-Status
|
||||
git status --short
|
||||
git fetch origin
|
||||
git log origin/master..HEAD --oneline # ungepushte Commits
|
||||
git log HEAD..origin/master --oneline # ungepullte Commits
|
||||
|
||||
# Policy-Check
|
||||
.\ops\policy-checks\check_repo.ps1
|
||||
|
||||
# Restore-Freshness
|
||||
.\ops\restore-tests\check-restore-freshness.ps1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# J. Community- / Best-Practice-Abgleich
|
||||
|
||||
> Nur fuer die Architekturentscheidungen, bei denen der Markt eindeutig ist oder Gegenpositionen relevant sind.
|
||||
|
||||
| Entscheidung | Markt-Best-Practice | Stuetzende Quellen | Bewertung |
|
||||
|---|---|---|---|
|
||||
| Traefik mit Docker-Labels statt File-Provider | Standard in Selfhosted (siehe `awesome-selfhosted-docker`, Smarthome-Beginner Templates) | Traefik-Doc v3 docs.traefik.io/providers/docker | passt zu MASTER 13 (Wechsel 2026-03-28) |
|
||||
| DNS-Challenge mit Cloudflare statt HTTP-01 | Standard fuer Wildcard und reduzierte Angriffsflaeche | acme.sh / lego docs | passt, korrekt |
|
||||
| Authelia ForwardAuth statt Authentik | Authelia ist leichtgewichtiger, Authentik maechtiger; beide valide | r/selfhosted-Konsens 2024-25 | Authelia richtig fuer Single-Family-Setup |
|
||||
| Authelia ohne Redis-Session-Backend | Markt-Standard ist mit Redis; deine Vereinfachung ist begruendet (MASTER 13 2026-05-04) | Authelia-Doc | Trade-off klar; Bewertung: vertretbar fuer Homelab |
|
||||
| Komodo statt Portainer/Dockge | Komodo ist neuer (2024), Dockge etabliert, Portainer kommerziell | Selfh.st 2025 Comparison | Komodo legitim, mehr GitOps-nativ als Dockge |
|
||||
| Borg statt Restic/Kopia | Borg ist klassische Wahl fuer Linux-Backup mit Deduplikation; Kopia/Restic gewinnen mit Multi-Backend | r/datahoarder, ServeTheHome 2024 | Borg passt zu Unraid-Stack; bewusste Vereinfachung |
|
||||
| Glance statt Homepage als Single-Dashboard | beide auf Augenhoehe; Homepage etablierter, Glance moderner, schneller, mit Live-Widgets | github.com/glanceapp/glance vs. github.com/gethomepage/homepage | Glance legitim; Bewertung: deine Wahl ist verteidigbar |
|
||||
| Immich nicht hinter Authelia ForwardAuth | offizielle Immich-Doku raet bei nativer App-Auth davon ab, weil Sync-Clients OIDC oder direkte Auth brauchen | immich.app/docs/administration/reverse-proxy | korrekt; OIDC spaeter (F-13) ist der Weg |
|
||||
| Nextcloud klassisch statt AIO | NC-AIO ist offizielle Empfehlung fuer Neuaufbau, klassisch hat mehr Flexibilitaet fuer GitOps | NC-Blog 2024 | bewusste Ausnahme MASTER 13; vertretbar, da GitOps-Anbindung wichtiger |
|
||||
| Single-Host + Borg statt Proxmox-Cluster + ZFS-Send | fuer Familien-Homelab ist Cluster Overkill | r/homelab, LTT-Forum | Single-Host korrekt; Cold-Standby (Sprint 6) ist die richtige naechste Stufe |
|
||||
| AdGuard + Unbound statt Pi-hole | aequivalent; AdGuard hat moderne UI, Unbound recursion | gowri/networkchuck Tutorials 2024 | passt |
|
||||
| Posture-Check als Skript statt Goss/InSpec | fuer Single-Host pragmatisch | Goss ist maechtiger, aber Overkill | Skript-Loesung legitim |
|
||||
| Renovate gegen Gitea | mehrere Erfahrungsberichte in Gitea-Issues + Renovate-Docs | docs.renovatebot.com/modules/platform/gitea/ | Standard-Pfad |
|
||||
| CrowdSec vor Traefik | starker Trend 2024-25 in Selfhosted-Community | crowdsec.net/blog, Marius-Hosting-Tutorials | sinnvolle Haertung |
|
||||
|
||||
**Gegenpositionen, die du kennen solltest:**
|
||||
|
||||
- **"Authelia OIDC ist kompliziert, lieber Authentik."** Korrekt, wenn du auch B2B-SAML brauchst. Fuer reine Familien-OIDC ist Authelia leichter wartbar.
|
||||
- **"CrowdSec laedt zentrale Reputation-Listen -> Privacy-Bedenken."** Stimmt, du kannst Local-Only-Mode fahren. Fuer Homelab egal.
|
||||
- **"Renovate-Bot erzeugt Laerm."** Mit Group/Schedule-Rules zaehmbar. Wert > Laerm.
|
||||
- **"Komodo ist zu jung."** Gegenargument: du benutzt es seit Q1/2026 produktiv, Major-Inzidenz war beherrschbar. Der Wechsel zurueck zu Portainer/Dockge waere hoehere Kosten als der Reifegrad-Nachteil.
|
||||
|
||||
---
|
||||
|
||||
# K. Endziel — "Nerd-Level Homelab"
|
||||
|
||||
So sieht dein Homelab aus, wenn es wirklich auf Senior-Level ist:
|
||||
|
||||
**Betrieb im Alltag**
|
||||
|
||||
- Morgens 30 Sekunden auf `monitoring.kaleschke.info`: Family-View zeigt 7 Tier-1-Services gruen, Backup-Job in der Nacht hat 100 % Files erfasst, alle Certs > 30 Tage, Disk < 80 %.
|
||||
- Push-Benachrichtigung auf dem Handy nur, wenn wirklich etwas brennt (Posture-Check critical, Borg > 30 h, Endpoint down ≥ 8 Min, Cert < 14 Tage).
|
||||
- Familienmitglieder loggen sich mit einem Login bei Nextcloud, Immich, Mealie ein. 2FA per TOTP-App, kein App-by-App-Passwortzettel mehr.
|
||||
|
||||
**Updates**
|
||||
|
||||
- Renovate oeffnet woechentlich 5–10 Pull-Requests in Gitea fuer Patch-Versionen. Du siehst sie im Web-UI, pruefst Release Notes, klickst Merge. Komodo deployt automatisch via Webhook. Smoke-Test in der naechsten Glance-Seite.
|
||||
- Major-Updates kommen separat mit Label `major`, behandelst du in einem geplanten Slot mit Restore-Snapshot davor.
|
||||
|
||||
**Backups**
|
||||
|
||||
- Borg lokal alle 6 h, Borg Hetzner taeglich, Wechselplatte monatlich. Borg-Passphrase auf Papier im Bankschliessfach. Alle drei Ziele juenger als 36 h Alert-Schwelle.
|
||||
- Pre-Dump-Hooks erzeugen 15 konsistente Dump-Artefakte pro Lauf, automatische Posture-Check-Vor-Hook bricht Backup ab, wenn FS oder Mount sich veraendert haben.
|
||||
|
||||
**Restore**
|
||||
|
||||
- Monatlicher Mini-Restore-Test fuer Vaultwarden/Gitea/Paperless/Immich nach `/mnt/user/backups/restore-lab/<dienst>/` laeuft automatisiert per Gitea Actions, Erfolgs-Report landet als Datei + ntfy-Info.
|
||||
- Quartalsweise End-to-End-Drill: ein kompletter Stack restauriert, App startet, Smoke-Test passt, Doku validiert. Komodo-Bootstrap-Pfad ist getestet.
|
||||
- Im Ernstfall folgst du `docs/DISASTER_RECOVERY.md` Phase 0–5 und bist nach < 8 h wieder im Vollbetrieb. Repo-Bootstrap aus GitHub-Mirror, Stacks in Stufen 1–5, Verifikation pro Stufe.
|
||||
|
||||
**Monitoring**
|
||||
|
||||
- Prometheus + Loki + Grafana + Alertmanager-ntfy-Bridge. ~15 Alert-Regeln, alle in `alerts.yml` versioniert.
|
||||
- Family-View, Host-Overview, Containers+Logs, Traefik-Standalone, Backup-Frische, Cert-Tage. Sechs Dashboards mehr braucht keine Familie.
|
||||
- Loki sammelt 30 Tage Logs aus allen Containern via Promtail. cAdvisor + node-exporter liefern Container- und Host-Metriken. Blackbox testet oeffentliche Endpoints alle 60 s.
|
||||
|
||||
**Security**
|
||||
|
||||
- Authelia OIDC fuer Nextcloud, Immich, Grafana, Mealie. ForwardAuth fuer Operator-UIs mit 2FA-Pflicht ab Tier-2.
|
||||
- CrowdSec sperrt Brute-Force-IPs auf Traefik-Ebene bevor sie die Apps treffen.
|
||||
- AdGuard-Admin nur via Tailscale. Operator-Pfad ausschliesslich Tailscale.
|
||||
- Authelia-Repo-Baseline und Host-Config sind per Diff-Check im posture-check abgesichert.
|
||||
- Secrets-Mounts mode 600, Borg-Passphrase analog.
|
||||
|
||||
**Dokumentation**
|
||||
|
||||
- SERVICE_CATALOG, RESTORE_MATRIX, DISASTER_RECOVERY, STORAGE_LAYOUT, SECRETS_MAP, WORKFLOW, GITOPS_DRIFT_RUNBOOK, ALERTING_MAP, HOMELAB_ARCHITECTURE_MASTER bleiben aktuelle Single-Source-of-Truth.
|
||||
- `services/komodo-bootstrap/` loest das Henne-Ei. `SERVICES_RECOVERY.md` ist final, nicht Draft.
|
||||
- Familien-Onboarding-Doku als Markdown: "So nutzt du Nextcloud-Web", "So aktivierst du Immich-Foto-Backup auf dem Handy", "So loggst du dich neu per 2FA ein".
|
||||
|
||||
**Taegliche Nutzung**
|
||||
|
||||
- Familie scannt Briefe per ASN-Barcode in `scans_inbox/`, Paperless tagged via paperless-gpt automatisch, alles durchsuchbar.
|
||||
- Immich erfasst Smartphone-Fotos aller Familienmitglieder automatisch, Familie blaettert per Web/App, Tagging per ML.
|
||||
- Nextcloud traegt Kalender, Kontakte, geteilte Familienordner per WebDAV/CardDAV — kein Google/Apple-Lock-In.
|
||||
- Mealie speichert Rezepte, Einkaufsliste auf dem Handy.
|
||||
- Vaultwarden ist der einzige Passwort-Tresor der Familie; Familien-Organisation aktiv.
|
||||
- Plex streamt Heim-Medien an alle Endgeraete.
|
||||
- ntfy schickt dir Vorfaelle aufs Handy — und sonst nichts.
|
||||
- Optional: Firefly III fuer die Familien-Finanzen, Ecowitt-Wetter-Dashboard, Home-Assistant-Automationen fuer Strom-Eigenverbrauch.
|
||||
|
||||
**Was bewusst weggelassen ist**
|
||||
|
||||
- Kein Kubernetes. Komodo + Compose reicht.
|
||||
- Kein zweiter Medienserver neben Plex (Jellyfin-Entscheidung 2026-05-25).
|
||||
- Kein zweites Dashboard neben Glance (Homepage-Entscheidung 2026-05-25).
|
||||
- Kein Uptime-Kuma neben Blackbox (Entscheidung 2026-05-25).
|
||||
- Kein Hermes-Agent, wenn er bis 2026-07-25 keinen klaren Alltagsnutzen liefert.
|
||||
- Kein BentoPDF/paperless-gpt 24/7, wenn nicht aktiv genutzt.
|
||||
- Kein Self-Stack-Komodo (durch `services/komodo-bootstrap/` ersetzt).
|
||||
|
||||
---
|
||||
|
||||
## Schlussbemerkung
|
||||
|
||||
Das Setup ist naeher an Senior-Reife als an Bastel-Niveau. Der groesste Hebel der naechsten drei Monate ist **Konsolidieren statt erweitern** (Hermes-Entscheidung, Altstaende raus, Auth-SSO, Off-Site-Diversitaet), kombiniert mit der einen Aktivierung, die das Setup vom Operator-Tool zum **Familien-Tool** macht: Immich-Smartphone-Backup fuer alle.
|
||||
|
||||
Das vorhandene 2026-05-23-Audit hat die richtigen Sprintziele bereits identifiziert. Diese externe Audit-Sicht ergaenzt:
|
||||
|
||||
- **2FA-Pflicht auf Tier-1-Operator-UIs** (F-04) — fehlt in der Bewertung 2026-05-23 in dieser Klarheit.
|
||||
- **Healthcheck-Luecke** (F-15) und **fehlende Mem-Limits** (F-19) — operative Detail-Findings, die in der strategischen Bewertung nicht auftauchen.
|
||||
- **Komodo-Self-Bootstrap als konkreter Code-Vorschlag** (F-09) statt nur als Risiko-Erwaehnung.
|
||||
- **Authelia-Drift-Detection automatisieren** (F-10) statt nur "manuell merge".
|
||||
- **Monitoring-Stack ohne Digest-Pin** (F-07) — Inkonsistenz mit der eigenen Image-Pinning-Disziplin.
|
||||
- **`infra/redis` ist faktisch nicht shared** (F-16) — Etikett-Realitaet-Drift.
|
||||
- **Alert-Regeln deutlich zu duenn** (F-08) — Sichtbarkeitsluecken bei Cert/Borg/Container-Down.
|
||||
|
||||
Wenn Sprint 1–3 in 4–6 Wochen sitzen, bist du auf einer 1-Note. Wenn dann Sprint 4–5 in weiteren 6–8 Wochen kommen, hat die Familie ein echtes Self-Hosting-System, kein "Container-Sammlung im Keller". Das ist der Unterschied, den der Audit-Auftrag adressiert.
|
||||
@@ -0,0 +1,80 @@
|
||||
# Audit Report - KalliLab CORE
|
||||
Datum: 2026-05-16
|
||||
Gepruefte Compose-Dateien: 30
|
||||
|
||||
## Kritische Befunde
|
||||
|
||||
Keine kritischen Befunde im Repo-Sollzustand gefunden.
|
||||
|
||||
- Keine Datenbank und kein Cache haengt in `frontend_net`.
|
||||
- Keine produktive Compose-Datei ohne explizites `networks:`-Feld gefunden.
|
||||
- Keine produktive `.env`- oder `stack.env`-Datei ohne `.example`-Suffix im Repository gefunden.
|
||||
- Keine Klartext-Passwoerter, Tokens oder API-Keys in Compose-`environment:`-Bloecken gefunden.
|
||||
|
||||
## Mittlere Befunde
|
||||
|
||||
- Docker-Socket ausserhalb der im Audit-Prompt genannten Allowlist: `traefik` mountet `/var/run/docker.sock:/var/run/docker.sock:ro` in `traefik/docker-compose.yml:34`. Der Socket ist fuer den Docker-Provider fachlich nachvollziehbar, aber in `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 10 nicht explizit als Docker-Socket-Ausnahme aufgefuehrt.
|
||||
- Docker-Socket ausserhalb der im Audit-Prompt genannten Allowlist: `alloy` mountet `/var/run/docker.sock:/var/run/docker.sock:ro` in `ops/loki/docker-compose.yml:26`. [AUSNAHME - dokumentiert] in `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 10 als `alloy` Docker-Socket read-only, aber nicht in der Prompt-Allowlist genannt.
|
||||
- `komodo-periphery` haengt ohne Web-UI im `frontend_net` in `ops/komodo/docker-compose.yml:92-94`. Die Compose-Datei dokumentiert an `ops/komodo/docker-compose.yml:77-79` den Grund als Git-Zugriff auf internes Gitea und Docker-Agent-Sonderfall. [AUSNAHME - lokal in Compose dokumentiert]
|
||||
- `hermes_net` ist ein app-internes Netz ohne `internal: true`: `ops/hermes-agent/docker-compose.yml:91-93`. Das ist nicht Teil der explizit geforderten `internal: true`-Liste, aber strukturell auffaellig, weil Gateway und Dashboard intern ueber dieses Netz sprechen.
|
||||
- `grafana` nutzt zusaetzlich `backend_net` in `ops/grafana-influxdb/docker-compose.yml:27-30`, obwohl die Architektur das Grafana/Influx-Paar primaer als `frontend_net` + `grafana_influx_internal` beschreibt. Grund ist vermutlich Loki-Datasource-Zugriff; `docs/REPO_MAP.md` nennt `backend_net` fuer Grafana-Loki-Datasource. [AUSNAHME - dokumentiert]
|
||||
- `paperless-gpt` verwendet `PAPERLESS_API_TOKEN` als Stack-ENV in `apps/paperless-gpt/docker-compose.yml:15`, taucht aber in `docs/SECRETS_MAP.md` nicht als eigener aktiver Secret-Eintrag auf.
|
||||
|
||||
## Hinweise
|
||||
|
||||
- Direkte Host-Ports sind nur bei dokumentierten Ausnahmen vorhanden:
|
||||
- [AUSNAHME - dokumentiert] `traefik`: `80:80`, `443:443` in `traefik/docker-compose.yml:30-32`.
|
||||
- [AUSNAHME - dokumentiert] `gitea`: `222:22` in `core/gitea/docker-compose.yml:17-18`.
|
||||
- [AUSNAHME - dokumentiert] `adguard`: `53:53/tcp`, `53:53/udp`, `8082:80` in `host-services/Adguard/docker-compose.yml:13-16`.
|
||||
- [AUSNAHME - dokumentiert] `influxdb3-core`: `${INFLUXDB_BIND_IP:-127.0.0.1}:8181:8181` in `ops/grafana-influxdb/docker-compose.yml:54-55`.
|
||||
- `backend_net` wird in allen Compose-Dateien als `external: true` referenziert, z. B. `infra/postgresql17/docker-compose.yml:25-26`, `infra/redis/docker-compose.yml:22-23`, `traefik/docker-compose.yml:59-60`. Ob das externe Docker-Netz live wirklich `internal: true` ist, ist aus dem Repo allein nicht verifizierbar.
|
||||
- `grafana_influx_lan` hat bewusst kein `internal: true`: `ops/grafana-influxdb/docker-compose.yml:88-89`. [AUSNAHME - dokumentiert]
|
||||
- Mutable Tags sind mit Digests gepinnt, aber semantisch weiterhin mutable:
|
||||
- `immich-server`: `release@sha256` in `apps/immich/docker-compose.yml:4`.
|
||||
- `immich-machine-learning`: `release@sha256` in `apps/immich/docker-compose.yml:35`.
|
||||
- `tailscale`: `stable@sha256` in `host-services/tailscale/docker-compose.yml:3`.
|
||||
- `ddns-updater`: `latest@sha256` in `infra/ddns-updater/docker-compose.yml:3`.
|
||||
- `komodo-core`: Major-Tag `2@sha256` in `ops/komodo/docker-compose.yml:36`.
|
||||
- `komodo-periphery`: Major-Tag `2@sha256` in `ops/komodo/docker-compose.yml:82`.
|
||||
- `uptime-kuma`: Major-Tag `1@sha256` in `ops/uptime-kuma/docker-compose.yml:3`.
|
||||
- Reines `image: name:latest` ohne Digest wurde in produktiven Compose-Dateien nicht gefunden.
|
||||
- Alle Services haben `restart: unless-stopped`.
|
||||
- Alle Services haben `security_opt: no-new-privileges:true`.
|
||||
- [AUSNAHME - dokumentiert] `scrutiny` nutzt `privileged: true` in `ops/scrutiny/docker-compose.yml:6`.
|
||||
- [AUSNAHME - dokumentiert] `tailscale` nutzt `network_mode: host` in `host-services/tailscale/docker-compose.yml:6`.
|
||||
|
||||
## Dokumentations-Abweichungen
|
||||
|
||||
- Service-Namen in Compose vs. `docs/SERVICE_CATALOG.md` weichen bei Immich ab: Compose nutzt `immich-server`, `immich-machine-learning`, `database`, `redis` in `apps/immich/docker-compose.yml:2`, `:33`, `:44`, `:53`; der Katalog dokumentiert `immich_server`, `immich_machine_learning`, `immich_postgres`, `immich_redis`.
|
||||
- Service-Name in Compose vs. `docs/SERVICE_CATALOG.md` weicht bei Paperless ab: Compose nutzt `paperless` in `apps/paperless/docker-compose.yml:2`; der Katalog dokumentiert `paperless-ngx`.
|
||||
- Service-Name in Compose vs. `docs/SERVICE_CATALOG.md` weicht bei Redis ab: Compose nutzt `redis` in `infra/redis/docker-compose.yml:2`; der Katalog dokumentiert `Redis`.
|
||||
- Traefik-Host bei Hermes ist im Compose variabel: `Host(`${HERMES_DASHBOARD_HOST}`)` in `ops/hermes-agent/docker-compose.yml:81`; `docs/REPO_MAP.md` dokumentiert konkret `hermes.kaleschke.info`. Das ist plausibel, aber maschinell nicht eindeutig abgleichbar.
|
||||
- `docs/REPO_MAP.md` Volumes-Tabelle ist fuer mehrere Mounts nur zusammenfassend, nicht pfadgenau. Beispiele mit Compose-Pfaden, die dort nicht wortgleich auftauchen:
|
||||
- `/mnt/user/appdata/unbound/config` in `apps/unbound/docker-compose.yml:7`.
|
||||
- `/mnt/user/appdata/ddns-updater` in `infra/ddns-updater/docker-compose.yml:17`.
|
||||
- `/mnt/user/appdata/filebrowser/database` und `/mnt/user/appdata/filebrowser/config` in `ops/filebrowser/docker-compose.yml:15-16`.
|
||||
- `/mnt/user/appdata/borg-ui/restore` in `ops/borg-ui/docker-compose.yml:27`.
|
||||
- Netzwerke in Compose sind alle in `docs/REPO_MAP.md` aufgefuehrt.
|
||||
- Traefik-Hosts aus Compose sind in `docs/REPO_MAP.md` aufgefuehrt; einzige Besonderheit ist der variable Hermes-Host.
|
||||
- `.example`-Dateien haben passende Gegenspieler in `.gitignore`: `.env`, `*.env`, `!*.env.example`, `**/stack.env`, `!**/stack.env.example`.
|
||||
- Keine `.keep`-Platzhalter-Dateien gefunden.
|
||||
|
||||
## Offene Architektur-Punkte: aktueller Stand
|
||||
|
||||
- `immich_redis`: weiterhin kein named volume. Compose-Service `redis` in `apps/immich/docker-compose.yml:44-50` hat aktuell gar keinen `volumes:`-Block. Architekturpunkt bleibt offen.
|
||||
- `AdGuard Home`: Admin-Port ist weiterhin direkt veroeffentlicht: `8082:80` in `host-services/Adguard/docker-compose.yml:15`; keine Traefik-Labels vorhanden. Block F bleibt offen.
|
||||
- `filebrowser`: Appdata-Breitmount ist entfernt; aktuelle Mounts sind `/mnt/user/documents`, `/mnt/user/photos`, `/mnt/user/projekte` plus eigene DB/Config in `ops/filebrowser/docker-compose.yml:12-16`. Langfristiges Hardening bleibt moeglich, aber der groesste alte Breitmount ist erledigt.
|
||||
- `bentopdf`: Compose ist vorhanden und Traefik-abgesichert in `apps/bentopdf/docker-compose.yml:2-27`. Runtime-Deploy und fachliche Abnahme koennen aus dem Repo allein nicht bestaetigt werden; Architekturpunkt bleibt als Live-Pruefung offen.
|
||||
- `grafana` und `influxdb3-core`: laufen weiterhin als `user: "0"` in `ops/grafana-influxdb/docker-compose.yml:6` und `ops/grafana-influxdb/docker-compose.yml:53`. [AUSNAHME - dokumentiert]
|
||||
- `plex-media-server`: keine Compose-Datei im Repo gefunden; bleibt Dockerman-/Host-Sonderfall laut Architektur.
|
||||
|
||||
## Bestanden
|
||||
|
||||
- 30 produktive `docker-compose.yml` wurden geprueft.
|
||||
- Keine Datenbanken oder Caches im `frontend_net`: `postgresql17` nur `backend_net` in `infra/postgresql17/docker-compose.yml:18`; shared `redis` nur `backend_net` in `infra/redis/docker-compose.yml:15`; `mealie-postgres` nur `mealie_internal` in `apps/mealie/docker-compose.yml:56`; Immich `database` und `redis` nur `immich_default` in `apps/immich/docker-compose.yml:48` und `:64`; Nextcloud DB/Redis nur `nextcloud_internal` in `apps/nextcloud/docker-compose.yml:61` und `:73`; `komodo-mongo` nur `komodo_net` in `ops/komodo/docker-compose.yml:16`.
|
||||
- App-interne Pflichtnetze sind korrekt `internal: true`: `immich_default` in `apps/immich/docker-compose.yml:73-75`, `mealie_internal` in `apps/mealie/docker-compose.yml:66-68`, `nextcloud_internal` in `apps/nextcloud/docker-compose.yml:82-84`, `grafana_influx_internal` in `ops/grafana-influxdb/docker-compose.yml:90-91`.
|
||||
- `frontend_net` und `backend_net` werden in Compose-Dateien als `external: true` referenziert.
|
||||
- Alle Services mit `traefik.enable=true` setzen explizit `traefik.docker.network=frontend_net`, `entrypoints=websecure`, `tls=true` und `tls.certresolver=le`.
|
||||
- Kein Traefik-Label mit `yourdomain.tld` gefunden.
|
||||
- Admin-/Ops-Router haben Middleware `authelia@file,secure-headers@file`, u. a. `homepage` in `apps/homepage/docker-compose.yml:31`, `filebrowser` in `ops/filebrowser/docker-compose.yml:27`, `scrutiny` in `ops/scrutiny/docker-compose.yml:32`, `grafana` in `ops/grafana-influxdb/docker-compose.yml:46`. [AUSNAHME - dokumentiert] `komodo-core` hat keine ForwardAuth-Middleware in `ops/komodo/docker-compose.yml:64-71`; [AUSNAHME - dokumentiert] `nextcloud` nutzt native Auth und nur Redirect-Middleware in `apps/nextcloud/docker-compose.yml:42-46`.
|
||||
- Web-UIs ohne Traefik-Labels wurden nur als dokumentierte Sonderfaelle gefunden: `adguard` mit LAN-Admin-Port in `host-services/Adguard/docker-compose.yml:13-16`; `ddns-updater` hat keine Web-UI und braucht Internet in `infra/ddns-updater/docker-compose.yml:8`; `komodo-periphery` ist Agent ohne Traefik-Route in `ops/komodo/docker-compose.yml:81-103`.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Codex-Prompt: KalliLab Endstufe
|
||||
|
||||
Du hast Vollzugriff auf `G:\Gitea_Clone\homelab-infra`, Gitea-Push, Komodo, und SSH auf Unraid `Kallilabcore`.
|
||||
|
||||
## Lies zuerst
|
||||
1. `CLAUDE.md`
|
||||
2. `docs/archive/2026-05/AUDIT_2026-05-23.md` — dort steht die komplette Restliste
|
||||
|
||||
## Auftrag
|
||||
Den Audit von oben verifizieren und die offenen Punkte abarbeiten, bis das Homelab in der Endstufe ist. Reihenfolge:
|
||||
|
||||
1. **P0** — Lokalen Commit `cd650b1` nach Gitea pushen, danach Komodo-Reaktion fuer `gitea` und `borg-ui` pruefen.
|
||||
2. **P0** — Live-Daten aus Audit-Abschnitt 9 messen und in `docs/archive/2026-05/AUDIT_2026-05-23_LIVE.md` ablegen (Secrets redacten).
|
||||
3. **P1** — Monitoring-Stack (`monitoring/`) live deployen, alte `ops/grafana-influxdb` und `ops/loki` `down` (nicht loeschen).
|
||||
4. **P1** — Jellyfin und Plex in `HOMELAB_ARCHITECTURE_MASTER_V2.md`, `docs/SERVICE_CATALOG.md`, `docs/REPO_MAP.md` nachtragen. Plex-Eintrag "nicht als Repo-Stack enthalten" korrigieren.
|
||||
5. **P2** — Borg-Lauf-Frische pruefen, ggf. neuen Lauf ausloesen, alle 14 Dump-Artefakte juenger als 24 h.
|
||||
6. **P3** — Repo-Hygiene: 8 leere Verzeichnisse weg, `.serena/` in `.gitignore`, Entscheidung zu `ops/windows-reinstall/*.ps1`.
|
||||
|
||||
## Regeln (aus CLAUDE.md, nicht verhandelbar)
|
||||
- Secrets nie im Klartext ausgeben.
|
||||
- Keine Aenderungen direkt in Komodo, nur ueber Git → Push → Komodo.
|
||||
- Kein `push --force`, kein blindes Loeschen von `/mnt/user/{appdata,documents,photos,services,backups}`.
|
||||
- Working-Tree-Status nur aus `git status --short` ableiten, nie aus `git diff` ueber Linux-Mount.
|
||||
- Traefik dynamic config wird nicht von Komodo deployed — Aenderungen dort manuell auf `/mnt/user/appdata/traefik/dynamic/` syncen.
|
||||
- Nicht anfassen: Hermes, Disk1 NTFS Phase 2, Komodo-Auth, Grafana/InfluxDB `user: "0"`, Image-Pinning ddns/glances/scrutiny.
|
||||
- Wenn zwei Reparaturversuche scheitern: stoppen, Drift-Runbook Pflichtmatrix, Operator fragen.
|
||||
|
||||
## Arbeitsmodus pro Block
|
||||
Lesen → minimal aendern → `ops/policy-checks/check_repo.ps1` lokal → Commit → Push → Komodo-Reaktion + Smoke-Test → eine Zeile in `docs/MIGRATION_LOG.md`.
|
||||
|
||||
## Fertig
|
||||
Wenn alles abgearbeitet ist (oder ein Punkt bewusst offen bleibt): `docs/archive/2026-05/AUDIT_2026-05-23_FINAL.md` schreiben mit Ampel + konkretem Beleg pro Punkt, committen, pushen, kurz an mich melden.
|
||||
@@ -0,0 +1,202 @@
|
||||
# Codex-Prompt: Jellyfin entfernen, Plex bleibt
|
||||
|
||||
> **Status (Stand 2026-05-30):** Auftrag ausgefuehrt. Jellyfin wurde 2026-05-25 aus Repo, Komodo, Traefik-Routing, Authelia-ACL und Appdata-Live-Pfad entfernt (Service-Removal-Checkliste in `docs/WORKFLOW.md`, MIGRATION_LOG-Eintrag dort). Datei bleibt im Repo als **Codex-Removal-Pattern** fuer kuenftige Stack-Removals (z.B. Hermes nach Review-Deadline 2026-07-25 oder bei BentoPDF/paperless-gpt-Folgeentscheidung). Inhaltlich nicht mehr aendern — als Vorlage referenzieren und pro Anwendung neu instanzieren.
|
||||
|
||||
Stand: 2026-05-23
|
||||
Ausloeser: Operator-Entscheidung "Plex bleibt, Jellyfin weg".
|
||||
Bezug: `docs/archive/2026-05/STRATEGISCHE_BEWERTUNG_2026-05-23.md` Block 9 Quick Wins.
|
||||
|
||||
Du hast Vollzugriff auf `G:\Gitea_Clone\homelab-infra`, Gitea-Push, Komodo, und SSH auf Unraid `Kallilabcore`.
|
||||
|
||||
## Lies zuerst
|
||||
|
||||
1. `CLAUDE.md`
|
||||
2. `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 7.4 und 7.8
|
||||
3. `docs/WORKFLOW.md`
|
||||
4. `docs/ROLLBACK.md`
|
||||
5. `apps/jellyfin/docker-compose.yml`
|
||||
6. `security/authelia/configuration.yml` (Access-Control-Block)
|
||||
7. `docs/SERVICE_CATALOG.md`, `docs/REPO_MAP.md`, `docs/MIGRATION_LOG.md`
|
||||
|
||||
## Ziel
|
||||
|
||||
Jellyfin ist vollstaendig aus dem Repo, Komodo, Traefik-Routing und Authelia-ACL entfernt. Plex laeuft unveraendert weiter. Medien-/Foto-Mounts unter `/mnt/user/media` und `/mnt/user/photos` bleiben unberuehrt. Domain `jellyfin.kaleschke.info` antwortet nicht mehr ueber Traefik.
|
||||
|
||||
## Wichtige Vorabinformation
|
||||
|
||||
- `/mnt/user/appdata/jellyfin/{config,cache}` ist **nicht** im Borg-Scope (`ops/borg-ui/all-important-sources.txt`). Watch-History, User-Settings und Metadaten-Cache sind danach weg. Das ist akzeptabel, weil Plex die Nutzungsdaten ohnehin separat fuehrt.
|
||||
- Plex teilt sich `/mnt/user/media:ro` und `/mnt/user/photos:ro` mit Jellyfin — Datenpfad bleibt unangetastet.
|
||||
- Authelia-Eintrag `jellyfin.kaleschke.info` steht unter `policy: bypass` in `security/authelia/configuration.yml` Zeile 42. Die `configuration.yml` ist Repo-Baseline und muss laut `docs/AI_CONTEXT.md` manuell auf den Host gemerged werden.
|
||||
- Jellyfin hat **keinen** Eintrag in `monitoring/blackbox/blackbox.yml`, `ops/glance/config/glance.yml`, `apps/homepage/docker-compose.yml`. Die Homepage-Service-Cards liegen hostseitig unter `/mnt/user/appdata/homepage/config/services.yaml` — dort moeglicherweise ein Eintrag, vor Ort pruefen.
|
||||
|
||||
## Reihenfolge
|
||||
|
||||
### P0 — Plex-Tauglichkeit verifizieren (vor jeglichem Loeschen)
|
||||
|
||||
Smoke-Test auf dem Host:
|
||||
|
||||
```bash
|
||||
curl -fsS -o /dev/null -w "%{http_code}\n" http://192.168.178.58:32400/identity
|
||||
docker exec plex test -d /data/Filme || echo "Filme nicht erreichbar"
|
||||
docker exec plex test -d /photos || echo "Photos nicht erreichbar"
|
||||
```
|
||||
|
||||
Akzeptanzkriterium: Plex antwortet mit `200`, beide Medien-Pfade sind im Plex-Container sichtbar, Plex zeigt in seiner Web-UI alle erwarteten Bibliotheken. **Wenn nicht erfuellt: abbrechen und Operator fragen.**
|
||||
|
||||
### P1 — Jellyfin Stack in Komodo stoppen (nicht loeschen)
|
||||
|
||||
In Komodo Web-UI Stack `jellyfin` `Stop` ausfuehren (nicht `Destroy`). Damit ist der Container weg, Stack-Definition und Workspace bleiben — Rollback per `Start` moeglich.
|
||||
|
||||
Akzeptanzkriterium:
|
||||
|
||||
```bash
|
||||
docker ps -a --filter name=jellyfin --format "{{.Names}}\t{{.Status}}"
|
||||
```
|
||||
|
||||
zeigt entweder keine Zeile oder `Exited`.
|
||||
|
||||
### P2 — Authelia ACL um Jellyfin-Bypass bereinigen
|
||||
|
||||
Datei: `security/authelia/configuration.yml`
|
||||
|
||||
```diff
|
||||
- domain:
|
||||
- immich.kaleschke.info
|
||||
- paperless.kaleschke.info
|
||||
- mealie.kaleschke.info
|
||||
- vault.kaleschke.info
|
||||
- ntfy.kaleschke.info
|
||||
- git.kaleschke.info
|
||||
- - jellyfin.kaleschke.info
|
||||
policy: bypass
|
||||
```
|
||||
|
||||
Kein anderer Authelia-Eintrag referenziert Jellyfin. Wildcard `*.kaleschke.info` mit `policy: one_factor` greift fuer geloeschte Domains nicht, weil Traefik die Route nicht mehr kennt.
|
||||
|
||||
**Manueller Host-Sync danach Pflicht** (`docs/AI_CONTEXT.md`, Workflow): die geaenderte `configuration.yml` muss auf `/mnt/user/appdata/authelia/config/configuration.yml` gemerged werden (OIDC-/Secret-Block hostseitig erhalten). Danach `docker exec authelia authelia validate-config -c /config/configuration.yml` und Stack-Restart.
|
||||
|
||||
### P3 — Compose-Stack aus Repo entfernen
|
||||
|
||||
```bash
|
||||
git rm -r apps/jellyfin/
|
||||
```
|
||||
|
||||
Akzeptanzkriterium: `apps/jellyfin/` existiert nicht mehr; `git status --short` zeigt `D apps/jellyfin/docker-compose.yml`.
|
||||
|
||||
### P4 — Doku synchronisieren
|
||||
|
||||
**`HOMELAB_ARCHITECTURE_MASTER_V2.md`:**
|
||||
|
||||
- Abschnitt 3.2 Diagramm: `jellyfin` aus oeffentliche-Apps-Zeile entfernen.
|
||||
- Abschnitt 4.1 "Oeffentlich ueber Traefik": Zeile `- jellyfin — jellyfin.kaleschke.info` entfernen.
|
||||
- Abschnitt 7.4 Tabelle "Produktive Apps": Zeile `jellyfin` entfernen.
|
||||
- Abschnitt 7.8 "Entfernte Container": neue Zeile
|
||||
|
||||
```text
|
||||
| `jellyfin` | 2026-05-23 | doppelter Medienserver neben Plex; Plex bleibt einziger Medienserver |
|
||||
```
|
||||
|
||||
**`docs/SERVICE_CATALOG.md`:**
|
||||
|
||||
- Block "Public / User Apps": Jellyfin-Zeile entfernen.
|
||||
|
||||
**`docs/REPO_MAP.md`:**
|
||||
|
||||
- Abschnitt "Apps"-Tabelle: Jellyfin-Zeile entfernen.
|
||||
- Abschnitt "Traefik Hosts": `jellyfin.kaleschke.info`-Zeile entfernen.
|
||||
- Abschnitt "Volumes und Datenpfade": Jellyfin-Zeile entfernen.
|
||||
|
||||
**`docs/MIGRATION_LOG.md`:** neuen Eintrag anhaengen
|
||||
|
||||
```text
|
||||
### Jellyfin entfernt (2026-05-23)
|
||||
- Operator-Entscheidung: Plex bleibt einziger Medienserver.
|
||||
- Compose-Stack `apps/jellyfin/` aus Repo entfernt.
|
||||
- Authelia-ACL bereinigt (`jellyfin.kaleschke.info` aus `bypass`-Liste raus), Host-Config gemerged.
|
||||
- Komodo-Stack `jellyfin` gestoppt; Stack-Eintrag und Webhook bei Abschluss von Schritt P7 entfernt.
|
||||
- Appdata unter `/mnt/user/appdata/jellyfin/` nach `/mnt/user/appdata/_archive/jellyfin-removed-2026-05-23/` verschoben (siehe Schritt P5).
|
||||
- DNS-Eintrag `jellyfin.kaleschke.info` in Cloudflare belassen, kann beim naechsten DNS-Cleanup mit entfernt werden.
|
||||
```
|
||||
|
||||
### P5 — Appdata archivieren statt loeschen
|
||||
|
||||
Auf dem Host:
|
||||
|
||||
```bash
|
||||
mkdir -p /mnt/user/appdata/_archive
|
||||
mv /mnt/user/appdata/jellyfin /mnt/user/appdata/_archive/jellyfin-removed-2026-05-23
|
||||
```
|
||||
|
||||
Akzeptanzkriterium: `/mnt/user/appdata/jellyfin` existiert nicht mehr, `/mnt/user/appdata/_archive/jellyfin-removed-2026-05-23` enthaelt `config/` und `cache/`. **Nicht endgueltig loeschen** vor mindestens 14 Tagen Plex-Stabilitaet.
|
||||
|
||||
### P6 — Policy-Check + Commit
|
||||
|
||||
```powershell
|
||||
pwsh ops/policy-checks/check_repo.ps1
|
||||
```
|
||||
|
||||
Akzeptanzkriterium: 0 Critical, keine neuen Warnings (vorher: 4 dokumentierte Warnings, soll danach gleich bleiben).
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "Remove Jellyfin stack; Plex remains sole media server"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
### P7 — Komodo-Stack-Eintrag und Webhook entfernen
|
||||
|
||||
Nach erfolgreichem Push und gruener Komodo-Reaktion auf restliche Stacks:
|
||||
|
||||
- In Komodo: Stack `jellyfin` `Destroy` (Workspace `/mnt/user/services/stacks/jellyfin/` entfernen).
|
||||
- In Gitea: Webhook-Eintrag fuer Komodo-Stack-ID `jellyfin` entfernen.
|
||||
|
||||
Akzeptanzkriterium: `ls /mnt/user/services/stacks/ | grep jellyfin` ist leer; Gitea-Webhook-Liste fuer `Micha/homelab-infra` enthaelt keinen Jellyfin-Eintrag mehr.
|
||||
|
||||
### P8 — Smoke-Test final
|
||||
|
||||
```bash
|
||||
curl -fsS -o /dev/null -w "%{http_code}\n" https://jellyfin.kaleschke.info/
|
||||
docker ps --filter name=jellyfin --format "{{.Names}}"
|
||||
ss -ltnp | grep 8096 || echo "Port 8096 frei"
|
||||
```
|
||||
|
||||
Erwartung:
|
||||
|
||||
- `https://jellyfin.kaleschke.info/` antwortet `404` (Traefik kennt die Route nicht mehr) oder Cert-Fehler je nach Cache.
|
||||
- Kein laufender `jellyfin`-Container.
|
||||
- Port `8096` nicht belegt (Jellyfin nutzte nur Container-Port, sollte sowieso frei sein).
|
||||
- Authelia-Login fuer Admin-Domains (`uptime`, `files`, `scrutiny`) funktioniert weiterhin — Bypass-Liste-Aenderung darf 2FA-Domains nicht angreifen.
|
||||
|
||||
## Rollback (bis Schritt P5 einschliesslich)
|
||||
|
||||
- Git: `git revert <commit-sha>` und push. Komodo deployt Jellyfin neu, sobald Stack in Komodo wieder existiert.
|
||||
- Appdata: `mv /mnt/user/appdata/_archive/jellyfin-removed-2026-05-23 /mnt/user/appdata/jellyfin`.
|
||||
- Authelia-ACL: Bypass-Eintrag wieder rein, Host-Sync, Authelia-Restart.
|
||||
|
||||
Ab Schritt P7 (Komodo Destroy + Webhook weg) ist Rollback nur per Neuanlegen des Komodo-Stacks moeglich.
|
||||
|
||||
## Regeln (aus CLAUDE.md, nicht verhandelbar)
|
||||
|
||||
- Secrets nie im Klartext ausgeben.
|
||||
- Keine Aenderungen direkt in Komodo, nur ueber Git → Push → Komodo. **Ausnahme:** Schritt P1 (`Stop`) und P7 (`Destroy`) sind explizit Komodo-Aktionen nach erfolgreichem Repo-Stand.
|
||||
- Kein `push --force`, kein blindes Loeschen unter `/mnt/user/{appdata,documents,photos,services,backups}` — Appdata wird in `_archive/` verschoben, nicht entfernt.
|
||||
- Working-Tree-Status nur aus `git status --short` ableiten, nie aus `git diff` ueber Linux-Mount.
|
||||
- Traefik dynamic config wird nicht von Komodo deployed — fuer diesen Auftrag nicht relevant, weil Jellyfin nur per Docker-Labels gerouteted war.
|
||||
- Nicht anfassen: Plex-Stack, Medien-/Foto-Mounts, alle anderen Apps.
|
||||
- Wenn zwei Reparaturversuche scheitern: stoppen, `docs/GITOPS_DRIFT_RUNBOOK.md` Pflichtmatrix, Operator fragen.
|
||||
|
||||
## Arbeitsmodus pro Schritt
|
||||
|
||||
Lesen → minimal aendern → `ops/policy-checks/check_repo.ps1` lokal (nur P6) → Commit → Push → Komodo-Reaktion + Smoke-Test → Eintrag in `docs/MIGRATION_LOG.md`.
|
||||
|
||||
## Fertig
|
||||
|
||||
Wenn alle 8 Schritte abgehakt sind: kurze Erfolgsmeldung an Operator mit:
|
||||
|
||||
- Commit-SHA des Removal-Commits
|
||||
- Bestaetigung Plex weiterhin gruen
|
||||
- Bestaetigung Authelia validate-config gruen
|
||||
- Bestaetigung Komodo-Stack und Webhook entfernt
|
||||
- Pfad zum Appdata-Archiv und Erinnerung, dass `_archive/jellyfin-removed-2026-05-23/` nach 14 Tagen Plex-Stabilitaet entfernt werden darf
|
||||
@@ -0,0 +1,123 @@
|
||||
# Codex-Prompt: Komodo 5xx-Spam Root-Cause
|
||||
|
||||
Stand: 2026-05-31
|
||||
Auftraggeber: Operator
|
||||
Vorarbeit: Claude (auto-mode), siehe Ermittlungsstand unten.
|
||||
|
||||
## Auftrag
|
||||
|
||||
`HomelabTraefik5xx` feuert dauerhaft fuer `service="komodo@docker"`. Quelle
|
||||
finden, fixen, dokumentieren. Bitte einmal **bis zum Ende** durchziehen, nicht
|
||||
nur eine Hypothese pruefen.
|
||||
|
||||
## Vor Arbeitsbeginn lesen
|
||||
|
||||
- `CLAUDE.md`
|
||||
- `docs/WORKFLOW.md`
|
||||
- `monitoring/prometheus/alerts.yml`
|
||||
- `docs/ALERT_RULES.md`
|
||||
- `ops/komodo/docker-compose.yml`
|
||||
- `traefik/docker-compose.yml`
|
||||
- `monitoring/prometheus/prometheus.yml` (Blackbox-Targets)
|
||||
- `monitoring/blackbox/blackbox.yml`
|
||||
- `ops/glance/config/glance.yml` (5 Komodo-URL-Stellen, **NICHT** die Quelle — siehe Ermittlung)
|
||||
|
||||
## Ermittlungsstand (bereits geklaert)
|
||||
|
||||
### Was gemessen wurde
|
||||
|
||||
- Traefik-Access-Log: Source-IP ist **eure WAN-IP `217.249.121.39`** (Hairpin
|
||||
aus dem Heimnetz). User-Agent leer (`"-"`).
|
||||
- Muster: `GET /` 200 **alle 15s** + `GET /user` **500** alle 30s, plus
|
||||
gelegentlich `POST /auth/login/GetLoginOptions` 200 und
|
||||
`POST /read/GetCoreInfo` 500.
|
||||
- Prometheus `sum by (code) (increase(traefik_service_requests_total{service="komodo@docker"}[5m]))`:
|
||||
`200`=22, `500`=14 (Werte vom 2026-05-31 08:11 UTC).
|
||||
- `docker logs komodo-core` ist still — keine internen Errors, nur normale
|
||||
Execute-Requests. Komodo wirft den 500 also vermutlich auf Auth-Pfad
|
||||
(`/user` ohne gueltige Session sollte `401` sein, nicht `500`). Das ist ein
|
||||
Komodo-Bug-on-Top, **aber nicht die Frage**.
|
||||
|
||||
### Ausgeschlossene Kandidaten (durch Test)
|
||||
|
||||
- **Browser-Tabs** — User hat alle Komodo-Tabs zugemacht, Polling laeuft
|
||||
weiter.
|
||||
- **PWA auf Handy** — User hat keine.
|
||||
- **Uptime-Kuma** — Container existiert nicht mehr.
|
||||
- **Homepage** — entfernt.
|
||||
- **Glance** — Test 2026-05-31 ~08:35 UTC: 130s gestoppt, 5xx-Rate
|
||||
unveraendert (2/60s Baseline → 4/130s waehrend Stop). Trotz 5 Komodo-URL-
|
||||
Eintraegen in `ops/glance/config/glance.yml` (search-shortcut Zeile 40,
|
||||
bookmark Zeilen 131/768, monitor-Widget Zeile 237 mit `check-url:
|
||||
http://komodo-core:9120`, docker-containers-Widget Zeile 725). Glance ist
|
||||
raus.
|
||||
|
||||
### Noch nicht getestete Kandidaten
|
||||
|
||||
- **Posture-Check / cert-token-check.sh** (`services/posture-check/`) — koennte
|
||||
periodisch Komodo-HTTPS pingen. 15s-/30s-Kadenz waere ungewoehnlich fuer
|
||||
einen Cron-Job, aber pruefen.
|
||||
- **Blackbox-Exporter** — pollt laut `monitoring/prometheus/prometheus.yml`
|
||||
`https://komodo.kaleschke.info` alle 15s. Das erklaert den `GET / 200`-
|
||||
Anteil sauber. Erklaert aber NICHT den `GET /user 500` 30s-Takt.
|
||||
- **Komodo Periphery** — auf `komodo_net` und `frontend_net`. Sollte mit
|
||||
Core via internes Netz reden, koennte aber per Misconfig die Public-URL
|
||||
treffen. Logs noch nicht eingesehen.
|
||||
- **Komodo Core selbst** mit `KOMODO_HOST=https://komodo.kaleschke.info` —
|
||||
evtl. Self-Check via Public-URL.
|
||||
- **Ein Gerat im LAN**, das wir noch nicht auf dem Schirm haben (zweiter
|
||||
Rechner mit altem Tab, Smart-TV, etc.).
|
||||
|
||||
### Was nicht geht
|
||||
|
||||
- `tcpdump` fehlt auf dem Host.
|
||||
- `conntrack` zeigt die Hairpin-Pakete nicht (NAT-Pre-Routing).
|
||||
|
||||
## Naechste Schritte (Vorschlag)
|
||||
|
||||
1. **Blackbox-Exporter ausschliessen**: Targets in `prometheus.yml` zeigen,
|
||||
dass Blackbox NUR `https://komodo.kaleschke.info` pollt (also `/`, kein
|
||||
`/user`). Bestaetigen.
|
||||
2. **Posture-Check pruefen**: `services/posture-check/cert-token-check.sh`
|
||||
lesen, Kadenz und Endpunkte protokollieren. Falls dort `/user` oder ein
|
||||
30s-Loop drin ist → Treffer.
|
||||
3. **Periphery isolieren**: Periphery 2 min stoppen, Traefik-Log gegen-
|
||||
checken. `docker stop komodo-periphery; sleep 130; <log-check>; docker
|
||||
start komodo-periphery`. Vorsicht: Periphery-Down heisst Komodo-Deploy
|
||||
funktioniert nicht — also nur kurz, kein Deploy in dem Fenster.
|
||||
4. **Komodo-Core isolieren**: Wenn 1-3 nichts ergeben, Komodo-Core selbst 2 min
|
||||
stoppen. Wenn Polling weiterlaeuft, ist der Client ausserhalb der Komodo-
|
||||
Stack (LAN-Geraet). Wenn es aufhoert, polled Komodo Core sich selbst.
|
||||
5. **LAN-Aufnahme via Komodo-Container**: Falls Container-Stack ausgeschlossen,
|
||||
im komodo-core-Container per `ss -tnp state syn-recv` waehrend einer
|
||||
typischen Polling-Sekunde mitschauen. Source-IP/Port der eingehenden
|
||||
Connection liefert den Hairpin-Origin am genauesten.
|
||||
|
||||
## Fix-Erwartung
|
||||
|
||||
Sobald Quelle bekannt:
|
||||
|
||||
- **Wenn Container im Stack**: Config so anpassen, dass die Anfrage intern
|
||||
laeuft (kein Public-Hostname), inkl. Doku.
|
||||
- **Wenn LAN-Geraet**: User informieren, was es ist; wenn moeglich Geraet
|
||||
reparieren (Tab schliessen, App deinstallieren). Kein Repo-Change noetig.
|
||||
- **Wenn nicht abstellbar**: separate Frage, ob `HomelabTraefik5xx` fuer
|
||||
`service="komodo@docker"` mit einem Exclude versehen werden soll — aber nur
|
||||
als letzter Ausweg. Default ist: Quelle fixen.
|
||||
|
||||
## Doku am Ende
|
||||
|
||||
- Eintrag in `docs/MIGRATION_LOG.md`: Datum, Symptom, Root-Cause, Fix,
|
||||
Smoke-Test.
|
||||
- Falls eine Glance-/Periphery-/sonstige Config-Aenderung noetig wird:
|
||||
Standard-Loop (Commit → Push → Komodo-Deploy → Smoke), Co-Authored-By-Tag
|
||||
mitgeben.
|
||||
|
||||
## Regeln (nicht verhandelbar)
|
||||
|
||||
- Git → Push → Komodo. Keine direkten Komodo-Edits.
|
||||
- Stop/Start-Tests sind okay, aber nur kurz (≤ 3 min) und mit
|
||||
Wiederanlauf-Schritt im selben Block.
|
||||
- Secrets nicht ausgeben.
|
||||
- Bei zwei gescheiterten Versuchen: stop, Pflichtmatrix aus
|
||||
`docs/GITOPS_DRIFT_RUNBOOK.md`, Operator fragen.
|
||||
@@ -0,0 +1,83 @@
|
||||
# Codex-Prompt: KalliLab Konsolidierung (Bewertungs-Followup)
|
||||
|
||||
> **Status (Stand 2026-05-30):** Erstprompt fuer den Audit-Zyklus 2026-05-25, Stand weitgehend abgearbeitet. Verbleibende Punkte sind in `docs/AUDIT_2026-05-25_TODO.md` weiter gefuehrt (offen, geparkt, bewusst nicht umgesetzt). Datei bleibt im Repo als **Codex-Prompt-Vorlage** fuer kuenftige Konsolidierungs-Sweeps; inhaltlich nicht mehr aendern.
|
||||
|
||||
Stand: 2026-05-23
|
||||
Auftraggeber: Operator
|
||||
Quelle: `docs/archive/2026-05/STRATEGISCHE_BEWERTUNG_2026-05-23.md`
|
||||
|
||||
## Schritt 0 — Reviewe die Bewertung kritisch
|
||||
|
||||
Lies `docs/archive/2026-05/STRATEGISCHE_BEWERTUNG_2026-05-23.md` komplett. Bevor du irgendetwas anfasst, sag dem Operator ehrlich:
|
||||
|
||||
- Wo ist Claudes Befund richtig?
|
||||
- Wo liegt Claude daneben oder hat etwas Wichtiges uebersehen?
|
||||
- Welche Hausaufgaben unten wuerdest du anders priorisieren oder weglassen?
|
||||
|
||||
Erst nach Operator-Freigabe weitermachen.
|
||||
|
||||
## Lies vor jedem Block
|
||||
|
||||
`CLAUDE.md`, `docs/WORKFLOW.md`, betroffene Compose-Datei. Bei DR/Backup zusaetzlich `docs/DISASTER_RECOVERY.md` und `docs/RESTORE_MATRIX.md`.
|
||||
|
||||
## Hausaufgaben
|
||||
|
||||
### P0 — Quick Wins (≤ 1 Woche, hoher Nutzen)
|
||||
|
||||
1. **Externer Repo-Mirror** einrichten (GitHub privat oder zweites Gitea); Push-Mirror in Gitea aktivieren. Schliesst das groesste DR-Loch.
|
||||
2. **Borg-Passphrase analog sichern** (Schliessfach oder Familienmitglied).
|
||||
3. **Jellyfin entfernen, Plex bleibt.** Detail-Schritte in `docs/archive/2026-05/CODEX_JELLYFIN_REMOVAL_2026-05-23.md`. Kurzfassung: Plex-Smoke-Test → Komodo-Stop → Authelia-Bypass raus + Host-Sync → `git rm apps/jellyfin/` → Doku (MASTER 3.2/4.1/7.4/7.8, SERVICE_CATALOG, REPO_MAP, MIGRATION_LOG) → Appdata nach `_archive/` → Policy-Check → Push → Komodo-Destroy + Webhook weg.
|
||||
4. **Glance oder Homepage** als einziges Dashboard waehlen, das andere stoppen und aus Repo entfernen.
|
||||
5. **AdGuard Admin-Port 8082** hinter Authelia oder nur via Tailscale (Block F aus MASTER 10).
|
||||
6. **Authelia 2FA-Pflicht** fuer alle aktiven User verifizieren bzw. aktivieren.
|
||||
7. **Disk1 NTFS → XFS Phase 2** abschliessen, anschliessend `ALLOW_DISK1_NTFS=0` in posture-check.
|
||||
|
||||
### P1 — Stabilitaet und Ordnung (2–4 Wochen)
|
||||
|
||||
8. **Monitoring-Migration abschliessen**: `monitoring/` produktiv, `ops/grafana-influxdb` + `ops/loki` `down` + aus Repo entfernen.
|
||||
9. **Uptime-Kuma abloesen** durch Blackbox + Grafana-Alerts (nach 7 Tagen Parallelbetrieb mit Paritaet, wie in SERVICE_CATALOG vorgesehen).
|
||||
10. **Hermes-Agent Entscheidung**: produktiv mit klarem Alltagsnutzen oder vollstaendig entfernen. Kein weiteres Quartal "halb da".
|
||||
11. **paperless-gpt und BentoPDF**: gleiche Frage. Produktiv im Workflow oder weg.
|
||||
12. **Unraid USB-Flash-Backup** einrichten (eingebauter Mechanismus).
|
||||
13. **Family-View-Dashboard** in Grafana: alles-gruen-Uebersicht fuer den Morgen-Check.
|
||||
|
||||
### P2 — Automatisierung und Transparenz (4–12 Wochen)
|
||||
|
||||
14. **Authelia OIDC-Provider** aktivieren; Nextcloud + Immich + Grafana als OIDC-Clients.
|
||||
15. **Renovate Bot gegen Gitea** fuer kontrollierte Image-Update-PRs (loest die manuelle Digest-Pflege ab).
|
||||
16. **Restore-Test fuer Immich** als eigener Sprint einplanen (groesster Datentopf ohne Mini-Restore).
|
||||
17. **Immich Smartphone-Auto-Backup** fuer alle Familien-Geraete aktivieren — der eigentliche Familien-Nutzen.
|
||||
18. **CrowdSec vor Traefik** als Bouncer fuer oeffentlich erreichbare Apps.
|
||||
|
||||
### P3 — Advanced (3–6 Monate)
|
||||
|
||||
19. Staging-Branch + zweites Komodo-Ziel in Tailscale-VM.
|
||||
20. Restore-Test-Automatisierung als CI (Gitea Actions oder Drone).
|
||||
21. Off-Site-Backup zu zweitem Ziel (zweites BorgBase-Repo oder Hetzner Storage Box).
|
||||
22. Cold-Standby-Konzept dokumentieren.
|
||||
23. Komodo-Self-Stack aus Komodo-Management herausnehmen, als handgepflegter `docker compose`-Service in `services/`.
|
||||
|
||||
### P4 — Nice-to-have / Spielwiese
|
||||
|
||||
24. Firefly III oder Actual Budget fuer `/mnt/user/finance`.
|
||||
25. Wandtablet im Flur mit Family-Dashboard.
|
||||
26. Home Assistant tiefer in ntfy-Workflows verzahnen (Frostwarnung, PV-Ueberschuss, Briefkasten).
|
||||
27. Ecowitt-Wetter-Dashboard, sobald HA→InfluxDB-Pipeline aus `docs/HOME_ASSISTANT_INFLUXDB_ECOWITT.md` laeuft.
|
||||
|
||||
## Regeln (aus CLAUDE.md, nicht verhandelbar)
|
||||
|
||||
- Git → Push → Komodo. Keine direkten Komodo-Edits, kein `push --force`.
|
||||
- Secrets nie ins Repo, nie loggen.
|
||||
- Appdata-Pfade nicht blind loeschen — vor Removal nach `/mnt/user/appdata/_archive/<ding>-removed-<datum>/` verschieben, 14 Tage warten.
|
||||
- Traefik dynamic config manueller Host-Sync.
|
||||
- Working-Tree-Status nur aus `git status --short`, nie aus `git diff` ueber Linux-Mount.
|
||||
- Nicht anfassen: Komodo native Auth (dokumentierte Ausnahme), Grafana/InfluxDB `user: "0"`, Image-Pinning ddns/glances/scrutiny.
|
||||
- Bei zwei gescheiterten Versuchen: stop, `docs/GITOPS_DRIFT_RUNBOOK.md` Pflichtmatrix, Operator fragen.
|
||||
|
||||
## Arbeitsmodus pro Block
|
||||
|
||||
Lesen → minimal aendern → `ops/policy-checks/check_repo.ps1` → Commit → Push → Komodo + Smoke-Test → eine Zeile in `docs/MIGRATION_LOG.md`.
|
||||
|
||||
## Fertig pro Block
|
||||
|
||||
Kurz an Operator: Commit-SHA, Smoke-Test-Beleg, ggf. neuer Watchpoint.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Disk1 Phase 2 - NTFS to XFS Migration
|
||||
|
||||
Stand: 2026-05-25 06:15 CEST. Ziel erreicht: `/mnt/disk1` wurde von `ntfs3` auf XFS migriert, ohne produktive Compose-Pfade zu aendern. Container nutzen weiter `/mnt/user/...`.
|
||||
|
||||
## Preflight
|
||||
|
||||
| Check | Ergebnis |
|
||||
|---|---|
|
||||
| Disk1 Mount | `/dev/md1p1` auf `/mnt/disk1`, `ntfs3`, 5.5T, 1.7T genutzt, 3.8T frei |
|
||||
| Cache Mount | `/dev/nvme0n1p1` auf `/mnt/cache`, `xfs`, 1.9T, 100G genutzt |
|
||||
| H: Backup-Ziel | `H:\`, Label `Externe HDD`, NTFS, 8T, 5.96T frei, healthy |
|
||||
| Compose-Binds | Keine Treffer fuer direkte `/mnt/disk1`, `/mnt/cache`, `/mnt/disks`, `/mnt/remotes` Binds |
|
||||
| SMB-Zugriff | `\\Kallilabcore\services`, `documents`, `photos`, `media` erreichbar |
|
||||
|
||||
## Zu sichernde Shares
|
||||
|
||||
| Share | Groesse laut Preflight |
|
||||
|---|---:|
|
||||
| `services` | 451M |
|
||||
| `documents` | 196M |
|
||||
| `photos` | 23G |
|
||||
| `backups` | 2.2G |
|
||||
| `media` | 1.7T |
|
||||
| `finance` | 0 |
|
||||
| `projekte` | 92K |
|
||||
|
||||
Zusaetzliche Disk1-Top-Level-Pfade: `scripts` 3.3M, `isos` 0, `System Volume Information` 0.
|
||||
|
||||
## Backup-Strategie
|
||||
|
||||
- Zielroot: `H:\kallilab-recovery\disk1-phase2-2026-05-23`.
|
||||
- Kritischer Linux-/GitOps-Pfad `services` wird zusaetzlich als Tar-Archiv ueber SSH gesichert, damit Linux-Metadaten erhalten bleiben.
|
||||
- User-Shares werden per SMB/Robocopy kopiert, mit Logs und anschliessender Zaehler-/Groessenverifikation.
|
||||
- Keine produktiven Datenpfade werden geloescht.
|
||||
|
||||
## Gates
|
||||
|
||||
1. Backup komplett und verifiziert.
|
||||
2. Dienste-Freeze vorbereitet und letzte Dumps frisch.
|
||||
3. Direkt vor Format/Array-Prozedur: Operator-Bestaetigung im konkreten Moment.
|
||||
|
||||
## Backup-Ergebnis
|
||||
|
||||
Stand: 2026-05-24 13:07 CEST.
|
||||
|
||||
| Bereich | Sicherungsart | Ergebnis |
|
||||
|---|---|---|
|
||||
| `media` | Robocopy/SMB nach `H:\kallilab-recovery\disk1-phase2-2026-05-23\shares\media` | 2722 Dateien, 1677.11 GiB, Manifestvergleich: 0 missing, 0 size mismatch, 0 extra |
|
||||
| `services` | Host-Tar auf Unraid Cache, danach binaer per `scp` nach H: | `services.tar`, 0.441 GiB, `tar -tf` gueltig |
|
||||
| `documents` | Host-Tar auf Unraid Cache, danach binaer per `scp` nach H: | `documents.tar`, 0.192 GiB, `tar -tf` gueltig |
|
||||
| `photos` | Host-Tar auf Unraid Cache, danach binaer per `scp` nach H: | `photos.tar`, 22.876 GiB, `tar -tf` gueltig |
|
||||
| `backups` | Host-Tar auf Unraid Cache, danach binaer per `scp` nach H: | `backups.tar`, 2.099 GiB, `tar -tf` gueltig |
|
||||
| `finance` | Host-Tar auf Unraid Cache, danach binaer per `scp` nach H: | `finance.tar`, leerer Share, `tar -tf` gueltig |
|
||||
| `projekte` | Host-Tar auf Unraid Cache, danach binaer per `scp` nach H: | `projekte.tar`, klein, `tar -tf` gueltig |
|
||||
| Disk1-Extras `scripts`, `isos` | Host-Tar auf Unraid Cache, danach binaer per `scp` nach H: | `disk1-extra.tar`, 0.003 GiB, `tar -tf` gueltig |
|
||||
|
||||
Hinweis: Erste Tar-Versuche per PowerShell-Redirect wurden verworfen, weil PowerShell den binaeren SSH-Stream als UTF-16 geschrieben hatte. Die ungueltige `media.tar` und unvollstaendige SMB-Teilkopien fuer `services`/`documents` wurden vom Backup-Ziel entfernt, damit nur verwertbare Sicherungen uebrig bleiben.
|
||||
|
||||
## Abschluss
|
||||
|
||||
Stand: 2026-05-25 06:15 CEST.
|
||||
|
||||
| Check | Ergebnis |
|
||||
|---|---|
|
||||
| Freeze-Dumps | `pre-backup-dumps.sh` vor Format ausgefuehrt; nach Wiederanlauf erneut erfolgreich, 15 kanonische Dump-Artefakte juenger als 24 h |
|
||||
| Disk1 Filesystem | `/dev/md1p1` auf `/mnt/disk1`, `xfs`, 5.5T, 1.8T genutzt, 3.7T frei |
|
||||
| Restore `media` | 2722 Dateien, 1,800,782,188,226 Bytes; finaler Manifestvergleich: 0 missing, 0 size mismatch, 0 extra |
|
||||
| Restore Tar-Shares | `services`, `documents`, `photos`, `backups`, `finance`, `projekte` und Disk1-Extras aus H:-Freeze-Archiven nach `/mnt/disk1` extrahiert |
|
||||
| Docker/Services | 49 Container laufend, 0 stopped, 0 unhealthy, 0 starting |
|
||||
| Smoke-Tests | `git.kaleschke.info` 200, `komodo.kaleschke.info` 200, `borg.kaleschke.info` 302, `jellyfin.kaleschke.info` 302, `monitoring.kaleschke.info` 302 |
|
||||
| Service-Mounts | Gitea SSH `:222` offen; Jellyfin und Plex sehen `/media`; Prometheus readiness ok |
|
||||
| Backup-Lauf | Borg-UI Repository `appdata-critical`, letzter Job `completed`, Archiv `Taegliche-Sicherung-2026-05-25T05:52:44.157`, `nfiles=100221` |
|
||||
| Temp-Cleanup | `/mnt/cache/disk1-phase2-tmp/*.tar` nach H:-Verifikation geloescht; Cache weiter XFS mit ca. 1.7T frei |
|
||||
|
||||
Hinweis zum Docker-Wiederanlauf: Nach dem manuellen Docker-Start liefen die Container, aber Healthcheck-Execs scheiterten wegen `dockerd` mit `XDG_RUNTIME_DIR=/run/user/0`. Ein gezielter Docker-Neustart mit unsetztem `XDG_RUNTIME_DIR` behob den Runtime-Fehler; danach wurden alle Healthchecks gruen. `monitoring-prometheus` war durch den geplanten Docker-Stop sauber beendet und wurde als bestehender Container wieder gestartet.
|
||||
|
||||
Offener Nachlauf: Die Array-Parity-Anzeige zeigte nach Abschluss weiter `mdNumDisabled=1`, `mdNumInvalid=1` und `mdResyncAction=check P`, waehrend beide beteiligten Devices `rdevStatus=DISK_OK` und `rdevNumErrors=0` melden. Parity-Zustand separat in Unraid pruefen und keinen Parity-/Disk-Slot ohne Operator-Entscheid aendern.
|
||||
@@ -0,0 +1,104 @@
|
||||
# FRITZ!Box Portfreigaben - Korrektur-Vorbereitung
|
||||
|
||||
Status: **umgesetzt 2026-05-28**, Doku bleibt als Historie und Begruendungs-Anker.
|
||||
Audit-Bezug: `docs/AUDIT_2026-05-25_TODO.md` Sprint 4 ("FRITZ!Box-Portfreigaben gegen Repo-Soll abgleichen") und `docs/NETWORK_INVENTORY.md`.
|
||||
|
||||
## Umsetzungs-Befund 2026-05-28
|
||||
|
||||
| Punkt | Entscheidung | Validierung |
|
||||
|---|---|---|
|
||||
| 1. `80/tcp` entfernen | **umgesetzt** | Mobilfunk-Test: `http://vault.kaleschke.info` Timeout, `https://...` weiter erreichbar. Lokal via LAN: HTTP->HTTPS-Redirect funktioniert weiter durch Traefik. |
|
||||
| 2. `222/tcp` ergaenzen | **bewusst NICHT umgesetzt** | Tailscale bleibt Operator-Pfad; GitHub-Mirror deckt DR-Bootstrap ab; SSH-Brute-Force-Vektor vermieden. Repo-Soll in `NETWORK_INVENTORY.md` und `MASTER_V2.md` Sektion 10 entsprechend angepasst. |
|
||||
| 3. UPnP-Selbstfreigabe `PC-192-168-178-71` | **umgesetzt** | "Selbstständige Portfreigaben fuer dieses Geraet erlauben" deaktiviert. Identifiziert als VONETS-WiFi-Bridge (Hostname `VONETS.COM`, MAC `00:17:13:2F:61:96`) — vermutlich Bridge zum SolarEdge-Wechselrichter. SolarEdge-Cloud-Sync ist outbound und benoetigt keine UPnP. |
|
||||
|
||||
Aktiver Endstand: ausschliesslich `443/tcp -> 192.168.178.58:443` (Traefik HTTPS) ist von WAN aus erreichbar.
|
||||
|
||||
## Aktueller FRITZ!Box-Befund (2026-05-27)
|
||||
|
||||
Aus dem Operator-Live-Check der FRITZ!Box-UI:
|
||||
|
||||
- aktiv: `80/tcp` -> `192.168.178.58`
|
||||
- aktiv: `443/tcp` -> `192.168.178.58`
|
||||
- fehlt: `222/tcp` -> `192.168.178.58` (Gitea-SSH)
|
||||
- zusaetzlich gemeldet: eine Portfreigabe durch das Geraet `PC-192-168-178-71` (Selbst-Freigabe per UPnP)
|
||||
|
||||
## Soll-Stand laut Repo
|
||||
|
||||
`docs/NETWORK_INVENTORY.md` definiert genau zwei aktive Portfreigaben:
|
||||
|
||||
| Erwartete Freigabe | Ziel | Begruendung |
|
||||
|---|---|---|
|
||||
| `443/tcp` -> `192.168.178.58:443` | Traefik HTTPS | einziger Public-HTTPS-Einstieg, Wildcard-Zert ueber Cloudflare-DNS-Challenge |
|
||||
| `222/tcp` -> `192.168.178.58:222` | Gitea SSH | Git-SSH-Push/Pull; dokumentierte Ausnahme |
|
||||
|
||||
Port `80/tcp` ist im Cloudflare-DNS-Challenge-Modell **nicht** notwendig.
|
||||
|
||||
## Drei Korrektur-Punkte
|
||||
|
||||
### 1. `80/tcp` entfernen
|
||||
|
||||
Begruendung:
|
||||
|
||||
- ACME laeuft als Cloudflare-DNS-Challenge (`traefik/docker-compose.yml`), nicht als HTTP-01.
|
||||
- Traefik leitet intern jeden HTTP-Request auf `https://` weiter; ein WAN-`80`-Listener bietet keinen Mehrwert, oeffnet aber einen zusaetzlichen Angriffsvektor (Header-/Method-Scanning, Open-Redirect-Versuche bevor TLS terminiert).
|
||||
- Innerhalb des LAN funktioniert die Browser-Auto-HTTPS-Umleitung weiter ueber AdGuard-DNS.
|
||||
|
||||
Empfehlung: WAN-Eintrag `80/tcp` in FRITZ!Box-UI **entfernen** nach Operator-Go.
|
||||
|
||||
Validierung nach Aenderung:
|
||||
|
||||
```bash
|
||||
# WAN-seitiger Test, idealerweise von einem Geraet im Mobilfunknetz oder Tailscale-Exit-Node
|
||||
curl -sI http://kaleschke.info/ # erwartet: Connection refused / Timeout
|
||||
curl -sI https://vault.kaleschke.info/ # erwartet: HTTP/2 200 oder Authelia-Redirect
|
||||
```
|
||||
|
||||
### 2. `222/tcp` ergaenzen (nur wenn externes Git-SSH wirklich gewuenscht)
|
||||
|
||||
Frage an Operator: Wird `git@git.kaleschke.info -p 222` von extern gebraucht? Hinweise:
|
||||
|
||||
| Pro `222/tcp` extern | Contra `222/tcp` extern |
|
||||
|---|---|
|
||||
| Push/Pull vom unterwegs-Laptop ohne Tailscale | Tailscale ist schon der Operator-Pfad, deckt das voll ab |
|
||||
| GitHub-Mirror-Bootstrap funktioniert dann auch ohne Tailscale | GitHub-Push-Mirror laeuft automatisch von Gitea aus, braucht kein WAN-SSH |
|
||||
| Externe Webhooks gegen Git push (nicht in Nutzung) | weniger Angriffsflaeche fuer SSH-Brute-Force |
|
||||
|
||||
Empfehlung: `222/tcp` **nicht** ergaenzen, solange Tailscale stabil verfuegbar ist. Stattdessen `docs/NETWORK_INVENTORY.md` und `HOMELAB_ARCHITECTURE_MASTER_V2.md` darauf abgleichen, dass Gitea-SSH bewusst LAN/Tailscale-only ist.
|
||||
|
||||
Wenn Operator entscheidet, `222/tcp` doch extern zu oeffnen: zusaetzlich SSH-Login auf Key-only setzen, Brute-Force-Limits in Gitea pruefen, `docs/NETWORK_INVENTORY.md` "Erwartete Freigabe"-Tabelle aktualisieren.
|
||||
|
||||
### 3. UPnP-Selbstfreigabe von `PC-192-168-178-71` deaktivieren
|
||||
|
||||
Begruendung:
|
||||
|
||||
- Geraete-initiierte Portfreigaben (UPnP) sind ausserhalb der Repo-Sollkonfiguration.
|
||||
- Welcher Port von welchem Programm geoeffnet wurde, ist aus der FRITZ!Box-UI heraus nicht versionierbar.
|
||||
- Wenn der Port gebraucht wird, gehoert er als bewusste Operator-Freigabe in `docs/NETWORK_INVENTORY.md`.
|
||||
|
||||
Empfehlung in zwei Stufen:
|
||||
|
||||
1. FRITZ!Box-UI: in den Geraete-Details fuer `PC-192-168-178-71` die aktuelle Selbstfreigabe-Liste pruefen und mit dem Operator besprechen.
|
||||
2. Wenn der Port nicht gebraucht wird: Selbstfreigabe deaktivieren. Optional: UPnP global pro Geraet abschalten ("Selbststaendige Portfreigaben fuer dieses Geraet erlauben" abwaehlen).
|
||||
|
||||
## Schutzregeln
|
||||
|
||||
- Keine Router-Aenderung ohne ausdrueckliches Operator-Go.
|
||||
- Nach jeder Aenderung: `docs/NETWORK_INVENTORY.md` Abschnitt "FRITZ!Box (WAN -> Host)" gegen den neuen UI-Stand abgleichen.
|
||||
- Aenderung in `docs/MIGRATION_LOG.md` als kurzer Eintrag dokumentieren (was/warum/Validierung).
|
||||
- Bei `80/tcp`-Entfernung kurz prufen, ob irgendein externer Dienst noch HTTP-01 nutzen wollte (sollte nicht der Fall sein).
|
||||
|
||||
## Nicht Teil dieser Vorbereitung
|
||||
|
||||
- FRITZ!OS-Update 8.21 -> aktuell. Das ist eigenes Service-Fenster und braucht WAN/Tailscale-Aufbau-Beobachtung.
|
||||
- IPv6-Exposure. Wenn Telekom IPv6 zustellt und Apps via Cloudflare-AAAA erreichbar sind, kann WAN-Filter pro Port noetig werden. Separater Doku-Punkt in `docs/NETWORK_INVENTORY.md` Offene Entscheidungen.
|
||||
- Mobilfunk-Failover-Stick. Bewusst nicht eingerichtet.
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
| Status | Punkt | Naechster Schritt |
|
||||
|---|---|---|
|
||||
| erledigt 2026-05-28 | `80/tcp` entfernen | umgesetzt, Mobilfunk-validiert |
|
||||
| erledigt 2026-05-28 (bewusst nicht) | `222/tcp` Entscheidung | bleibt Tailscale-only; Repo-Soll entsprechend angepasst |
|
||||
| erledigt 2026-05-28 | UPnP-Freigabe `PC-192-168-178-71` | UPnP-Selbstfreigabe-Recht fuer VONETS-Bridge deaktiviert |
|
||||
| offen | FRITZ!OS 8.21 Update | Service-Fenster, separat geplant |
|
||||
| offen | IPv6-Exposure pruefen | bei naechstem WAN-Touch mit erfassen |
|
||||
@@ -0,0 +1,41 @@
|
||||
# Aktuelle Restliste - KalliLab CORE
|
||||
|
||||
Stand: 2026-05-17
|
||||
|
||||
Diese Datei ersetzt die alte Sprint-Liste vom 2026-05-16. Die damaligen Backup-, Posture-, Logging- und Hardening-Bloecke sind weitgehend erledigt oder dokumentiert. Sie bleibt nur als kurze Restliste fuer die naechsten bewussten Arbeitspakete bestehen.
|
||||
|
||||
## Erledigt / nicht mehr offen
|
||||
|
||||
- Filebrowser-Hardening: breiter Appdata-Mount ist entfernt; Filebrowser mountet nur noch Documents, Photos, Projekte und eigenen App-State.
|
||||
- Authelia Argon2id-Haertung: `iterations: 3`, `memory: 65536`, `parallelism: 4`, `key_length: 32`, `salt_length: 16` sind gesetzt.
|
||||
- Gitea Webhook-Allowlist: `GITEA__webhook__ALLOWED_HOST_LIST` ist auf `komodo-core,localhost,127.0.0.1,192.168.178.0/24` eingeschraenkt.
|
||||
- Backup-Konsistenz: SQLite-/Nextcloud-Dumps, Borg-Scope fuer Nextcloud-Daten, Restore-Matrix und Freshness-Checks sind umgesetzt.
|
||||
- Posture-/Cert-/Drift-Checks: Skripte und Unraid User Scripts sind vorhanden und geplant.
|
||||
- Monitoring-Zielstack: `monitoring/` buendelt Prometheus, Loki, Promtail, Grafana, node-exporter, cAdvisor und InfluxDB 3 Core im Repo-Zielzustand.
|
||||
- Docker-Log-Rotation: Unraid-native Rotation ist dokumentiert; keine separate `/etc/docker/daemon.json` setzen.
|
||||
- Disk1-NTFS-Migration Phase 2: am 2026-05-25 abgeschlossen; Disk1 ist XFS, `posture-check` akzeptiert NTFS nicht mehr als Standard.
|
||||
|
||||
## Morgen / bewusst spaeter
|
||||
|
||||
- Monitoring live finalisieren:
|
||||
- Secrets `monitoring_grafana_admin_password.txt`, `monitoring_grafana_influxdb_token.txt`, `influxdb3_admin_token.json` auf dem Host pruefen/anlegen
|
||||
- `monitoring` in Komodo deployen
|
||||
- alte Stacks `ops/loki` und `ops/grafana-influxdb` nach erfolgreichem Smoke-Test stoppen
|
||||
- `https://monitoring.kaleschke.info`, Prometheus Targets, Loki-Logs und InfluxDB-Datasource pruefen
|
||||
- Home Assistant -> InfluxDB finalisieren:
|
||||
- HA-Token/Writer final pruefen
|
||||
- erste Messwerte in InfluxDB verifizieren
|
||||
- Grafana-HA-/Wetter-Dashboard in `monitoring-grafana` aufbauen
|
||||
- Hermes VM-Seite:
|
||||
- Runner-VM, echte `.env`, SSH-Key und Dashboard/Gateway final zusammenfuehren
|
||||
- NAS-Stack erst starten, wenn VM-Seite bereit ist
|
||||
|
||||
## Verbleibende bekannte Warnings
|
||||
|
||||
- `ddns-updater`, `glances`, `scrutiny`: nutzen noch `latest...@sha256`; spaeter durch konkrete Versionstags ersetzen, sofern upstream sinnvoll versioniert.
|
||||
- `ops/grafana-influxdb` und `ops/loki`: bleiben nur noch als Rollback-/Migrationsreferenz im Repo, nach Live-Migration nicht parallel betreiben.
|
||||
- `scrutiny`: bleibt `privileged: true`; dokumentierte SMART-Ausnahme, spaeter erneut pruefen.
|
||||
|
||||
## Regel
|
||||
|
||||
Neue Arbeit erst starten, wenn klar ist, ob sie eines der drei Morgen-Themen betrifft oder eine der bekannten Warnings bewusst abbaut.
|
||||
@@ -0,0 +1,89 @@
|
||||
# Recovery Handoff - KalliLab CORE - 2026-05-15
|
||||
|
||||
Zweck: Startpunkt fuer einen neuen Chat, ohne das komplette Repo erneut zu lesen.
|
||||
|
||||
## Kontext
|
||||
|
||||
- Incident: NTFS-Cache-Vorfall ab 2026-05-11.
|
||||
- Host: Unraid `Kallilabcore`, SSH `root@192.168.178.58`.
|
||||
- Root Cause: Cache war NTFS/ntfs3; Disk1 ist noch NTFS/ntfs3 und wird spaeter separat migriert.
|
||||
- Recovery-Prinzip: `docs/STORAGE_LAYOUT.md` ist bindend. Zum Zeitpunkt dieses Handoffs hiess die Datei noch `docs/STORAGE_LAYOUT.draft.md`.
|
||||
- Keine Stacks starten, wenn ein Pfad/Setting gegen Storage Layout, Restore Matrix oder Architecture Master verstoesst.
|
||||
|
||||
## Host-Zustand
|
||||
|
||||
- Cache wurde erfolgreich von NTFS auf XFS neu formatiert.
|
||||
- Verifiziert: `/mnt/cache` ist XFS auf `/dev/nvme0n1p1`.
|
||||
- Disk1 bleibt vorerst NTFS auf `/mnt/disk1`; Migration ist Phase 2 nach stabilem Cache-Betrieb.
|
||||
- Docker und Libvirt wurden nach dem Format wieder gestoppt.
|
||||
- `/mnt/user/appdata` ist leer bzw. nur Basisverzeichnis; produktive Appdaten sind noch nicht restored.
|
||||
- Share-Settings wurden nach Storage Layout korrigiert:
|
||||
- `appdata`, `system`, `domains`: cache `only`
|
||||
- `services`, `documents`, `photos`, `backups`, `media`, `finance`, `projekte`: cache `no`, include `disk1`
|
||||
- `isos`: cache `yes`
|
||||
- Backup alter Share-Configs: `/boot/config/shares.bak-20260515-pre-storage-layout`
|
||||
|
||||
## Image und Backups
|
||||
|
||||
- Full NVMe image liegt auf Windows `H:\kallilab-recovery\2026-05-14\nvme0n1-full-20260514.img`.
|
||||
- `dd` exit code war `0`; Image-Groesse/Padding geprueft; Source-Raw-Hash war fertig.
|
||||
- Image-Data-Hash wurde aus Zeitgruenden bewusst abgebrochen. Risiko wurde als ca. 1-3 Prozent eingeschaetzt.
|
||||
- Hetzner-Borg-Archiv `Taegliche-Sicherung-2026-05-10T04:30:52.050` wurde als lesbare Recovery-Quelle verifiziert.
|
||||
- Verifiziert wurden u. a. Vaultwarden SQLite, Gitea SQLite, Postgres-Dumps und Komodo Mongo-Archiv-Header.
|
||||
- Lokaler Verify-Auszug liegt unter `H:\kallilab-recovery\2026-05-14\borg-verify-may10`.
|
||||
|
||||
## Entscheidungen seit dem Cache-Rebuild
|
||||
|
||||
- WD MyBookLive Duo wird komplett aus dem Setup entfernt.
|
||||
- Backrest wird komplett aus dem aktiven Setup entfernt.
|
||||
- Borg ist alleinige Backup-Technologie.
|
||||
- Appdata Backup Plugin bleibt deaktiviert; WD-Ziele wurden aus aktiver Host-Konfiguration geleert.
|
||||
- Unassigned Devices SMB-Remote fuer `//MYBOOKLIVEDUO/Public` wurde aus aktiver Host-Konfiguration entfernt.
|
||||
- Backrest User Script `check_backrest_hetzner` wurde aus Schedule/Cron entfernt.
|
||||
- Host-Konfig-Backup fuer diese Bereinigung: `/boot/config/cleanup-backup-20260515-remove-wd-backrest`
|
||||
|
||||
## Repo-Aenderungen im aktuellen Arbeitsbaum
|
||||
|
||||
Backrest wurde aus dem aktiven Zielbild entfernt:
|
||||
|
||||
- `ops/backrest/docker-compose.yml` geloescht
|
||||
- `HOMELAB_ARCHITECTURE_MASTER_V2.md` aktualisiert
|
||||
- `docs/REPO_MAP.md` aktualisiert
|
||||
- `docs/SERVICE_CATALOG.md` aktualisiert
|
||||
- `docs/RESTORE_MATRIX.md` aktualisiert
|
||||
- `docs/AI_CONTEXT.md` aktualisiert
|
||||
- `docs/DISASTER_RECOVERY.md` aktualisiert
|
||||
- `ops/borg-ui/BACKUP_SCOPE.md` aktualisiert
|
||||
- `ops/hermes-agent/services.json` aktualisiert
|
||||
- `ops/hermes-agent/services.yaml` aktualisiert
|
||||
- `ops/policy-checks/last-report.md` aktualisiert
|
||||
|
||||
Verifikation:
|
||||
|
||||
- `rg "/mnt/(cache|disk1|disks|remotes)" -g docker-compose.yml -g compose.yaml -g *.yml -g *.yaml` findet keine aktiven Compose/YAML-Treffer.
|
||||
- `rg "ops/backrest|backrest.kaleschke|/mnt/user/appdata/backrest|192.168.178.86|MYBOOKLIVEDUO|WD-DUO"` findet nur historische/gewollte Hinweise.
|
||||
- `python -m json.tool ops/hermes-agent/services.json` ok.
|
||||
- `ops/hermes-agent/services.yaml` YAML ok.
|
||||
- `ops/policy-checks/check_repo.ps1` ok: 29 Compose-Dateien, 0 Critical, 4 Warnings.
|
||||
|
||||
## Wichtigste Stop-Regeln
|
||||
|
||||
- Keine Container starten, solange Core-Pfade oder Share-Settings nicht gegen Storage Layout geprueft sind.
|
||||
- Keine Backrest-/WD-Referenzen reaktivieren.
|
||||
- Keine Bind-Mounts auf `/mnt/cache`, `/mnt/disk1`, `/mnt/disks`, `/mnt/remotes`.
|
||||
- Keine Schreibaktionen auf Disk1 ausser bewusst noetig; Disk1 ist noch NTFS.
|
||||
- Komodo nur gemeinsam und explizit anfassen.
|
||||
- Erst Daten/Secrets restoren, dann Stacks einzeln starten und smoke-testen.
|
||||
|
||||
## Naechster sinnvoller Schritt
|
||||
|
||||
1. Repo-Aenderungen kurz reviewen und committen/pushen, bevor Komodo wieder produktiv wird.
|
||||
2. DNS-Basis wiederherstellen:
|
||||
- AdGuard: `/mnt/user/appdata/adguard/conf` aus Borg oder Image restoren; `work` kann frisch sein.
|
||||
- Unbound: `/mnt/user/appdata/unbound/config` aus Borg oder Image restoren.
|
||||
- Danach nur AdGuard + Unbound starten und DNS testen.
|
||||
3. Danach Traefik + Authelia + Gitea/Vaultwarden in kleinen Schritten.
|
||||
|
||||
## Startprompt fuer neuen Chat
|
||||
|
||||
Lies zuerst `docs/archive/2026-05/RECOVERY_HANDOFF_2026-05-15.md`, dann `docs/STORAGE_LAYOUT.md`, `docs/RESTORE_MATRIX.md` und nur die Compose-Dateien des naechsten betroffenen Stacks. Fuehre den KalliLab-CORE-Restore token-sparend fort. Nichts erfinden, keine Container starten, wenn etwas gegen Storage Layout verstoesst. Backrest und WD MyBookLive Duo sind entfernt und duerfen nicht wieder ins Setup.
|
||||
@@ -0,0 +1,522 @@
|
||||
# Strategische Bewertung KalliLab CORE
|
||||
|
||||
> **Status (Stand 2026-05-30): Historischer Snapshot vom 2026-05-23, inhaltlich grossteils ueberholt.**
|
||||
>
|
||||
> Dieses Dokument bleibt im Repo als Audit-Anker und als "wo standen wir am 2026-05-23". Die konkreten Befunde, Top-5-Listen und Mehrwert-Fahrplaene sind durch den Audit-Zyklus 2026-05-25 zu einem grossen Teil **abgearbeitet, bewusst nicht umgesetzt oder explizit geparkt**.
|
||||
>
|
||||
> - **Nicht als TODO-Liste lesen.** Aktuelle Arbeitsliste: `docs/AUDIT_2026-05-25_TODO.md`.
|
||||
> - **Originaltext nicht aendern.** Statt Inline-Annotationen steht der pro-Punkt-Status in einer Tabelle am Ende des Dokuments (Abschnitt "Status-Anhang 2026-05-30").
|
||||
> - **Schulnote 2- gilt nicht mehr.** Mit den Konsolidierungen seit 2026-05-25 sind die meisten Notenabzieher behoben; eine neue Note wuerde hier eher bei 1- bis 2 landen, ist aber kein Selbstzweck.
|
||||
|
||||
Stand: 2026-05-23
|
||||
Bewertet von: externer Blick auf den Repo-Sollzustand
|
||||
|
||||
> Diese Bewertung ist bewusst kein Sicherheits- oder Konfigurations-Audit, sondern eine ganzheitliche Einordnung: was das Setup heute leistet, wo es stark ist, wo es zu komplex ist, und wo der nächste echte Mehrwert liegt.
|
||||
|
||||
---
|
||||
|
||||
## Vorbemerkung und Methode
|
||||
|
||||
Bewertet wurde der Repo-Stand auf `master`, nicht der Live-Zustand auf dem Host. Grundlage waren `HOMELAB_ARCHITECTURE_MASTER_V2.md`, `docs/WORKFLOW.md`, `docs/SERVICE_CATALOG.md`, `docs/REPO_MAP.md`, `docs/DISASTER_RECOVERY.md`, `docs/RESTORE_MATRIX.md`, `docs/SECRETS_MAP.md`, `docs/AI_CONTEXT.md`, `docs/GITOPS_DRIFT_RUNBOOK.md`, `docs/HOME_ASSISTANT_INFLUXDB_ECOWITT.md`, `docs/ALERTING_MAP.md`, `ops/borg-ui/BACKUP_SCOPE.md`, `ops/policy-checks/last-report.md`, `ops/restore-tests/schedule.md`, repräsentative Compose-Dateien (Paperless, Monitoring) sowie die Memory-Notiz zum Post-Restore-Sprint.
|
||||
|
||||
Ehrliche Einschätzung in einem Satz: Das ist kein Bastel-Homelab mehr. Das ist eine kleine private Plattform mit dokumentationsbasierter Disziplin, die ein paar Lasten mitschleppt, die man jetzt bewusst loswerden sollte, bevor noch mehr dazukommt.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architektur und Grundidee
|
||||
|
||||
Der Aufbau ist nicht gewachsen, er ist gestaltet. Das sieht man sofort an drei Stellen:
|
||||
|
||||
Erstens trennt das Repo Verantwortlichkeiten konsequent über die Top-Level-Ordner `core/`, `security/`, `infra/`, `apps/`, `ops/`, `host-services/`, `monitoring/`, `traefik/` und `services/`. Das ist keine willkürliche Kosmetik, das spiegelt die Tier-Hierarchie aus DR und Restore wider. Ein neuer Dienst weiß durch das Einordnungsschema in `HOMELAB_ARCHITECTURE_MASTER_V2.md` Abschnitt 6 sofort, wo er hin gehört und in welche Netze er kommt. Das ist überdurchschnittlich.
|
||||
|
||||
Zweitens ist das Netzmodell schlicht und gleichzeitig diszipliniert: `frontend_net` für alles mit Web-UI oder Internetbedarf, `backend_net` `internal: true` für DB/Redis, und app-interne Netze (`mealie_internal`, `immich_default`, `nextcloud_internal`, `monitoring_net`) für Stack-Isolation. Es gibt keine Kunstnetze wie `admin_net` oder `media_net` aus reiner Symmetriesucht. Das ist genau die Linie, die viele Homelabs verfehlen, weil sie entweder alles in ein Bridge-Netz werfen oder fünfzehn semantische Netze erfinden, ohne dass sie was tun.
|
||||
|
||||
Drittens ist die Source-of-Truth-Hierarchie explizit (Gitea Online → lokaler Clone → Komodo → Docker → Host) und es gibt ein Drift-Runbook (`docs/GITOPS_DRIFT_RUNBOOK.md`) mit echter Messreihenfolge. Das schlägt 95% der "Selfhoster mit Portainer und Glück".
|
||||
|
||||
**Wo es trotzdem hakt:** Die Trennung Monitoring/Spielerei ist noch nicht sauber. Es gibt `ops/grafana-influxdb` (Altstand), `ops/loki` (Altstand) und `monitoring/` (Zielstack) gleichzeitig im Repo. Solange die Migration nicht abgeschlossen und die Altstände nicht entfernt sind, ist das echte Doppelpflege-Risiko — und genau so entstehen die Bugs, die man nachher zwei Wochen sucht. Die Doku sagt klar "nicht parallel betreiben", aber das Repo macht es trotzdem möglich. Das ist eine offene Baustelle, kein Architekturproblem.
|
||||
|
||||
**Note für diesen Block: 1-2.**
|
||||
|
||||
---
|
||||
|
||||
## 2. Nutzen und Mehrwert
|
||||
|
||||
Hier wird es ehrlicher: Das Setup hat sehr viel Substanz, aber auch klare Spielereien.
|
||||
|
||||
Echter Alltagsnutzen, der den Aufwand rechtfertigt:
|
||||
|
||||
- **Vaultwarden** als Passwort-Tresor — der Klassiker, der wirklich täglich genutzt wird.
|
||||
- **Paperless-ngx** mit Scan-Inbox, Barcode/ASN-Workflow und Tika aus — das ist klassische Familien-Dokumentenverwaltung mit echtem Wert, sobald man Briefe digitalisiert. Die Barcode-Konfiguration (`PAPERLESS_CONSUMER_BARCODE_DPI=600`, `PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE=1`) zeigt, dass der Workflow durchdacht ist.
|
||||
- **Immich** für Fotos, mit `family_archive`-Mount — das ersetzt sinnvoll Google Photos für eine Familie.
|
||||
- **Nextcloud** für Dateifreigabe und WebDAV/CardDAV — wenn das wirklich genutzt wird, ist es ein echtes Google-Drive/iCloud-Replacement.
|
||||
- **Mealie** für Rezepte — nett, aber das ist ein Lebensmittel-Ding, nicht Infrastruktur.
|
||||
- **Mail-Archiver** — sehr persönlicher Mehrwert, wenn IMAP-Archive aus GMX/Gmail langfristig durchsuchbar bleiben sollen.
|
||||
- **ntfy** als Push-Backbone für `homelab-alerts` und `homelab-info` — operativ unverzichtbar.
|
||||
- **Gitea** — primär als GitOps-Quelle. Für andere Projekte ein Bonus.
|
||||
- **AdGuard Home + Unbound** — ja, das hat Alltagsnutzen für alle Geräte im LAN.
|
||||
- **Tailscale** — Remote-Zugang ohne Port-Freigabe nach außen, klar wertvoll.
|
||||
|
||||
Spielerei oder Overengineering, das ehrlich auf den Prüfstand gehört:
|
||||
|
||||
- **Plex zusätzlich zu Jellyfin**: Beide sind Medienserver mit derselben Bibliothek (`/mnt/user/media`, `/mnt/user/photos`). Plex bringt zwar Remote-Streaming und bessere Clients, Jellyfin bringt native Open-Source-Auth und keine Lizenz. Einen davon kann man weglassen — die ehrlichste Antwort ist, das nach 30 Tagen Nutzungs-Tracking zu entscheiden.
|
||||
- **Glance + Homepage + Komodo-UI als drei parallele Dashboards**: Homepage als Startseite, Glance als zweites Dashboard mit Widgets, Komodo als Stack-Sicht. Hier ist mindestens eines redundant. Glance ist erst seit kurzem live und wirkt eher wie "weil cool" als "weil nötig".
|
||||
- **paperless-gpt**: Coole Idee (LLM für Tagging), aber wenn das nicht aktiv genutzt wird, ist es nur ein Container, der idle Ressourcen frisst. Frage an dich: Wann hast du das letzte Mal eine GPT-Vorschlags-Tag-Liste angenommen?
|
||||
- **BentoPDF**: Ist als "vorbereitet" markiert, Fachabnahme offen. Wenn du in zwei Monaten noch keine PDFs verarbeitet hast: weglassen.
|
||||
- **Hermes-Agent**: Das ist die eindeutigste Spielerei. Ein LLM-Agent über SSH-Runner zu einer separaten VM, mit eigenem Dashboard, dessen NAS-Seite bewusst deaktiviert ist, weil die VM-Seite "offen" ist. Komplexes Modell C, abhängig von einer dedizierten Linux-VM, mit Provider-Keys und Dashboard-Domain. Das ist klassisches Nerd-Lieblingsprojekt-ohne-klaren-Alltagsnutzen-Symptom. Solange du nicht ehrlich beschreiben kannst, was Hermes für dich täglich tut, ist es Reifegrad "Experiment".
|
||||
- **Speedtest-Tracker**: Nett für Monitoring der ISP-Qualität, aber ein einziger Speedtest-Container für eine private Leitung ist eher "ich messe gerne" als "ich brauche das wirklich".
|
||||
- **code-server**: Web-IDE im Browser. Sinnvoll, wenn du wirklich vom iPad aus arbeitest. Sonst: VSCode lokal reicht.
|
||||
|
||||
Use Cases, die echten Mehrwert hätten und fehlen:
|
||||
|
||||
- **Finanzen**: Im DR-Doc steht `/mnt/user/finance` als Share, aber kein App-Stack. Firefly III oder Actual Budget würden hier sofort spürbaren Alltagsnutzen liefern — Konten konsolidieren, Budgets verfolgen, Steuer-Vorbereitung.
|
||||
- **Familien-SSO**: Du hast Authelia, aber Authelia ist primär für Admin-UIs konfiguriert. Wenn deine Familie Nextcloud, Immich, Mealie und Vaultwarden mit einem Login nutzen könnte (Authelia OIDC-Provider), wäre das ein echter Mehrwert für andere als dich.
|
||||
- **Smartphone-Foto-Auto-Backup**: Immich kann das nativ. Wenn das nicht eingerichtet ist und alle Familien-Smartphones automatisch in `immich` landen würden, wäre das die Killer-App für deine Frau und Kinder, nicht für dich.
|
||||
- **Tagliche Familien-Übersicht auf einem Wandtablet**: Homepage oder Glance auf einem alten Tablet im Flur, mit Kalender (Nextcloud), Wetter (Ecowitt), und ntfy-Notifications.
|
||||
- **Kalender/Aufgaben/CardDAV-Nutzung**: Nextcloud kann das, aber ich sehe in der Doku keinen Hinweis, dass die Familie das tatsächlich nutzt. Wenn nicht: Migration weg von Google Calendar/iCloud wäre ein echter Souveränitäts-Gewinn.
|
||||
|
||||
**Note für diesen Block: 2-3.** Die infrastrukturelle Substanz ist top, aber der Anteil "Container läuft, weil ich ihn ausprobieren wollte" ist höher als nötig.
|
||||
|
||||
---
|
||||
|
||||
## 3. Best Practices
|
||||
|
||||
Was richtig gut ist gemessen an dem, was professionelle Setups machen würden:
|
||||
|
||||
- **Image-Pinning mit Tag und Digest** für Stateful Services (Postgres 17.9, Redis 7.4-alpine, Mongo 7.0.32, alle mit `@sha256:...`). Das machen die wenigsten Homelabs. Echt vorbildlich.
|
||||
- **Secrets via Docker `_FILE`-Mounts oder Komodo Stack ENV, niemals im Git** — und das ist konsequent durchgezogen, inklusive `.gitignore` für `.env`-Dateien und expliziter Doku in `docs/SECRETS_MAP.md`.
|
||||
- **`no-new-privileges:true`** als Standard, mit dokumentierten Ausnahmen für Scrutiny (SMART) und Glances (Host-Observability) statt versteckter Lockerungen.
|
||||
- **Policy-as-Code light** über `ops/policy-checks/check_repo.ps1` — der letzte Report zeigt 0 Critical und 4 dokumentierte Warnings. Das ist Tooling-Disziplin, die viele Firmen nicht haben.
|
||||
- **Restore-Tests mit Schedule** (`ops/restore-tests/schedule.md`): wöchentliche Freshness-Checks, monatliche Mini-Restores für Vaultwarden und Gitea, alle zwei Monate Paperless. Erfolg ist explizit als "Smoke-Test passt", nicht "Container startet" definiert. Das ist seltene Reife.
|
||||
- **Pre-Backup-Dumps statt rohe Live-DB-Verzeichnisse als primärer Restore-Pfad** — das ist die Lehre, die viele erst nach dem ersten kaputten Restore lernen.
|
||||
- **Posture-Check + Docker-Critical-Events → ntfy** als Live-Alarmierung, bereits mit Wiederholungsschutz (`ALERT_REPEAT_SECONDS=86400`) und Dedup. Das ist Operations-Reife.
|
||||
- **Cloudflare DNS Challenge für ACME** statt HTTP-01, ermöglicht Wildcard-Zertifikate und keine Port-80-Abhängigkeit für Erneuerung.
|
||||
- **GitOps mit Webhook-Pflicht für neue Stacks** (`docs/WORKFLOW.md`, Abschnitt "Pflicht bei neuen Komodo-Stacks"). Das verhindert "deployed-once-then-forgotten"-Stacks.
|
||||
|
||||
Was Standard wäre und du sinnvoll davon abweichst:
|
||||
|
||||
- **Komodo bewusst ohne pauschale ForwardAuth-Middleware** — richtig, weil Webhooks, API und Periphery sonst brechen. Die meisten würden hier blind Authelia davor schalten und dann zwei Tage debuggen.
|
||||
- **Authelia ohne Redis-Session-Backend** — bewusste Vereinfachung. Du bezahlst dafür mit Re-Login nach Authelia-Restart, gewinnst dafür weniger Tier-1-Abhängigkeiten. Vertretbarer Trade-off.
|
||||
- **Traefik dynamic config als manuelle Host-Sync-Ausnahme** — pragmatisch dokumentiert, statt eines komplexen Auto-Sync-Workarounds.
|
||||
|
||||
Wo du gefährlich von Best Practice abweichst:
|
||||
|
||||
- **Externer Repo-Mirror als DR-Voraussetzung ist offenes TODO** (`docs/DISASTER_RECOVERY.md`, Abschnitt 11). Wenn Gitea ausfällt — und Gitea hängt auch noch an Traefik und PostgreSQL — kannst du Komodo nicht aus Git deployen, kannst die Repo-Doku nicht lesen, und je nach Schaden hast du den lokalen Clone als einzigen Pfad. Das ist ein echter Single Point of Failure. Ein Push-Mirror nach GitHub/GitLab (privat) oder zumindest ein versionierter Sync nach BorgBase würde das in 30 Minuten lösen.
|
||||
- **Unraid USB-Flash-Backup ist offenes TODO**. Wenn der USB-Stick stirbt, ist das nicht das Ende der Welt (Daten leben), aber es kostet einen vollen Wiederaufsetzungs-Tag. Unraid hat dafür einen eingebauten Backup-Mechanismus.
|
||||
- **Komodo Self-Stack Drift Mai 2026**: Du hattest schon einen Vorfall, wo Komodo selbst nicht mehr sauber managebar war ("Recovery-ENV als Tier-1-Secret-Material"). Das Bootstrap-Problem — Komodo verwaltet Komodo — ist nicht gelöst, nur dokumentiert. Eine echte Lösung wäre: Komodo-Self-Stack explizit aus Komodo herauslassen und nur als `docker compose`-Script in `services/` halten.
|
||||
- **Kein Fail2Ban / CrowdSec vor Traefik**. Vaultwarden und Nextcloud sind im Internet erreichbar mit eigener Auth. Die meisten Anti-Brute-Force-Maßnahmen liegen in den Apps selbst, nicht auf Layer 7. Bei einer ernsten Bot-Welle würde Authelia die Last tragen, ohne IP-Bans auszusprechen. CrowdSec als Bouncer für Traefik wäre eine sinnvolle Härtung mit überschaubarem Aufwand.
|
||||
|
||||
**Note für diesen Block: 2.**
|
||||
|
||||
---
|
||||
|
||||
## 4. Nerd-Level / Advanced Homelab
|
||||
|
||||
Was sehr erfahrene Selfhoster mit so einem Repo zusätzlich machen würden:
|
||||
|
||||
- **Renovate Bot oder ein vergleichbares Image-Update-Tracking**: Du pinnst Digests, was richtig ist, aber damit hast du dich auch in die manuelle Update-Pflicht begeben. Renovate gegen Gitea würde wöchentliche PRs für neue Patch-Versionen auf master öffnen, die du mergen oder ignorieren kannst. Das ist deutlich besser als "irgendwann manuell den Digest aktualisieren".
|
||||
- **Staging-Path**: Aktuell hast du master und das ist gleichzeitig produktiv. Ein zweiter Branch (`staging`) der gegen einen zweiten Komodo-Server (in einer Tailscale-VM oder einem zweiten Unraid-Share) deployed, würde Risiko-Aenderungen testbar machen. Das ist viel Aufwand für ein Homelab, aber wenn dich die Stabilität ernsthaft kümmert, ist es der nächste Reifegrad.
|
||||
- **OIDC-Provider statt nur ForwardAuth**: Authelia kann OIDC. Wenn Nextcloud, Immich, Grafana, Komodo (theoretisch), Vaultwarden (via OIDC-Bridge) per SSO laufen, ist das die "echte" Konsolidierung. Heute hast du ForwardAuth für Admin-Dienste, aber Apps mit eigener Auth (Nextcloud, Immich, Jellyfin) sind Eigeninseln.
|
||||
- **Restore-Tests automatisiert in CI**: Du hast Skripts und Cron-Slots, aber kein CI gegen das Repo, das die Restore-Test-Skripte syntaktisch und semantisch prüft. Ein Gitea Actions oder Drone-Setup auf dem Host könnte das gegen jeden Commit laufen lassen.
|
||||
- **Backup-Test-Härtung: Restore in eine echte Test-Domain mit Traefik-Route hinter Authelia** (heute bewusst ohne Domain — siehe `docs/RESTORE_MATRIX.md`). Das ist eine bewusste Entscheidung, würde aber einen "End-to-End restore drill" möglich machen, der einmal pro Quartal komplett durchläuft.
|
||||
- **Disk1 NTFS → XFS Phase 2**: Im Repo dokumentiert, im posture-check temporär toleriert mit `ALLOW_DISK1_NTFS=1`. Das ist die offensichtlichste offene Hardening-Baustelle.
|
||||
- **Loki-Retention und Log-Volume mal anschauen**: 30 Tage Retention ist gut, aber im aktuellen Stand wirst du irgendwann Storage-Probleme bekommen, wenn du nicht weißt, wie viel der Stack pro Tag produziert.
|
||||
|
||||
Was sie bewusst weglassen würden:
|
||||
|
||||
- **Hermes-Agent**: Genau dieses "ich baue mir einen Agenten der über SSH meine VM bedient und ein Dashboard hat" ist das, wovor erfahrene Leute nach dem dritten Homelab warnen. Es bringt Komplexität, Wartungslast und keine messbare Reduktion deiner manuellen Arbeit. Wenn Hermes nicht in den nächsten 60 Tagen produktiv und unverzichtbar wird: entfernen.
|
||||
- **Drei Dashboard-Tools**: Sie würden eines wählen (vermutlich Homepage), die anderen rauswerfen.
|
||||
- **Zwei Medienserver**: Plex und Jellyfin parallel ist Tool-Sammlerei.
|
||||
- **Eigenes paperless-gpt-Container** wenn nicht aktiv im Workflow: lieber das LLM ein-zwei mal manuell auf eine PDF werfen als einen Container 24/7 idle laufen lassen.
|
||||
|
||||
**Note für diesen Block: 2-3.** Sehr nahe am nächsten Reifegrad, aber an drei, vier Stellen würde erfahrene Hand jetzt entrümpeln statt erweitern.
|
||||
|
||||
---
|
||||
|
||||
## 5. Betrieb und Wartbarkeit
|
||||
|
||||
Hier ist die Bewertung am eindeutigsten positiv. Dieses Setup ist langfristig wartbar.
|
||||
|
||||
Die Dokumentation ist auf einem Niveau, das ich selten sehe. `docs/SERVICE_CATALOG.md` ist ein vollständiger Dienst-Katalog mit Restore-Quelle, Smoke-Test und Besonderheiten pro Dienst. `docs/REPO_MAP.md` ist eine technische Landkarte. `docs/RESTORE_MATRIX.md` ist nicht nur "wo ist das Backup", sondern "was ist die führende Quelle", "welche Dumps", "welche Secrets müssen vor Start da sein", "was ist der Smoke-Test". Das ist Doku, die in sechs Monaten noch funktioniert.
|
||||
|
||||
Der Workflow ist klar (`docs/WORKFLOW.md`): Fetch → Pull → ändern → Commit → Push → Komodo. Es gibt eine explizite Stop-Regel ("wenn zwei Reparaturversuche nicht funktionieren, Pflichtmatrix ausfüllen"), die viele Selfhoster nicht haben und stattdessen in Mut-Spiralen rutschen.
|
||||
|
||||
Drei Stellen, wo Wartbarkeit gefährdet ist:
|
||||
|
||||
- **Hermes-Agent**: Spätestens nach sechs Monaten ohne aktive Pflege verstehst du die Model-C-Architektur nicht mehr ohne `ops/hermes-agent/README.md` zu lesen — und dann ist die Frage, warum überhaupt.
|
||||
- **Doppelter Monitoring-Stack (`ops/grafana-influxdb`, `ops/loki`, `monitoring/`)**: Solange beide Welten im Repo sind, vergisst du in einem halben Jahr, welche live ist. Die Migration muss abgeschlossen und die Altstände müssen entfernt werden.
|
||||
- **Authelia Repo-Baseline vs. Host-Config**: Du dokumentierst selbst, dass die Repo-`configuration.yml` "manuell auf den Host gemerged" werden muss, mit OIDC und Secrets hostseitig. Das ist Drift-Risiko per Design. Ein zweiter Mechanismus (z. B. das manuelle Pendant zum Traefik-dynamic-Sync) oder mindestens ein expliziter Diff-Check vor jeder Auth-Änderung wäre Pflicht.
|
||||
|
||||
**Note für diesen Block: 1-2.**
|
||||
|
||||
---
|
||||
|
||||
## 6. Sicherheit und Zugriff
|
||||
|
||||
Du hast eine durchdachte Schichtung:
|
||||
|
||||
- Authelia für Admin-UIs (`uptime`, `borg`, `files`, `code`, `grafana`, `monitoring`, `pdf`, `glance`, `glances`, `scrutiny`, `paperless-gpt`, `speedtest`, `hermes`, `traefik`-Dashboard, `homepage`).
|
||||
- Native App-Auth für User-Apps (`vaultwarden`, `nextcloud`, `immich`, `jellyfin`, `paperless`).
|
||||
- Komodo mit eigener Auth ohne ForwardAuth (bewusste Ausnahme).
|
||||
- Tailscale für Admin-Zugriff von außen.
|
||||
|
||||
Was wirklich gut ist:
|
||||
|
||||
- Authelia mit Argon2id, `iterations=3`, `memory=65536`, `parallelism=4`, `key_length=32`, `salt_length=16` — das ist solide Konfiguration, nicht Default-Müll.
|
||||
- Secrets durchgängig per File-Mount oder Komodo Stack ENV, nie im Compose im Klartext.
|
||||
- Gitea Webhook-Allowlist (`GITEA__webhook__ALLOWED_HOST_LIST=komodo-core,localhost,127.0.0.1,192.168.178.0/24`) und Registrierung deaktiviert — das schließt Webhook-SSRF-Vektoren.
|
||||
- `cloudflare_dns_api_token` als Docker Secret, nicht als ENV.
|
||||
|
||||
Wo du härter trennen solltest:
|
||||
|
||||
- **AdGuard Admin-Port 8082 ist direkt am LAN gebunden ohne Authelia**. Das ist im Architekturdokument als offenes TODO ("Block F") markiert. Im Home-LAN ist das verschmerzbar, aber wenn du eines Tages einen Gast im WLAN hast oder ein IoT-Gerät kompromittiert wird, ist das ein direkter Pfad in die DNS-Konfiguration.
|
||||
- **Nextcloud läuft ohne ForwardAuth** (bewusst wegen WebDAV/CardDAV). Wenn deine Familie schwache Passwörter setzt, ist Nextcloud im Internet das primäre Angriffsziel. Nextcloud-eigene Maßnahmen (Brute-Force-Protection, 2FA-Pflicht für Admin) sollten dokumentiert aktiv sein.
|
||||
- **2FA-Pflicht in Authelia**: In der Doku nicht klar erwähnt. Wenn 2FA nur "optional" ist, läuft die Härtung ins Leere.
|
||||
|
||||
Wo Komfort wichtiger ist und das sinnvoll so bleibt:
|
||||
|
||||
- Komodo ohne ForwardAuth — richtig.
|
||||
- Authelia ohne Redis-Session-Backend — vertretbar.
|
||||
- Plex/Jellyfin mit nativer Auth — sinnvoll, weil die Clients eigene Auth machen.
|
||||
|
||||
**Note für diesen Block: 2.**
|
||||
|
||||
---
|
||||
|
||||
## 7. Backup und Disaster Recovery
|
||||
|
||||
Das ist eine der stärksten Säulen.
|
||||
|
||||
Was du richtig machst:
|
||||
|
||||
- Borg statt Backrest — dokumentierte Entscheidung, eine Backup-Technologie statt zwei.
|
||||
- **Pre-Backup-Dumps als kanonische Restore-Quelle**, nicht rohe Live-DB-Verzeichnisse. Explizit dokumentiert in `ops/borg-ui/BACKUP_SCOPE.md` ("Do not back up raw live database storage directories as the primary recovery artifact").
|
||||
- **Restore-Tests mit Schedule** und expliziter Erfolgsregel ("Container läuft reicht nicht — Smoke-Test muss greifen").
|
||||
- Dump-Skript für SQLite-Container (Gitea, Vaultwarden, Uptime-Kuma, Speedtest-Tracker), BoltDB-Snapshot für Filebrowser, `pg_dump` für die einzelnen Postgres-Datenbanken, `mongodump` für Komodo-Mongo.
|
||||
- Borg-Scope erweitert um `/mnt/user/services` für GitOps-Recovery (Repo, Stack-Workspaces, Posture-Check-State).
|
||||
- Tier-Modell in `docs/RESTORE_MATRIX.md` mit klarer Reihenfolge.
|
||||
- Dokumentierte Restore-Lab-Praxis: Testpfad `/mnt/user/backups/restore-lab/<dienst>`, Reports unter `/mnt/user/backups/restore-reports`, ohne Traefik-Route — keine Vermischung von Test und Produktion.
|
||||
|
||||
Was wirklich offen ist:
|
||||
|
||||
- **Externer Backup-Mirror oder Off-Site-Ziel**: BorgBase ist erwähnt (`ops/borg-ui` als Borg-UI auf BorgBase-Repo), aber die Frage "was passiert, wenn der Unraid-Host und BorgBase gleichzeitig down sind" hat keine dokumentierte Antwort. Zwei Repos (z. B. BorgBase + ein zweites lokales NAS oder ein Hetzner Storage Box) wären die Standardlösung.
|
||||
- **Externer Repo-Mirror als DR-Voraussetzung** — in DR.md als TODO markiert. Wenn Gitea nicht aufsteht, ist das Repo nur über deinen lokalen Clone erreichbar.
|
||||
- **Unraid USB-Flash-Backup** — in DR.md als TODO markiert.
|
||||
- **Borg-Passphrase extern sicher hinterlegt** — als TODO markiert. Das ist die typische "wenn das Haus brennt"-Frage. Vaultwarden hilft dir nicht, wenn Vaultwarden gerade restauriert werden soll. Eine zweite Kopie der Passphrase (verschlüsselt auf einem USB-Stick im Bankschließfach, oder bei einem Familienmitglied) ist Standard.
|
||||
- **Komodo-Mongo Dump nach Major-Upgrades verifizieren** — als Watchpoint dokumentiert, aber nicht im automatischen Restore-Test-Cron.
|
||||
|
||||
Restore-Tests sind monatlich für Vaultwarden und Gitea, alle zwei Monate für Paperless, "später" für Immich. Das ist gut, aber Immich-Restore-Tests sind die kritischsten, weil dort die größten Datenmengen liegen und ein silent corruption am schmerzhaftesten wäre.
|
||||
|
||||
**Note für diesen Block: 1-2.** Wenn die offenen DR-Vorbereitungs-TODOs abgehakt wären, klare 1.
|
||||
|
||||
---
|
||||
|
||||
## 8. Monitoring und Transparenz
|
||||
|
||||
Das ist der Bereich mit dem größten Übergang. Du hast viele Tools, mit Überschneidungen, und der zentrale Monitoring-Stack ist im Aufbau.
|
||||
|
||||
Was du heute hast:
|
||||
|
||||
- **Uptime-Kuma**: HTTP/TCP-Uptime-Checks mit Web-UI.
|
||||
- **Glances**: Live-System-Sicht (CPU/RAM/Disk pro Host).
|
||||
- **Scrutiny**: SMART-Monitoring für Laufwerke.
|
||||
- **Speedtest-Tracker**: Periodische Speedtests gegen den ISP.
|
||||
- **Glance**: Status-Dashboard mit Widgets (Immich, AdGuard, Speedtest, Docker-Container).
|
||||
- **Homepage**: Start-Dashboard mit Service-Cards.
|
||||
- **Posture-Check**: Host-Filesystem, NVMe-SMART, Mover, Füllstand → ntfy.
|
||||
- **Docker-Critical-Events**: `die`/`oom`/`kill` → ntfy.
|
||||
- **`monitoring/`-Zielstack**: Prometheus, Alertmanager, ntfy-Bridge, Blackbox, Loki, Promtail, Grafana, node-exporter, cAdvisor, InfluxDB 3 Core.
|
||||
|
||||
Was richtig gut ist:
|
||||
|
||||
- **Ein zentraler Alert-Pfad**: alle problemrelevanten Meldungen landen auf `homelab-alerts` per ntfy. Das ist die wichtigste Disziplin und du hast sie. `docs/ALERTING_MAP.md` listet alle Sender.
|
||||
- Prometheus-Stack mit Alertmanager + Bridge zu ntfy, also nicht "Grafana sendet Email" sondern "Alertmanager-Pflicht-Pfad".
|
||||
- Blackbox-Exporter ersetzt mittelfristig Uptime-Kuma (richtige Strategie).
|
||||
- 30 Tage Retention für Prometheus und Loki — sinnvoll für Diagnose-Daten, kein Backup-Surrogat.
|
||||
- node-exporter + cAdvisor + Traefik-Metrics → wirklich vollständige Infrastruktur-Telemetrie.
|
||||
|
||||
Was fehlt oder zu viel ist:
|
||||
|
||||
- **Doppelte Beobachtungs-Tools nebeneinander**: Uptime-Kuma vs. Blackbox, Glances vs. node-exporter+cAdvisor, Glance vs. Homepage. Du weißt das, die Migration ist im Gang. Bis sie fertig ist, gibt es Verwirrung darüber, welches die "Wahrheit" ist.
|
||||
- **Smoke-Test-Dashboards**: In `monitoring/grafana/dashboards/` sind ein paar Dashboards, aber die "Family-View" — "alles grün, alles erreichbar, Backup heute Nacht durchgelaufen" — fehlt als explizites Dashboard. Das wäre der Wert für dich selbst: morgens kurz draufschauen und wissen, ob etwas die Aufmerksamkeit braucht.
|
||||
- **Alert-Regeln explizit listen**: `monitoring/prometheus/alerts.yml` existiert, aber eine kurze Doku, welche Regeln wann feuern (Disk > 90%, Borg älter 36h, Cert läuft in 14 Tagen ab, etc.), würde die Operations-Reife komplettieren.
|
||||
- **Cert-Token-Check** läuft (laut ALERTING_MAP) — gut, das ist die einzige sinnvolle Methode, "TLS-Cert läuft ab" früh genug zu sehen.
|
||||
|
||||
**Note für diesen Block: 3.** Bricht ab, sobald die Monitoring-Migration sauber abgeschlossen ist und die Altstände entfernt sind — dann eine 2.
|
||||
|
||||
---
|
||||
|
||||
## 9. Konkreter Mehrwert-Fahrplan
|
||||
|
||||
### Quick Wins (≤ eine Woche, hoher Nutzen)
|
||||
|
||||
- **Externer Push-Mirror für das Repo nach GitHub privat** einrichten. Das ist ein Webhook in Gitea + ein leerer GitHub-Privat-Repo. 30 Minuten. Löst das wichtigste DR-Risiko.
|
||||
- **Borg-Passphrase auf einen USB-Stick im Bankschließfach** oder in eine versiegelte Umschlag-Box. Eine analoge Sicherung gegen das digitale Worst-Case-Szenario.
|
||||
- **Plex oder Jellyfin entscheiden**: einen davon weg. 14 Tage Nutzungs-Tracking via Server-Logs oder einfach beobachten, wer welchen Client öffnet. Dann den ungenutzten Stack archivieren.
|
||||
- **Glance ODER Homepage** als einziges Dashboard wählen. Heute laufen beide. Es gibt keinen technischen Grund für zwei.
|
||||
- **Authelia 2FA-Pflicht für alle aktiven User** verifizieren — wenn nicht gesetzt, jetzt setzen.
|
||||
- **Disk1 NTFS → XFS Phase 2 abschließen** — das ist im Repo dokumentiert und im posture-check als Übergangsausnahme markiert. Loswerden.
|
||||
|
||||
### Phase 1 (zwei bis vier Wochen, Stabilität und Ordnung)
|
||||
|
||||
- **Monitoring-Migration abschließen und Altstände entfernen**: `monitoring/` produktiv, dann `ops/grafana-influxdb` und `ops/loki` aus dem Repo löschen (mit Backup-Branch fürs Gewissen).
|
||||
- **Uptime-Kuma ablösen durch Blackbox + Grafana-Alerts**: nach den sieben Tagen Parallelbetrieb, die in `docs/SERVICE_CATALOG.md` als Pflicht stehen.
|
||||
- **Hermes-Agent ehrliche Entscheidung**: produktiv machen mit klarem Alltagsnutzen, oder entfernen. Kein "halb da, halb deaktiviert"-Zustand für ein weiteres Quartal.
|
||||
- **paperless-gpt und BentoPDF Status**: gleiche Frage. Produktiv oder weg.
|
||||
- **Unraid USB-Flash-Backup** einrichten (Unraid hat einen eingebauten Mechanismus).
|
||||
- **Ein Family-View-Dashboard in Grafana** bauen: alles-grün-Übersicht für den Morgen-Check.
|
||||
|
||||
### Phase 2 (vier bis zwölf Wochen, Automatisierung und Transparenz)
|
||||
|
||||
- **Authelia OIDC-Provider aktivieren** und Nextcloud, Immich, Grafana als OIDC-Clients konfigurieren. Echtes SSO für die Familie.
|
||||
- **Renovate Bot gegen Gitea** für kontrollierte Image-Updates (PRs statt manuelle Digest-Pflege).
|
||||
- **Restore-Test für Immich** als eigener Sprint einplanen — der größte Datentopf und der einzige Tier-2-Dienst ohne Mini-Restore-Test.
|
||||
- **Familie onboarden**: Smartphone-Auto-Backup zu Immich für alle Familien-Geräte. Das ist der Schritt vom "ich betreibe Container" zum "meine Familie benutzt aktiv was Selbstgebautes".
|
||||
- **CrowdSec vor Traefik** als Bouncer für die öffentlich erreichbaren Apps (Vaultwarden, Nextcloud, Immich, Gitea).
|
||||
|
||||
### Phase 3 (drei bis sechs Monate, Advanced Nerd-Level)
|
||||
|
||||
- **Staging-Branch + zweites Komodo-Ziel** in einer Tailscale-VM, für Risiko-Änderungen.
|
||||
- **Restore-Test-Automatisierung als CI** (Gitea Actions oder Drone).
|
||||
- **Off-Site-Backup zu einem zweiten Ziel** (zweites BorgBase-Repo, Hetzner Storage Box, oder zweites NAS bei einem Familienmitglied).
|
||||
- **Cold-Standby-Konzept** dokumentieren: was passiert, wenn der Unraid-Host stirbt und du erst in zwei Wochen Ersatz hast?
|
||||
- **Komodo-Self-Stack rausnehmen** und als handgepflegten `docker compose`-Service in `services/` halten — löst das Bootstrap-Problem.
|
||||
|
||||
### Phase 4 (Spielwiese, nice-to-have)
|
||||
|
||||
- Firefly III oder Actual Budget für Finanz-Übersicht.
|
||||
- Wandtablet-Setup im Flur mit Family-Dashboard.
|
||||
- Smart-Home-Automatisierungen über Home Assistant tiefer mit ntfy verzahnen (Frost-Warnung, PV-Überschuss-Hinweis, Briefkasten-Sensor).
|
||||
- Ein eigenes kleines Dashboard für Ecowitt-Wetterdaten (sobald die Pipeline aus `docs/HOME_ASSISTANT_INFLUXDB_ECOWITT.md` läuft).
|
||||
|
||||
---
|
||||
|
||||
## Schulnote, Top-5-Listen, klare Empfehlung
|
||||
|
||||
### Schulnote
|
||||
|
||||
**2- (gut bis befriedigend, eher 2).**
|
||||
|
||||
Auf der Skala "durchschnittliches Homelab" wäre das eine 1. Die strukturelle Disziplin, GitOps-Konsequenz, Doku-Qualität, Backup-Reife und Architektur-Klarheit liegen weit über dem, was die meisten Selfhoster jemals erreichen. Was die Note von einer 1 runterzieht: drei bis fünf offene Baustellen, die nicht trivial sind (externer Repo-Mirror, Monitoring-Migration unfertig, Hermes-Agent im Schwebezustand, zwei Medienserver parallel, AdGuard Admin-Port ohne ForwardAuth). Wenn du Phase 1 abschließt, bist du klar bei einer 1.
|
||||
|
||||
### Top 5 sofort verbessern
|
||||
|
||||
1. **Externer Repo-Mirror** (GitHub privat, BorgBase, oder zweites Gitea). 30 Minuten Aufwand, schließt das wichtigste DR-Loch.
|
||||
2. **Borg-Passphrase analog außerhalb des Systems sichern** (Bankschließfach, Familienmitglied, Tresor).
|
||||
3. **Plex oder Jellyfin entscheiden**, einen davon entfernen.
|
||||
4. **Glance oder Homepage** als einziges Dashboard wählen.
|
||||
5. **AdGuard Admin-Port hinter Authelia** oder mindestens nur via Tailscale erreichbar (heute LAN-direkt).
|
||||
|
||||
### Top 5 mit dem größten zusätzlichen Mehrwert
|
||||
|
||||
1. **Smartphone-Auto-Backup zu Immich für die ganze Familie**: macht aus deinem Foto-Server eine echte Killer-App für andere als dich.
|
||||
2. **Authelia OIDC-Provider aktivieren** und Nextcloud + Immich + Grafana per SSO: ein Login für alle wichtigen Apps.
|
||||
3. **Renovate Bot gegen Gitea**: automatisierte Update-PRs für deine Digest-pinnten Images.
|
||||
4. **Family-View-Dashboard in Grafana**: morgens 30 Sekunden draufschauen statt Tools-Tour.
|
||||
5. **Finanz-App (Firefly III oder Actual Budget)**: füllt den `/mnt/user/finance`-Share mit echtem Alltagsnutzen.
|
||||
|
||||
### Top 5 lieber NICHT machen
|
||||
|
||||
1. **Hermes-Agent ausbauen statt loswerden**. Wenn du in 60 Tagen nicht ehrlich sagen kannst, was Hermes dir täglich abnimmt: weg damit. Komplexität ohne Gegenwert ist das größte Anti-Pattern in jedem Homelab.
|
||||
2. **Noch mehr Dashboards einbauen**. Du hast bereits Homepage, Glance, Komodo-UI und kommst gleich noch mit Grafana-Family-View. Mehr wäre Sammlerei.
|
||||
3. **Pauschale Authelia-ForwardAuth vor Komodo** schalten. Dokumentierte Ausnahme aus gutem Grund. Webhooks, API und Periphery würden brechen.
|
||||
4. **Backend_net auf `external: true` statt `internal: true`** umstellen, weil "ist ja einfacher". Genau das ist die Mauer, die viele Apps vor öffentlichem Zugriff schützt.
|
||||
5. **Komodo Self-Stack komplett über Komodo managen lassen**. Du hattest schon einen Drift-Vorfall. Komodo verwaltet Komodo ist ein Bootstrap-Problem ohne befriedigende Lösung.
|
||||
|
||||
### Klare Empfehlung
|
||||
|
||||
**Vereinfachen und konsolidieren, NICHT weiter ausbauen.**
|
||||
|
||||
Du bist an einem Punkt, an dem das Setup mehr Substanz hat, als aktiv genutzt wird. Die nächsten sechs Monate sollten weniger neue Dienste sehen und mehr Entrümpelung (Plex vs. Jellyfin, Glance vs. Homepage, Hermes-Entscheidung, Monitoring-Altstände raus, paperless-gpt/BentoPDF-Entscheidung), mehr Familien-Aktivierung (Immich-Smartphone-Backup, OIDC-SSO, Family-Dashboard), und mehr DR-Resilienz (externer Mirror, Off-Site-Backup-Ziel, Borg-Passphrase analog gesichert).
|
||||
|
||||
Wenn du das in den nächsten drei Monaten machst, hast du eine private Plattform mit echtem Alltagsnutzen, klarer Wartbarkeit, und einer Wiederherstellbarkeit, die seriöser ist als das, was viele Mittelstandsfirmen für ihre Office-IT haben. Das ist das Ziel, nicht "noch ein Container".
|
||||
|
||||
Wenn du dann weiterausbauen willst, bist du in der Position, das aus einer Stärke heraus zu tun, nicht aus dem "ich muss noch das hier probieren"-Reflex.
|
||||
|
||||
---
|
||||
|
||||
## Status-Anhang 2026-05-30
|
||||
|
||||
Dieser Anhang ist nicht Teil der Originalbewertung vom 2026-05-23. Er ordnet jedem konkret handelbaren Befund den tatsaechlichen Stand nach den Audit-Sprints zu, damit das Dokument selbststaendig lesbar bleibt.
|
||||
|
||||
### Block 1 - Architektur
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| ops/grafana-influxdb + ops/loki + monitoring/ parallel im Repo | **erledigt** 2026-05-26: Altstaende entfernt, monitoring/ einziger aktiver Observability-Stack |
|
||||
|
||||
### Block 2 - Nutzen und Mehrwert
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Plex zusaetzlich zu Jellyfin | **erledigt** 2026-05-25: Jellyfin entfernt, Plex bleibt einziger Medienserver |
|
||||
| Glance + Homepage + Komodo-UI als drei parallele Dashboards | **erledigt** 2026-05-25: Homepage entfernt, Glance bleibt einziges Dashboard |
|
||||
| paperless-gpt — produktiv oder weg? | **entschieden** 2026-05-28: behalten bis Paperless-NGX 3.0 native KI-Features, dann neu bewerten |
|
||||
| BentoPDF — produktiv oder weg? | **entschieden** 2026-05-28: behalten als situatives Tool (~4 MB RAM-Footprint) |
|
||||
| Hermes-Agent als Spielerei, Review-Deadline gesetzt | **geparkt** mit Review-Deadline 2026-07-25 |
|
||||
| Speedtest-Tracker als "ich messe gerne" | unveraendert, keine Operator-Entscheidung getroffen |
|
||||
| code-server — sinnvoll oder weg? | unveraendert, keine Operator-Entscheidung getroffen |
|
||||
| Finanz-App (Firefly III / Actual Budget) als fehlender Mehrwert | offen, nice-to-have ohne aktiven Termin |
|
||||
| Familien-SSO ueber Authelia OIDC | **geparkt** im Auth-Block (F-13) |
|
||||
| Smartphone-Auto-Backup zu Immich | offen, Anwendungsentscheidung pro Familienmitglied |
|
||||
| Wandtablet im Flur mit Family-Dashboard | offen, Spielwiese |
|
||||
| Kalender/Aufgaben/CardDAV-Nutzung dokumentieren | offen, Operator-Frage |
|
||||
|
||||
### Block 3 - Best Practices
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Externer Repo-Mirror als DR-Voraussetzung offen | **erledigt**: GitHub-Push-Mirror `michaelkaleschke-spec/homelab-infra` aktiv |
|
||||
| Unraid USB-Flash-Backup offen | **erledigt** 2026-05-25: `unraid-flash-config.tar.gz` im Borg-Scope |
|
||||
| Komodo Self-Stack Drift Mai 2026 nur dokumentiert, nicht geloest | **teilweise erledigt** 2026-05-29/30: Trockenlauf-Skript + erfolgreicher Erstlauf belegen `ops/komodo/docker-compose.yml` als Recovery-Anker; Self-Stack-Entkopplung selbst bleibt offen |
|
||||
| Kein Fail2Ban/CrowdSec vor Traefik | **geparkt** im Auth-Block (F-14) |
|
||||
| Renovate Bot fehlt | **erledigt** 2026-05-29: live, erster Lauf erfolgreich, 5 PRs in Gitea |
|
||||
|
||||
### Block 4 - Nerd-Level
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Renovate Bot oder vergleichbares Update-Tracking | **erledigt** 2026-05-29 |
|
||||
| Staging-Path mit zweitem Komodo-Ziel | offen, Phase 3 nice-to-have |
|
||||
| OIDC-Provider statt nur ForwardAuth | **geparkt** im Auth-Block (F-13) |
|
||||
| Restore-Tests automatisiert in CI (Gitea Actions / Drone) | offen, Phase 3 |
|
||||
| End-to-End restore drill mit Test-Domain hinter Traefik | offen, bewusst nicht (Test-Lab bleibt ohne Domain) |
|
||||
| Disk1 NTFS -> XFS Phase 2 | **erledigt** (`ALLOW_DISK1_NTFS=0` als Default im posture-check, XFS-Erwartung aktiv) |
|
||||
| Loki-Retention und Log-Volume bewerten | offen, Detail-Sweep |
|
||||
| Hermes-Agent loswerden | **geparkt** mit Review 2026-07-25 |
|
||||
| Drei Dashboard-Tools auf eines reduzieren | **erledigt**: Glance bleibt als einziges |
|
||||
| Zwei Medienserver | **erledigt**: Jellyfin entfernt |
|
||||
|
||||
### Block 5 - Betrieb und Wartbarkeit
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Doppelter Monitoring-Stack als Wartbarkeits-Risiko | **erledigt** 2026-05-26 |
|
||||
| Authelia Repo-Baseline vs. Host-Config Drift "by design" | **erledigt** 2026-05-30 (F-10): `services/authelia-diff.sh` + Posture-Check ueberwacht ACL-Drift automatisch, WORKFLOW.md hat eigene Pflicht-Sektion |
|
||||
| Hermes-Agent verstaendnis-kritisch nach 6 Monaten | **geparkt** mit Review 2026-07-25 |
|
||||
|
||||
### Block 6 - Sicherheit und Zugriff
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| AdGuard Admin-Port 8082 LAN-direkt ohne Authelia | **erledigt** 2026-05-26: auf Tailscale-IP `100.80.98.33:8082` gebunden, LAN-Zugriff blockiert |
|
||||
| Nextcloud ohne ForwardAuth, Brute-Force-Doku offen | **geparkt** im Auth-Block (F-18) |
|
||||
| Authelia 2FA-Pflicht nicht klar dokumentiert | **geparkt** im Auth-Block (F-04) |
|
||||
|
||||
### Block 7 - Backup und Disaster Recovery
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Externer Backup-Mirror / zweites Off-Site-Ziel | **entschieden** 2026-05-28: kein zweites Off-Site; 3-2-1 mit Live + lokalem Borg + Hetzner + H:/-Nearline erfuellt; Hetzner-Haertungen als Folge-TODOs |
|
||||
| Externer Repo-Mirror | **erledigt**: GitHub-Push-Mirror aktiv |
|
||||
| Unraid USB-Flash-Backup | **erledigt** 2026-05-25 |
|
||||
| Borg-Passphrase analog gesichert | **erledigt** 2026-05-26: Operator bestaetigt, offline gesichert |
|
||||
| Komodo-Mongo Dump-Verifikation nach Major-Upgrades | offen, Watchpoint dokumentiert, nicht im automatischen Cron |
|
||||
| Restore-Tests Immich (groesster Datentopf ohne Mini-Restore) | **erledigt** 2026-05-27: erster Host-Lauf erfolgreich (`SUCCESS`, 11977 Assets) |
|
||||
|
||||
### Block 8 - Monitoring und Transparenz
|
||||
|
||||
| Originalbefund | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Doppelte Tools (Uptime-Kuma vs. Blackbox, Glance vs. Homepage) | **erledigt** 2026-05-25: Uptime-Kuma und Homepage entfernt |
|
||||
| Family-View Dashboard fehlt als Morgens-Check | **Spec da, JSON offen**: `docs/FAMILY_VIEW_DASHBOARD.md` definiert Layout/Queries/Thresholds; JSON wird gebaut, sobald Metriken 7+ Tage stabil sind |
|
||||
| Alert-Regeln explizit listen | **teilweise**: `monitoring/prometheus/alerts.yml` enthaelt Regeln (Borg-Stale, Cert-Expiry, Container-Down), `docs/ALERTING_MAP.md` mappt Sender — eine Doku-Zusammenfassung "welche Regel feuert wann" ist noch nicht zentralisiert |
|
||||
|
||||
### Block 9 - Konkreter Mehrwert-Fahrplan
|
||||
|
||||
#### Quick Wins (≤ 1 Woche)
|
||||
|
||||
| Original-Punkt | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Externer Push-Mirror GitHub privat | **erledigt** |
|
||||
| Borg-Passphrase analog sichern | **erledigt** 2026-05-26 |
|
||||
| Plex oder Jellyfin entscheiden | **erledigt** 2026-05-25: Jellyfin weg |
|
||||
| Glance oder Homepage waehlen | **erledigt** 2026-05-25: Homepage weg |
|
||||
| Authelia 2FA-Pflicht aktivieren | **geparkt** (F-04) |
|
||||
| Disk1 NTFS -> XFS Phase 2 | **erledigt** |
|
||||
| AdGuard Admin Tailscale-only | **erledigt** 2026-05-26 |
|
||||
|
||||
#### Phase 1 (2-4 Wochen)
|
||||
|
||||
| Original-Punkt | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Monitoring-Migration abschliessen, Altstaende entfernen | **erledigt** 2026-05-26 |
|
||||
| Uptime-Kuma abloesen durch Blackbox + Grafana | **erledigt** 2026-05-25 |
|
||||
| Hermes-Agent Entscheidung | **geparkt** mit Review 2026-07-25 |
|
||||
| paperless-gpt / BentoPDF Entscheidung | **entschieden** 2026-05-28: beide behalten mit Begruendung |
|
||||
| Unraid USB-Flash-Backup | **erledigt** 2026-05-25 |
|
||||
| Family-View-Dashboard | Spec da, JSON wartet |
|
||||
|
||||
#### Phase 2 (4-12 Wochen)
|
||||
|
||||
| Original-Punkt | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Authelia OIDC fuer Nextcloud/Immich/Grafana | **geparkt** (F-13) |
|
||||
| Renovate Bot gegen Gitea | **erledigt** 2026-05-29 |
|
||||
| Restore-Test fuer Immich | **erledigt** 2026-05-27 |
|
||||
| Familien-Smartphone-Auto-Backup zu Immich | offen, Operator-Anwendungsentscheidung |
|
||||
| CrowdSec vor Traefik | **geparkt** (F-14) |
|
||||
|
||||
#### Phase 3 (3-6 Monate)
|
||||
|
||||
| Original-Punkt | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Staging-Branch + zweites Komodo-Ziel | offen |
|
||||
| Restore-Test-Automatisierung als CI | offen |
|
||||
| Off-Site-Backup zu zweitem Ziel | **entschieden** 2026-05-28: bewusst nicht |
|
||||
| Cold-Standby-Konzept dokumentieren | offen |
|
||||
| Komodo-Self-Stack rausnehmen | teilweise erledigt: Bootstrap-Anker und Trockenlauf-Skript da, Entkopplung selbst noch nicht |
|
||||
|
||||
#### Phase 4 (Spielwiese)
|
||||
|
||||
| Original-Punkt | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| Firefly III / Actual Budget | offen |
|
||||
| Wandtablet mit Family-Dashboard | offen |
|
||||
| Home Assistant + ntfy enger verzahnen | offen |
|
||||
| Ecowitt-Wetter-Dashboard | offen |
|
||||
|
||||
### Top-5-Listen vom 2026-05-23
|
||||
|
||||
#### Top 5 sofort verbessern
|
||||
|
||||
| Original-Top-5 | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| 1. Externer Repo-Mirror | **erledigt** |
|
||||
| 2. Borg-Passphrase analog sichern | **erledigt** |
|
||||
| 3. Plex oder Jellyfin entscheiden | **erledigt** |
|
||||
| 4. Glance oder Homepage waehlen | **erledigt** |
|
||||
| 5. AdGuard Admin-Port haerten | **erledigt** |
|
||||
|
||||
**Alle 5 erledigt.**
|
||||
|
||||
#### Top 5 mit groesstem zusaetzlichen Mehrwert
|
||||
|
||||
| Original-Top-5 | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| 1. Smartphone-Auto-Backup zu Immich | offen, Anwendungsentscheidung |
|
||||
| 2. Authelia OIDC fuer SSO | **geparkt** |
|
||||
| 3. Renovate Bot gegen Gitea | **erledigt** |
|
||||
| 4. Family-View-Dashboard | Spec da, JSON wartet |
|
||||
| 5. Finanz-App | offen |
|
||||
|
||||
#### Top 5 lieber NICHT machen
|
||||
|
||||
| Original-Anti-Top-5 | Stand 2026-05-30 |
|
||||
|---|---|
|
||||
| 1. Hermes-Agent ausbauen statt loswerden | gehalten — Agent geparkt mit Review, nicht ausgebaut |
|
||||
| 2. Noch mehr Dashboards einbauen | gehalten — Homepage entfernt, Glance bleibt einziges |
|
||||
| 3. Pauschale Authelia vor Komodo | gehalten — Komodo bleibt ohne ForwardAuth |
|
||||
| 4. backend_net auf external statt internal | gehalten — backend_net bleibt internal |
|
||||
| 5. Komodo Self-Stack komplett via Komodo | teilweise gehalten — Trockenlauf-Skript als Gegenmaszahme, vollstaendige Entkopplung offen |
|
||||
|
||||
### Zusammenfassung des Status-Anhangs
|
||||
|
||||
- **Top 5 sofort**: 5/5 erledigt.
|
||||
- **Quick Wins (7)**: 6 erledigt, 1 geparkt.
|
||||
- **Phase 1 (6)**: 4 erledigt, 1 geparkt, 1 wartend.
|
||||
- **Phase 2 (5)**: 2 erledigt, 2 geparkt, 1 offen.
|
||||
- **Phase 3 (5)**: 1 entschieden (nicht umgesetzt), 1 teilweise, 3 offen.
|
||||
- **Phase 4 (Spielwiese)**: alle offen, bewusst niedrige Prioritaet.
|
||||
- **Auth-Block (F-04/13/14/18)**: vollstaendig geparkt nach Operator-Entscheidung 2026-05-26, gebuendelte Bearbeitung ausserhalb des aktuellen Zyklus.
|
||||
|
||||
Wer hier weiterarbeiten will, schaut auf `docs/AUDIT_2026-05-25_TODO.md` — dort ist der operative Stand gepflegt.
|
||||
Reference in New Issue
Block a user