# Backupstrategie Draft — K3s DMZ + Synology NAS

## Ausgangslage

- K3s Cluster steht in der DMZ.
- Synology NAS steht im Intranet.
- Neuer Hilfs-Backup-Server in der DMZ: `dmz-backup` (`192.168.20.90`).
- NAS kann aktiv auf Rechner in der DMZ zugreifen.
- diskstation-bot ist zuständig für Synology/NAS.
- kube-bot ist zuständig für K3s/DMZ/Cluster.
- Ziel: belastbare Backupstrategie vor Longhorn-Reparatur/Replica-Umstellung.

## Grundprinzip

Backups sollten bevorzugt vom Intranet/NAS aus *pull-basiert* aus der DMZ geholt werden, statt der DMZ Schreibzugriff ins Intranet zu geben.

Konkret neu:
- Cluster pusht Backup-Dateien nach `dmz-backup` (`192.168.20.90`).
- Synology pullt von `dmz-backup`.
- `dmz-backup` ist Staging/Puffer in der DMZ, Synology bleibt Backup-Master.

Vorteile:
- DMZ bekommt keine breiten Credentials ins Intranet.
- NAS kontrolliert Zeitplan, Retention und Zielpfade.
- Kompromittierter DMZ-Service kann Backups nicht ohne Weiteres löschen.

## Backup-Ebenen

## Ordnerstruktur auf dmz-backup / Synology

Empfehlung: Struktur nach Platform/Tenants uebernehmen, aber Kubernetes-Namespace nur als Metadatum fuehren.

Grund:
- Fachliche Restore-Entscheidungen laufen nach Platform/Tenant/App.
- Einige Live-Namespaces sind historisch gewachsen (`hf-*`, `pidoka-hf-*`, `homarr`, `zammad`).
- Synology-Retention und Restore-Tests lassen sich pro Tenant/App sauberer steuern.

Staging-Root auf `dmz-backup`:

```text
/srv/dmz-backup/k3s-dmz/
```

Synology-Pull-Ziel sinngemaess:

```text
K3S_DMZ_Backups/
```

Kurzschema:

```text
k3s-dmz/
  platform/
    argocd/prod/
    infisical/prod/
    external-secrets/prod/
    longhorn/prod/
    nginx-proxy-manager/prod/
    cluster/prod/
  tenants/
    pidoka/prod/<app>/
    cattaro/stage/<app>/
    cattaro/prod/<app>/
  legacy/
    <legacy-service>/prod/
  _indexes/
  _restore-tests/
```

Detailentwurf:
- `/home/node/.openclaw/workspace/inventory/backup-folder-structure-dmz-backup-20260619.md`

### Ebene 1 — Konfiguration / Wiederaufbau

Zu sichern:
- Nginx Proxy Manager Datenbank und LetsEncrypt-Verzeichnis vom Raspberry Pi
  - Container: `ngm2-app-1`
  - Daten: `/data/compose/2/data`
  - Zertifikate: `/data/compose/2/letsencrypt`
- Kubernetes Inventar/Manifeste ohne Secrets
- ArgoCD Git Repo / Application Struktur
- ggf. OPNsense Export separat über zuständigen Admin

Ziel:
- Schnelle Rekonstruktion von Proxy, Routing und GitOps-Zustand.

### Ebene 2 — Applikationsdaten / Datenbanken

Priorität:
1. `hf-espocrm` MariaDB
2. `hf-suitecrm` MariaDB
3. `hf-mautic` MariaDB + Redis falls relevant
4. `hf-n8n` Daten/DB
5. `hf-matomo` DB + App-Daten

Empfehlung:
- Logische Dumps pro DB, weil sie einfacher testbar und portabel sind.
- Dumps temporär auf Cluster/Node erzeugen oder direkt per Stream ans NAS ziehen.
- Secrets nicht in Slack teilen; Zugang über Kubernetes Secrets nur gezielt und lokal auslesen, falls Mislav OK gibt.

### Ebene 3 — Volume Backups / Longhorn

Aktueller Longhorn-Status:
- 12 Volumes sichtbar
- 11 `attached/degraded`
- 1 `detached/unknown`
- `default-replica-count=3`, aber nur 2 Nodes
- Longhorn Backup Target aktuell leer/nicht verfügbar

