# 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 `@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-.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 \ | openssl x509 -noout -dates 2>/dev/null done ``` ### GitOps-Konsistenz ```bash # Komodo Stack-Workspace vs. Repo cd /mnt/user/services/stacks/ 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//` 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.