From c031f2be6457662448ef9cbee239c484d8166287 Mon Sep 17 00:00:00 2001 From: Christoph Emsenhuber Date: Wed, 26 Aug 2026 17:51:07 +0200 Subject: [PATCH] =?UTF-8?q?handoff:=202026-08-26=20=E2=80=94=20AdGuard=20D?= =?UTF-8?q?NS-Cutover=20fortsetzen=20(TP23/TP31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/handoff-20260826-agh-dns-cutover.md | 87 ++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs/handoff-20260826-agh-dns-cutover.md diff --git a/docs/handoff-20260826-agh-dns-cutover.md b/docs/handoff-20260826-agh-dns-cutover.md new file mode 100644 index 0000000..946eb55 --- /dev/null +++ b/docs/handoff-20260826-agh-dns-cutover.md @@ -0,0 +1,87 @@ +# Übergabe — nächste Session: AdGuard DNS-Cutover fortsetzen (TP23 Stufe 2 ∥ TP31 Schritt 4) + +> **Entstanden am 2026-08-26.** Die Handoff `20260825-agh-dns-cutover.md` wurde begonnen und teilweise +> abgearbeitet. Diese Datei führt den neuen Stand fort. Keine Config-Transaktion offen. + +## Ausgangslage + +**✅ Erledigt in dieser Session (2026-08-26):** + +| Was | Stand | +|-----|-------| +| `opencode.jsonc` | Permission `"allow"`, MCPs: gitea-mcp, mikromcp, pve-mcp, home-assistant, cloudflare (OAuth) | +| `docs/teilprojekte.md` | Quick-Index-Tabelle eingebaut (1-Read-Statusbaum), `hass`-400-Fix vermerkt | +| `CLAUDE.md` | TP-Management-Regel: vorschlagen → abstimmen → anlegen | +| `.opencode/commands/handoff.md` | `/handoff`-Custom-Command (generate + resume) | +| LXC 110 `agh-bf1` | pve, Debian 13, `10.40.20.36`, 4 GB / 512 MB / 2 Cores, `onboot=1`, `startup order=10` | +| LXC 111 `agh-bf2` | pve, Debian 13, `10.40.20.37`, 4 GB / 512 MB / 2 Cores, `onboot=1`, `startup order=10` | +| Backup-Job | Beide VMIDs im Job `backup-6dcf5c10-610f` (pbs, sonntags 01:00) | +| AdGuard `v0.107.79` | Installiert auf 110 + 111 (offizieller Installer) | +| AGH-Konfig | `docs/transaktionen/agh-bf1-AdGuardHome.yaml` — 28 Rewrites (16 Caddy-Sites → `.40`, 8 Hosts → live-IPs), conditional upstream `[/bf.emsenhuber.net/]`, Admin-PW wie altes `adguard_bf1` | + +**Entscheidungen getroffen:** +- **(a)** `bf.lan` → `bf.emsenhuber.net` heben (Domain-Wechsel im DHCP + conditional upstream) +- **(b)** FM beantwortet BF-Namen künftig nicht selbst, sondern fragt nach BF — Paar-Sync löst die toten VLAN1-Antworten +- **tv** = `10.40.40.11` (Reservierung bestätigt), **appletv**/**vuplus** → streichen (keine Reservierung/ARP) + +**IPs vergeben (alle `.36`/`.37`):** ARP auf `vlan20` geprüft — beide frei (keine Kollision). + +## 🔴 AKTUELLER BLOCKER: AGH startet nicht + +**Symptom:** `--check-config` meldet `yaml: construct errors: line 33: cannot construct !!seq into string` +**Ursache:** AdGuard Home v0.107.79 schreibt die `AdGuardHome.yaml` beim Start **selbst neu** (alphabetische +Schlüsselreihenfolge) und verschachtelt dabei `bootstrap_dns` von flach auf `- - 1.1.1.1 / - 1.0.0.1` — +ein Format, das es selbst nicht mehr parsen kann. Zirkelschluss. +**Versuchter Fix:** Datei direkt schreiben → start → AGH korrumpiert sie erneut. + +**🔑 Empfohlener Weg für die nächste Session:** +AGH **nicht** über YAML-Datei einrichten, sondern über die **HTTP-API im First-Run-Wizard-Modus:** +1. AGH stoppen (`systemctl stop AdGuardHome`), `AdGuardHome.yaml` löschen. +2. Starten → AGH läuft im Wizard-Modus auf Port 3000 (kein Admin-Login nötig). +3. `POST /control/install/configure` mit Admin-PW + DNS-Config (upstreams, filter, bootstrap). +4. `POST /control/rewrite/add` für jeden der 28 Rewrites (oder Bulk-POST). +5. `POST /control/dns_config` für cache_size, refuse_any, enable_dnssec etc. +6. Nach erfolgreichem Setup: die resultierende YAML von 110 → 111 kopieren, und auf 111 `POST /control/install/configure` mit denselben Werten. +7. Beide YAMLs ins Repo committen (unter `adguard/AdGuardHome.yaml` o.ä.). + +**Alternativer Weg (einfacher):** Docker-Container auf pve (Muster wie LXC 400) mit `adguard/adguardhome:latest` +— genau das Image, das produktiv auf `adguard_bf1` läuft und dort klaglos startet. Die LXCs sind schon +da, ein `docker compose` darin wäre minimaler Aufwand. Entscheidung gehört dem User. + +## Noch offene Schritte (aus dem ursprünglichen Auftrag) + +Der Handoff `20260825-agh-dns-cutover.md` (192 Zeilen) bleibt **vollständig gültig** — alle Punkte +dort gelten weiter. Zusammenfassung der noch offenen Schritte: + +1. **AGH zum Laufen bringen** (API- oder Docker-Weg, s.o.) +2. **Rewrites auf beiden Instanzen identisch** (Paar-Sync = eine Quelle) +3. **Firewall zuerst** (Fund 3 des Original-Handoffs): + - `TP5-E2: LAN->AGH dns` (.16) → umziehen auf das Paar `.36/.37` + - **Über Golden Config** (Core ist GC-only), nicht ad hoc + - `--refresh-compliance` vor dem Cutover +4. **Testen:** `dig @10.40.20.36 vw.emsenhuber.net` (erwartet `.40`), `dig @10.40.20.36 ` (erwartet Core-Antwort), aus anderem VLAN +5. **VLAN für VLAN umstellen** (20→10→Rest→30 IoT zuletzt): + - Vor jedem Flip `lease-time` auf ~10 min senken + - `dns-server` auf `.36,.37` umstellen + - Abnahme: **frische DHCP-Lease**, nicht `ping` +6. **Domain-Wechsel `bf.lan` → `bf.emsenhuber.net`:** `/ip dhcp-server network set` → `domain=bf.emsenhuber.net` (alle 7). Conditional upstream im AGH zeigt bereits auf `[/bf.emsenhuber.net/]`. +7. **Rollback:** Core bleibt bis Session-Ende unangetastet als Rückfallebene (DNS und DoH laufen dort weiter). +8. **Danach (TP31 Schritt 5–6):** Tunnel `bf-public` + cloudflared auf ap1/ap2, CNAMEs umhängen, alte Tunnel + Container abbauen. + +## Einstieg für die nächste Session + +1. **Diese Datei lesen** → `docs/handoff-20260826-agh-dns-cutover.md` +2. **`docs/teilprojekte.md`** → Quick-Index-Block (Zeilen ~174–200) +3. **Original-Handoff:** `docs/handoff-20260825-agh-dns-cutover.md` (192 Zeilen, alle Details) +4. **AGH zum Laufen bringen** (API- oder Docker-Weg, s.o.) — das ist der erste technische Schritt. +5. **LXC-Zugang:** `ssh root@10.40.20.100 "pct exec 110 -- bash"` +6. **Referenz-Config:** `docs/transaktionen/agh-bf1-AdGuardHome.yaml` (236 Zeilen, lokal) + +## Fallen, die schon bezahlt sind + +- **AGH-YAML-Datei-Kampf ist verloren** — API-Weg oder Docker. +- **`pvesm free` scheitert an geschützten PBS-Snapshots stillschweigend** (Merkregel aus TP31). +- **Ein Statuscode vom öffentlichen FQDN beweist nichts** (Access-Login maskiert tote Dienste). +- **`pct push` liest vom pve-Host, nicht lokal** — Datei erst per scp auf pve, dann push. +- **`bf.lan`-Suffix vs. `bf.emsenhuber.net`**: der conditional upstream muss zum DHCP-domain-Wert passen. + Beim Domain-Wechsel beides synchron ändern, sonst brechen Lease-Namen.