Optionen:

A) Synology als NFS Backup Target für Longhorn
- NAS stellt NFS Share bereit.
- K3s Nodes mounten bzw. Longhorn nutzt NFS Backup Target.
- Einfach, lokal schnell.
- Risiko: DMZ braucht Netzwerkzugriff zum NAS-Share.

B) Synology als S3-kompatibles Ziel via MinIO auf NAS
- MinIO läuft auf Synology oder Umgebung im Intranet.
- Longhorn nutzt S3 Backup Target.
- Bessere Credential-/Bucket-Trennung und Lifecycle möglich.
- Etwas mehr Setup-Aufwand.

C) NAS pullt Dateisystem-/DB-Backups aus DMZ
- Für DB-Dumps und Proxy-Konfig sehr gut.
- Für Longhorn-native Backups weniger passend.

Empfehlung:
- Kurzfristig: NAS pullt NPM-Konfig + DB-Dumps.
- Für Longhorn nicht direkt auf DiskStation-NFS/S3 setzen, wenn DMZ -> NAS bewusst gesperrt ist. Longhorn braucht ein vom Cluster erreichbares Backup Target.
- Angepasste Phase 1: DMZ-lokales Longhorn Backup Target bereitstellen (NFS oder MinIO/S3), Longhorn schreibt dorthin, Synology pullt anschließend per SSH/rsync in ein dediziertes Share `Backup_K3s_Longhorn`.
- Direkter NAS-NFS-Export nur weiterverfolgen, wenn Mislav die Firewall-Regel DMZ -> NAS explizit erlauben will; aktuell nicht empfohlen.

## Retention-Vorschlag

Für produktive Business-Services:
- Täglich: 14 Tage
- Wöchentlich: 8 Wochen
- Monatlich: 6–12 Monate
- Vor Wartung/Longhorn-Änderungen: manuelles Pre-Change Backup

## Security-Vorschlag

- Dedizierter NAS-Backup-User/Key für Pull-Zugriff.
- Nur read-only/pull wo möglich.
- Für Backup-Ziel getrennte Credentials, keine Admin-Credentials.
- Backups möglichst versioniert/immutable oder mit Snapshot-Schutz auf Synology.
- Restore-Test einplanen, nicht nur Backup-Erfolg prüfen.

## Offene Fragen an diskstation-bot

1. Welche Synology Backup-Technologien sind verfügbar/eingerichtet?
   - Hyper Backup?
   - Active Backup?
   - Snapshot Replication?
   - NFS Shares?
   - Docker/Container Manager für MinIO?
2. Gibt es bereits ein dediziertes Backup-Volume/Share?
3. Kann das NAS aus dem Intranet per SSH/NFS/S3 auf DMZ-Ziele zugreifen?
4. Soll Longhorn über NFS oder S3/MinIO angebunden werden?
5. Welche Retention/Quota ist realistisch?
6. Können Synology Snapshots/Immutability für Backup-Schutz genutzt werden?

## Nächste Schritte

1. diskstation-bot prüft NAS-Fähigkeiten und schlägt Zielpfad/Zieltechnologie vor.
2. kube-bot liefert Liste der zu sichernden DMZ-Quellen und Kubernetes-PVCs.
3. Mislav entscheidet: NFS vs. S3/MinIO für Longhorn.
4. Erst danach Longhorn Backup Target einrichten.
5. Danach DB-Dumps/Proxy-Backups automatisieren.
6. Erst nach validiertem Backup: Longhorn Replica-Count/StorageClass korrigieren.

## K3s-Anforderungen an neue DMZ-Backup-Strecke (2026-06-20)

Abgleich mit diskstation-bot-Konzept:

