57 KiB
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/AUDIT_2026-05-23_LIVE.md, wo verfuegbar.
Auftrag: externer, kritischer Audit-Blick zusaetzlich zur internen docs/STRATEGISCHE_BEWERTUNG_2026-05-23.md.
Wichtige Vorbemerkung
Es gibt seit dem 23.05. eine fundierte interne Bewertung (docs/STRATEGISCHE_BEWERTUNG_2026-05-23.md) und eine konsolidierte Hausaufgabenliste (docs/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.gzim Borg-Lauf) - GitHub-Push-Mirror
michaelkaleschke-spec/homelab-infraaktiv (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— komplettdocs/WORKFLOW.md,docs/REPO_MAP.md,docs/SERVICE_CATALOG.md— komplettdocs/DISASTER_RECOVERY.md,docs/RESTORE_MATRIX.md,docs/SECRETS_MAP.md— komplettdocs/STORAGE_LAYOUT.md(zum Audit-Zeitpunktdocs/STORAGE_LAYOUT.draft.md),docs/STRATEGISCHE_BEWERTUNG_2026-05-23.md— komplettdocs/AUDIT_2026-05-23_LIVE.md,docs/AUDIT_2026-05-23_FINAL.mdops/policy-checks/last-report.mdmonitoring/docker-compose.yml,monitoring/prometheus/alerts.ymltraefik/docker-compose.yml,traefik/dynamic/middlewares.ymlsecurity/authelia/configuration.yml,security/authelia/docker-compose.ymlapps/paperless/docker-compose.yml,apps/immich/docker-compose.yml,apps/nextcloud/docker-compose.ymlhost-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.ps1mit 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.infoundscrutiny.kaleschke.info(security/authelia/configuration.yml:44-48). Borg-UI, Code-Server, Filebrowser, Glance — alles nurone_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.yamlneu erzeugen — dafuer brauchst du die.envmitKOMODO_*-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/redisist 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:
- AdGuard-Admin-Port nur auf Tailscale-Interface binden (5 Min, Compose-Edit).
- Borg-Passphrase auf Papier in Bankschliessfach (15 Min, off-system).
scrutinyundddns-updaterno-new-privilegesWarning aufraeumen (10 Min) — kosmetisch, aber Policy-Check sollte clean sein.- Altstaende
ops/grafana-influxdb/undops/loki/aus Repo entfernen (Backup-Branch danngit rm). - 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:80direkt 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_factoroder 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 :8082zeigt 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.txtliegt 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 listgegen 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.infoundscrutiny.kaleschke.infosindtwo_factor. Tier-1-Operator-UIs wie Borg-UI, Code-Server, Filebrowser (zweite Route?), Komodo (eigene Auth), Glance, Grafana laufen mitone_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_factorfuerborg.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.infowird 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 rmder beiden Verzeichnisse, Tagpre-monitoring-cleanupfuer Rollback, MIGRATION_LOG-Eintrag. - Prioritaet: Sollte zeitnah
- Aufwand: S
- Validierung:
policy-checkslaeuft clean, Repo enthaelt nur nochmonitoring/.
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.infomit 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, ...). Nurinfluxdb3-corehat@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.ymllistet 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_exportertextfile 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.
- Borg-Lauf-Frische (ueber
- 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) undTLSCertExpiryNear(<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_PASSKEYetc., 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 inservices/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, dasdiffzwischen 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 derimmich.dumpund 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 indocs/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.infowird 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 hathealthcheck:-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, PostgreSQLpg_isready, Komodowget /api/healthcheck) Healthchecks ergaenzen. Fuer Tier-2 schrittweise. - Prioritaet: Sollte zeitnah
- Aufwand: M (pro Stack 5–15 Min)
- Validierung:
docker pszeigt(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/redisfuer 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 AccessUI 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.mdmit 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 inservices/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:oderdeploy.resources.limitsSektion 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 statszeigtMEM USAGE / LIMITungleichunlimited.
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
_FILEnicht 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.gzfuer 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
onlyfuerappdata,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.mdundSTORAGE_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-baselineaufmastersetzen 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.mdEintrag "Audit-Sprint-Start".
- Git-Tag
- Erfolgskriterium: Tag pushed, Borg-Lauf gruen, Mongo-Dump verifiziert.
- Validierung:
git fetch && git tag | grep audit-2026-05-25-baselineundls /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):
- F-02 Borg-Passphrase analog sichern (off-system, kein Code-Change).
- F-01 AdGuard-Admin-Port auf Tailscale-IP — Edit
host-services/Adguard/docker-compose.yml:16. - F-04 Authelia ACL erweitern (
two_factorfuer borg, code, files, traefik) — Editsecurity/authelia/configuration.yml+ Host-Sync. - F-05 Altstaende
ops/grafana-influxdb/,ops/loki/entfernen —git rm, MIGRATION_LOG. - 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:
- F-09 Komodo-Bootstrap-Compose nach
services/komodo-bootstrap/extrahieren + dokumentierter Standalone-Restore-Pfad. - F-10 Authelia-Drift-Diff in posture-check ergaenzen.
- F-11 Immich-Restore-Test einrichten (analog zu vaultwarden/gitea/paperless).
- F-06 Hermes-Entscheidung mit 60-Tage-Deadline schriftlich.
- F-09 Komodo-Bootstrap-Compose nach
- 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 -dausservices/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:
- F-03 Zweitziel: Wechselplatten-Rotation dokumentieren ODER zweites Borg-Repo (rsync.net / BorgBase EU2).
- F-20 Stack-ENV-Liste in DR-Doc explizit machen (Restore-Reihenfolge).
- Borg-Verifikation Cron fuer
borg check --repository-onlyweekly (STORAGE_LAYOUT 8.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 listgegen beide Repos.
Sprint 4 — Monitoring & Alerting ausbauen (2 Wochen)
- Ziel: Sichtbarkeit auf das, was wirklich weh tut.
- Aufgaben:
- F-08 Alert-Regeln:
BorgArchiveStale,TLSCertExpiryNear,ContainerDown,PostgresConnSaturation. - F-15 Healthchecks fuer Traefik, Authelia, Postgres, Komodo, Gitea.
- F-07 Digest-Pin in
monitoring/docker-compose.yml. - Family-View-Dashboard in Grafana (1 Panel: Service-Up, 1 Panel: Backup-Frische, 1 Panel: Cert-Tage, 1 Panel: Disk-Fuellung).
- F-08 Alert-Regeln:
- 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:
- F-13 Authelia OIDC-Provider aktivieren.
- Nextcloud OIDC-Plugin + Test-Login.
- Immich OIDC + Test-Login.
- Grafana OIDC + Test-Login.
- F-14 CrowdSec-Bouncer vor Traefik.
- 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:
- F-12 Renovate-Bot gegen Gitea.
- F-19 Mem-Limits Tier-1.
- Restore-Test-CI via Gitea Actions (P3).
- Optional: Staging-Branch + zweites Komodo-Ziel in Tailscale-VM (P3).
- 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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)
# 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.mdPhase 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.ymlversioniert. - 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.mdist 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/redisist 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.