- Zielstrecke ist aus Cluster-Sicht stimmig: K3s/DMZ pusht nach `dmz-backup` (`192.168.20.90`), Synology pullt von dort und bleibt Langzeit-Backup-Master.
- `dmz-backup` ist nur Staging/Puffer, nicht finales Backup.
- Keine direkten Schreibrechte aus DMZ/K3s auf die Synology.
- Initial keine destruktive Retention und kein `--delete`; Pruning erst nach Restore-Test und expliziter Freigabe.
- Backups mit Secret-, Credential-, Datenbank- oder personenbezogenem Inhalt werden vor Ablage auf `dmz-backup` clientseitig verschlüsselt. `dmz-backup` darf keine dauerhaften Passphrases oder Private Keys halten. Keine Secretwerte in Metadaten, Logs oder Slack.

Prioritäten:

1. Zustandsbehaftete Workloads/PVCs und Datenbanken.
2. Plattform-Komponenten und Cluster-/GitOps-Konfiguration.
3. Stateless Workloads, soweit sie nicht vollständig aus GitOps rekonstruierbar sind.

Gewünschte Artefakte je Backup-Satz:

- `metadata.json`
- `manifest.sha256`
- `status.json`
- `restore-notes.md`
- optional `k8s-resources.yaml` ohne Klartext-Secrets
- optional `volume-backup-ref.txt` für Longhorn-native Backup-Referenzen
- optional `app-dump/` für applikationsspezifische Dumps, z. B. Datenbank-Dumps

Minimale k3s-Metadaten:

- Cluster, Namespace, Tenant/Platform, App/Release und Environment.
- PVC/PV, StorageClass, Longhorn Volume-Name und Backup-/Snapshot-Zeitpunkt.
- Image-/Chart-/Git-Revision, soweit vorhanden.
- Backup-Art, Restore-Ziel, Prüfschritte und Restore-Test-Status.
- Verschlüsselungsstatus, Key-/Secret-Referenz und Fingerprint nur ohne Secretwerte.

Longhorn-Anforderungen:

- Klare Zuordnung `PVC -> Longhorn Volume -> Backup-Artefakt`.
- Restore immer zuerst in neue Test-PVCs, nie über produktive PVCs.
- Retention/Delete erst nach mindestens einem erfolgreichen Restore-Test je Backup-Klasse.
- Zielarchitektur soll auf `dmz-backup` umgestellt werden; bisherige Staging-Altlast `192.168.20.40` bleibt als technische Schuld markiert.

Restore-Test aus Cluster-Sicht:

1. Synology stellt eine Kopie in Restore-Staging bereit.
2. Kube-Seite nutzt nur freigegebene Artefakte/Referenzen; keine produktiven Secrets im Klartext.
3. Restore in separaten Namespace, z. B. `restore-test-*`, mit neuen PVCs.
4. App startet isoliert ohne produktiven Ingress/Traffic.
5. Prüfung: Pods ready, Daten sichtbar/konsistent, Logs ohne kritische Fehler, Checksummen/Manifest passen.
6. Ergebnis wird in `_restore-tests/` und in kube-bot-Doku protokolliert.

Empfehlung:

- Pilot mit unkritischem, aber zustandsbehaftetem Workload mit kleinem PVC starten.
- Erst danach Datenbanken oder tenant-kritische Volumes einbeziehen.
- Für echte Backup-Jobs, Longhorn-Zielkonfiguration, Credential-Anlage oder Restore-Ausführung ist explizites OK von Mislav erforderlich.

## Pilot-Scope `platform/cluster/prod` — Control-Plane-Konfiguration (2026-06-20)

Mislav moechte den ersten Pilot im Bereich "cluster control-plane" ansetzen. Kube-bot-Einordnung:

- Als erster Pilot akzeptabel, wenn es ein Backup-Strecken-Pilot fuer rekonstruierbare Plattform-/Cluster-Konfiguration bleibt.
- Kein produktiver Control-Plane-Restore, kein etcd-Restore, keine Longhorn-Setting-Aenderungen und kein Ueberschreiben produktiver PVCs.
- Ablauf: read-only Export, clientseitige Verschluesselung vor `dmz-backup`, Synology Pull ohne `--delete`, Restore-Pruefung nur in Staging/Parser/Doku.
- Zielpfad: `k3s-dmz/platform/cluster/prod/`.
- Restore-Test-Ebene: Artefakt-, Manifest- und Checksum-Pruefung aus Synology-Staging; kein Restore in die produktive Control Plane.

In Scope:

- Namespace-/Node-/StorageClass-/PVC-/PV-Inventar.
- ArgoCD Applications/AppProjects/Cluster-Zielmetadaten ohne Secretwerte.
- Longhorn Volume-/BackupTarget-/Storage-Metadaten ohne Secretwerte.
- Relevante CRD-/Controller-Uebersichten, z. B. External Secrets, Longhorn und Ingress.
- Events/Status-Snapshots als Diagnosekontext.
- Restore-Runbook und Pruefliste.

Out of Scope fuer diesen Pilot:

- Produktiver Control-Plane-Restore.
- etcd-Restore.
- Secrets im Klartext.
- PVC-Ueberschreiben.
- Neue Restore-Ressourcen im produktiven Cluster.
- Retention/Delete/Pruning.

## Homarr App-Pilot — Phase 1 verifiziert gepusht (2026-06-20)

Mislav hat Homarr als banaleren ersten App-Pilot bevorzugt. Kube-bot-Einordnung:

- Homarr ist geeignet, weil die App klein, GitOps-managed und zustandsbehaftet ist.
- Zielpfad: `k3s-dmz/tenants/pidoka/prod/homarr/`.
- Phase 1 bleibt ein Backup-Strecken-/Artefakt-Pilot ohne produktiven Restore.
- Keine Secretwerte und keine PVC-Dateiinhalte im ersten Paket.

Vorbereitetes lokales Paket:

- Arbeitsverzeichnis: `/home/node/.openclaw/workspace/backups/homarr-pilot-20260620T104142Z`.
- Archiv: `/home/node/.openclaw/workspace/backups/20260620T104142Z__dmz-k3s__pidoka__homarr__metadata__pilot.tar.gz`.
- SHA256: `64802165be001fd7c5dab1a59bf0f97934ce47aa31863fcf0c622d0bfa66db87`.
- Verschluesseltes Artefakt: `/home/node/.openclaw/workspace/backups/20260620T104142Z__dmz-k3s__pidoka__homarr__metadata__pilot.tar.gz.age`.
- Verschluesseltes Artefakt SHA256: `b90154a732f756a10de218f30d28fa9afd8bd15644781aa207011188ca4a5f19`.

Enthalten:

- Live-Summary fuer Namespace `homarr`.
- Deployment/Service/PVC-Manifeste.
- PV-Metadaten fuer aktive PVCs.
- Longhorn-Metadaten fuer `my-homarr-config` und `my-homarr-icons`.
- GitOps-Artefakte fuer `pidoka-hf-homarr`.
- Reduzierte Secret-Metadaten ohne Werte.
- `metadata.json`, `status.json`, `restore-notes.md`, `checksums/manifest.sha256`.

Aktueller Live-Stand beim Export:

- Deployment `my-homarr`: `1/1`.
- Pod `my-homarr-698bc75847-nsfph`: `Running`, Restarts `0`.
- Aktive PVCs:
  - `my-homarr-data`: `local-path`, `100Gi`.
  - `my-homarr-icons`: Longhorn, `10Gi`, Volume `healthy`.
  - `my-homarr-config`: Longhorn, `10Gi`, Volume `healthy`.
- Secret `my-homarr-homarr-secrets` wurde nur als Referenz/Metadatum dokumentiert; kein Secretwert exportiert.

Nicht durchgefuehrt:

- Keine Verschluesselung mit improvisierter Passphrase.
- Keine Secretwerte exportiert.
- Keine PVC-Dateiinhalte exportiert.
- Keine Longhorn Snapshots/Backups erstellt.
- Keine Cluster-Aenderungen.

Durchgefuehrt/verifiziert:

- `age` v1.3.1 verwendet: `/home/node/shared/tools/age`.
- Infisical `Backup_Restore/prod` enthaelt die benoetigten Secret-Referenzen `BACKUP_HOMARR_AGE_RECIPIENT`, `BACKUP_HOMARR_AGE_PRIVATE_KEY` sowie die `DMZ_BACKUP_*` SSH-/Zielwerte.
- Lokale Decrypt-Probe gegen Original-SHA erfolgreich.
- `dmz-backup` ED25519 Host-Key-Fingerprint gegen Infisical verifiziert.
- Remote-Datei vorhanden: `/srv/dmz-backup/k3s-dmz/tenants/pidoka/prod/homarr/20260620T104142Z__dmz-k3s__pidoka__homarr__metadata__pilot.tar.gz.age`.
- Remote-SHA256 stimmt mit lokalem verschluesseltem Artefakt ueberein: `b90154a732f756a10de218f30d28fa9afd8bd15644781aa207011188ca4a5f19`.
- `dmz-backup` erhaelt keinen dauerhaften Age-Private-Key.

Naechster Schritt:

- Synology/diskstation-bot soll das `.age`-Artefakt von `dmz-backup` pullen und danach einen Staging-Restore-Test nur als Decrypt-/Checksum-/Manifest-Pruefung fahren. Kein produktiver Restore und kein PVC-Ueberschreiben.
- Stand 2026-06-20 18:02 UTC: Synology-Pull ist noch nicht erfolgt, weil der Zielshare `Backup_K3S_DMZ` fehlt. Share-Anlage via DSM API `SYNO.Core.Share create` liefert fuer diskstation-bot `403`, SSH zur Synology scheitert mit `Permission denied`. Benoetigt wird manuelle Share-Anlage oder passende diskstation-bot Rechte; bis dahin bleibt das verifizierte `.age`-Artefakt auf `dmz-backup`.

## Restic/Kopia Einordnung fuer Homarr und spaetere App-Backups (2026-06-20)

Mislav fragte, ob Restic oder Kopia auf `dmz-backup` helfen wuerden.

Kube-bot-Einordnung:

- Fuer Homarr Phase 1, also Metadaten/Manifeste/Checksums, ist Restic/Kopia noch nicht noetig.
- `dmz-backup` soll weiterhin nur Staging/Fileablage bleiben; dort sollen keine dauerhaften Keys, Passphrases oder aktive Backup-Logik liegen.
- Fuer echte Datei-/App-/DB-Dump-Backups kann Restic spaeter sinnvoll sein: verschluesselt, dedupliziert, inkrementell und gut pruefbar.
- Kopia ist ebenfalls geeignet, bringt aber mehr Policy-/UI-/Konzeptoberflaeche und ist fuer den ersten kleinen Pilot nicht noetig.
- Wenn Restic eingesetzt wird, dann quellsseitig oder in einem spaeter freigegebenen K3s Job/CronJob; Repository-Ziel kann ein Ordner/SFTP auf `dmz-backup` sein.
- Restic-Passphrase bzw. Recipient/Key-Referenz gehoert nach Infisical `Backup_Restore`, nicht nach Slack, lokale Metadaten oder `dmz-backup`.

Empfehlung:

- Phase 1 weiter simpel halten: SSH/SFTP + clientseitig verschluesseltes Artefakt.
- Restic als naechsten Kandidaten fuer echte Homarr-Datei-/PVC- oder DB-Dump-Backups evaluieren.
- Kopia/MinIO/S3 erst separat entscheiden, wenn Longhorn oder eine spaetere Backup-Policy das wirklich braucht.

## Homarr Backup-/Restore-Pilot Retro — 2026-06-21

Ergebnis:

- Backup-Transport K3s/DMZ -> `dmz-backup` -> DiskStation: verifiziert.
- Restore-Transport DiskStation -> `dmz-backup` -> kube-bot/K3s-Kontext: verifiziert.
- Decrypt mit Age-Key aus Infisical `Backup_Restore/prod`: verifiziert.
- Archiv-/Checksum-Pruefung: verifiziert.
- Kubernetes Server-Dry-Run fuer normale K8s-Objekte: verifiziert.
- Keine produktive Aenderung und kein produktiver Restore.

Wichtige Grenze:

- Das Homarr-Pilotartefakt ist nur `metadata-manifest-pilot`.
- Es enthaelt keine Secretwerte, keine PVC-Dateiinhalte und keine Longhorn-Backupdaten.
- Longhorn Live-CR-Dumps sind als Metadaten nuetzlich, aber nicht direkt apply-faehige Restore-Manifeste.

Folgeentscheidung:

- Ein echter Homarr-Restore-Test braucht ein vollwertiges Restore-Artefakt:
  - PVC-/Datei-Payload oder
  - DB-/App-Export oder
  - Longhorn-Backup-Referenz plus bereinigte Restore-Manifeste.
- Restore zuerst in isoliertem Namespace/PVC; produktive Restores bleiben zustimmungspflichtig.

Ergaenzende Bewertung je Artefakttyp:

- Siehe `/home/node/.openclaw/workspace/inventory/backup-restore-artifact-classes-20260621.md`.

## DMZ-Staging Host Kandidaten (read-only geprüft)

- `192.168.20.40` / `mbrkanov-Mini-IT13`: Ubuntu 22.04, ca. 1.3T frei auf `/`, `rsync` und `nfs-common` vorhanden, SSH offen. Kein `nfs-kernel-server` sichtbar. Beste Kapazität, aber Control-Plane/Master.
- `192.168.20.45` / `mini-it13-02`: Ubuntu 22.04, ca. 686G frei auf `/`, `rsync` und `nfs-common` vorhanden, SSH offen. Kein `nfs-kernel-server` sichtbar. Worker, aber weniger Kapazität.
- `192.168.20.20` / Raspberry Pi Reverse Proxy: ca. 22G frei; wegen SD-Karte/Proxy-Rolle nicht als Longhorn-Staging geeignet.

Empfehlung aktualisiert 2026-06-19: Der neue dedizierte DMZ-Backuphost `dmz-backup` (`192.168.20.90`) ersetzt die bisherige Zielarchitektur "Control-Plane als Staging". `192.168.20.40` bleibt nur historische/technische Übergangslösung und sollte abgeloest werden.

## Technical Debt — Longhorn Backup Staging Option B (2026-06-08 22:35 UTC)

Decision by Mislav: Start with Option B for Longhorn backup staging.

Option B means using existing DMZ host `192.168.20.40` (`mbrkanov-Mini-IT13`, K3s control-plane) as a temporary Longhorn backup staging target because it has the most available local capacity.

This is explicitly technical debt, not target architecture. Risks:
- backup staging on control-plane host
- risk of filling `/` or impacting K3s control-plane if not hard-limited
- no dedicated backup host/datastore yet

Mandatory safeguards before/while implementing:
- separate staging path, e.g. `/srv/longhorn-backup-staging`
- hard quota or separate filesystem/mount; no unbounded writes to `/`
- monitoring/alerting for capacity
- conservative retention
- Synology rsync pull initially without `--delete`
- do not use `/var/lib/longhorn` as staging path

Target architecture to retire this debt:
- dedicated DMZ backup disk/host for Longhorn staging, then Synology pulls from there
- Neuer Zielhost dafuer: `dmz-backup` (`192.168.20.90`)

## Longhorn Backup Staging Option B — Implemented (2026-06-08 23:00 UTC)

Implemented temporary technical-debt staging on `192.168.20.40` (`mbrkanov-Mini-IT13`).

Current state:
- Staging image: `/srv/longhorn-backup-staging.img`, size `300G`
- Mount: `/srv/longhorn-backup-staging`, ext4 loopback, about `280G` usable
- NFS export restricted to `192.168.20.40`, `192.168.20.45`, and K3s pod CIDR `10.42.0.0/16` because Longhorn manager mounts from pod context
- Longhorn BackupTarget/default: `nfs://192.168.20.40:/srv/longhorn-backup-staging`
- Verified status: `available=true`
- `fs.inotify.max_user_instances` raised from `128` to `1024` via `/etc/sysctl.d/99-kube-bot-longhorn-staging.conf` because `nfs-mountd` failed with `Too many open files`

Debt/risk notes:
- Backup staging is on the control-plane host and must remain temporary.
- Capacity is hard-limited by the loopback image, but monitoring/retention are still required.
- NAS pull target `Backup_K3s_Longhorn` is handled by diskstation-bot / DSM side.

Next steps:
- Create a first Longhorn test backup once an appropriate test volume is selected.
- Plan replacement by `dmz-backup` (`192.168.20.90`).
- Configure Synology pull from `dmz-backup` without `--delete` initially.
- Migrate/retire temporary control-plane staging after successful test backup and restore.
