# Übergabe — nächste Session: AdGuard als Resolver + Split-Horizon (TP23 Stufe 2 ∥ TP31 Schritt 4) > **Einstieg:** diese Datei, dann [`teilprojekte.md`](teilprojekte.md) → **TP31** und **TP32**. > **Zustand am Netz: stabil.** Caddy läuft produktiv und ist abgenommen, keine Config-Transaktion offen. > > 🔄 **Zweite Fassung (2026-08-25, spät).** Die erste entstand *vor* der Caddy-Abnahme und enthielt drei > Annahmen, die live nicht halten — sie stehen unten unter **„Was den Plan ändert"**. Wer die alte > Fassung im Kopf hat: **Punkt 2 des Auftrags („Konfiguration übernehmen") ist so falsch.** ## Warum eine eigene Session Der Schritt verschiebt die **DNS-Auflösung des ganzen Standorts** vom Core in einen Container. Heute liefert der DHCP in **allen sieben VLANs** `dns-server = .1` (live geprüft) — AdGuard bekommt **niemand**. Ein Fehler trifft sofort jedes Gerät und ist schlecht zu diagnostizieren, wenn die Auflösung selbst das Kaputte ist. **Nicht ans Ende einer langen Sitzung legen** (Lehre aus TP28). ## Ausgangslage (Stand 2026-08-25 23:30, live geprüft) - ✅ **Caddy produktiv und abgenommen**: LXC **130** `caddy-bf1`, **`10.40.20.40`**, `onboot=1`, `startup order=10`, im Backup-Job. Caddy **v2.11.4**, **16 Sites**. Abnahme über den *Host-Header* von einem zweiten Host: **11× 200**, `nautobot` 302, 0,02–0,11 s. Config im Repo **`caddy/Caddyfile`**, Ausrollen mit **`caddy/deploy.sh`**. - ℹ️ `pve-mcp` 400 / `ha-mcp` 403 / `gitea-mcp` 404 sind **keine Proxy-Fehler** — dieselben Codes kommen direkt vom Origin. Nicht als Baustelle behandeln. - 🧹 Der Zertifikatsspeicher hält **17** Zertifikate bei 16 Sites: `grafana` ist verwaist (harmlos). - 🟡 **`hass` liefert weiter 400 — ungelöst, gehört VOR die CNAME-Umstellung** (nicht vor diesen Schritt). `http:`-Block steht in `/homeassistant/configuration.yaml` (`use_x_forwarded_for: true`, `trusted_proxies: 10.40.20.0/24` + `.10` + `.167`), Sicherung `configuration.yaml.bak-20260825-tp31`. **Die Änderung ist seit 23:18 drin, HA läuft aber noch mit dem Stand von 22:40 — der Neustart fehlt.** ⚠️ Sowohl der Schreibzugriff als auch der Restart wurden zuletzt vom Auto-Mode-Klassifikator blockiert; entweder freigeben oder selbst ausführen: `ha core restart` bzw. `homeassistant.restart`, danach `curl -o /dev/null -w "%{http_code}\n" --resolve hass.emsenhuber.net:443:10.40.20.40 https://hass.emsenhuber.net/` - 🔎 **Der Logtext ist der Befund, nicht der Statuscode:** `Received X-Forwarded-For header from an untrusted proxy 10.40.20.40` ≠ „not set-up for reverse proxies" ⇒ die Option greift, die Liste nicht. - ✅ **Aufgeräumt** (TP31 Schritt 1): LXC `120/121/128/129/130(alt)/131` **und `104`** zerstört, 72/72 PBS-Snapshots weg. Die **14 Snapshots von `ct/104` stehen bewusst** (einzige Grafana-Kopie). - ✅ **Startreihenfolge auf pve repariert** (TP32): HA startet nach MariaDB, Docker, MQTT, z2m25. ## 🔴 Was den Plan ändert — drei Funde vom 2026-08-25 (spät), alle live erhoben ### 1. Der Bestands-AdGuard ist ein **Archiv, keine Vorlage** `adguard_bf1` (`10.40.20.16`, Docker in LXC 400) läuft seit 7 Tagen und hält **24 Rewrites** — davon ist der überwiegende Teil **tot**: | Klasse | Anzahl | Beispiel | Warum tot | |---|---|---|---| | Ziel im **toten VLAN1** | 8 | `nas.bf…→10.40.41.10`, `mfc.bf…→10.40.41.4`, `macmini.bf…→10.40.41.167` | VLAN1 ist seit 2026-08-18 leer (TP19) | | Ziel **`nginx-bf.emsenhuber.net`** | 9 | `portainer`, `z2m25`, `nodered`, `grafana`, `vw`, `speedtest`, … | der NPM (LXC **128**) ist **heute** zerstört worden | | **FritzBox-Reste** | 2 | `*.myfritz.net → 100.72.62.31` / `10.40.41.254` | FB6660 seit 2026-07-01 ausgebaut | | FM-Standort | 3 | `nas.fm…→10.101.0.10` | anderer Standort, hier nicht anfassen | ⇒ **Übernehmen: `upstream_dns`, `bootstrap_dns`, Filterlisten. NICHT die Rewrites.** Die 16 Rewrites werden **aus `caddy/Caddyfile` neu erzeugt** (jeder Site-Name → `10.40.20.40`). Die Altlasten oben sind eine **eigene, bewusste Entscheidung je Name** — nicht mitschleppen. Was dort **richtig** steht und mitmuss: ``` upstream_dns: - https://px35ynlol3.cloudflare-gateway.com/dns-query - '[/bf.lan/]10.40.20.1' - '[/40.10.in-addr.arpa/]10.40.20.1' ``` 🔑 Die zweite Zeile ist **nicht optional**: der Core vergibt `domain=bf.lan` und legt aus jeder Lease einen `*.lan`-Eintrag an (`add-dns-entries-suffix=lan`). Ohne diesen conditional upstream sterben **alle** Lease-Namen. Ebenso bleibt **mDNS Sache des Core** (`mdns-repeat-ifaces` = vlan10/20/30/40/90). ### 2. `10.40.20.17` ist **nicht** „bf2" Dort läuft **`adguard_fm2`** — die zweite Instanz des **FM**-Standorts, hier nur mitgehostet. Sie beantwortet `gitea.emsenhuber.net` mit **`10.40.41.123`**, also ebenfalls ins tote VLAN1. ⇒ **Nicht als Vorlage, nicht als „vorhandene Redundanz" verbuchen.** BF hat heute **einen** AGH. (Dass FM stale Rewrites hat, ist ein eigener Punkt — nicht in dieser Session.) ### 3. Die Firewall-Vorratsregeln zeigen auf die **falsche** IP TP5 Etappe 2 hat vorgesorgt, aber hart auf den heutigen Container: ``` TP5-E2: LAN->AGH dns accept udp dst-address=10.40.20.16 dst-port=53 TP5-E2: LAN->AGH dns-tcp accept tcp dst-address=10.40.20.16 dst-port=53 ``` 🔴 **Das ist der Punkt, an dem dieser Cutover sonst scheitert:** heute fragt jeder Client seinen **eigenen Gateway** (`input`-Kette, keine Regel nötig). Nach dem DHCP-Flip wird DNS zu einem **`forward`-Fluss über VLAN-Grenzen** — und die Firewall ist seit 2026-08-18 deny-by-default. Ohne passende Regeln verlieren **IOT, MEDIA, UNTRUSTED, GUEST und MGMT** schlagartig die Auflösung, während VLAN20 (wo der Resolver steht) unauffällig weiterläuft. ⇒ **Die beiden Regeln auf die neuen AGH-Adressen erweitern, bevor irgendein DHCP angefasst wird** — und zwar **über Nautobot Golden Config**, nicht ad hoc: Core-Config ist GC-only. ## Der Auftrag **User-Entscheid 2026-08-25:** Split-Horizon **nicht** auf dem Core, sondern **in AdGuard, zusammen mit TP23 Stufe 2** — „nichts zweimal bauen". 1. **LXC 110 `agh-bf1` + 111 `agh-bf2` bauen**, Muster exakt wie LXC 130 (Debian 13, `tag=20`, `onboot=1`, `startup order=10`, in den Backup-Job `backup-6dcf5c10-610f`). **Als Paar** — ein einzelner AGH wäre ein DNS-SPOF auf pve. **Adressen `10.40.20.36` / `.37`** — TP32 will DNS auf `.3x`, `.30/.31/.32` sind Nautobot; `.36/.37` sind **frei geprüft** (kein ARP, keine Lease, DHCP-Pool beginnt erst bei `.100`). ⚠️ Nebenbefund: TP32 nennt als Pool `.200–.249`, live läuft `.100–.200` — Konflikt mit „`.100–.199` App-Services". Bestand bleibt; nur beim *Vergeben* aufpassen. 2. **Basis-Config übernehmen** (Upstreams/Bootstrap/Filter) aus `adguard_bf1`, `/opt/docker/adguard_bf1/conf/AdGuardHome.yaml` (Backup daneben: `…bak-tp23-20260817`). **Rewrites NEU bauen** — s. Fund 1. 3. **Die 16 Rewrites setzen**: jeder Site-Name aus `caddy/Caddyfile` → **`10.40.20.40`**. 4. **Firewall zuerst** (Fund 3): `TP5-E2`-Regeln auf `.36/.37` erweitern, per GC deployen, `--refresh-compliance` fahren. 5. **Testen, bevor irgendein DHCP angefasst wird:** `dig @10.40.20.36 vw.emsenhuber.net` (erwartet `10.40.20.40`), `dig @10.40.20.36 .lan` (erwartet die Lease-IP), und dasselbe gegen `.37`. **Zusätzlich aus einem anderen VLAN** — sonst prüft man nur VLAN20 und übersieht genau den Firewall-Fall. 6. **VLAN für VLAN umstellen**, nicht alle sieben: **VLAN20 → VLAN10 → Rest**, **VLAN30 (IoT, 26 Geräte) zuletzt**; dort ist ein Reconnect am teuersten. ### ⏱️ Die Falle, die den Zeitplan bestimmt: `lease-time=1d` Alle sieben Server stehen auf **1 Tag** (GUEST 12 h). Ein geändertes `dns-server` erreicht die Clients erst zur **Erneuerung (T1 ≈ halbe Laufzeit)** — der Cutover wirkt also **verzögert und ungleichzeitig**, und ein Rollback wirkt **genauso langsam**. Zwei Konsequenzen: - **Vor dem Flip die `lease-time` im betroffenen VLAN auf ~10 min senken** (GC-Deploy), umstellen, verifizieren, danach zurücksetzen. Sonst zieht sich die Umstellung über Stunden. - **„Es geht noch" beweist nach dem Flip gar nichts** — das Gerät hat schlicht die alte Lease. Abnahme ist **eine frische Lease + `scutil --dns` / `resolvectl status`**, nicht ein `ping`. ### 🔙 Rollback (vorher lesen, nicht danach) 1. `dns-server` im betroffenen `/ip dhcp-server network` zurück auf `.1` — der Core ist unverändert ein vollwertiger Resolver (**DoH zum CF-Gateway, `verify-doh-cert=yes`, `allow-remote-requests=yes`**); er wird in diesem TP **nicht** abgeschaltet. 2. Clients erneuern lassen (s. `lease-time` oben) oder gezielt bouncen. 3. Firewall-Regeln dürfen stehen bleiben — sie schaden nicht. ⇒ **Der Core bleibt bis zum Ende der Session unangetastet als Rückfallebene.** Erst wenn alle sieben VLANs sauber über AGH laufen, wird über sein Abschalten überhaupt geredet (eigener Entscheid). ## Fallen, die schon bezahlt sind - 🔴 **Ein Statuscode vom öffentlichen FQDN beweist nichts.** `grafana.emsenhuber.net` lieferte monatelang **302** — das war der **Access-Login**, während der Dienst gar nicht existierte. **Immer gegen das Origin messen.** Umgekehrt gilt dasselbe: die 400/403/404 der MCP-Endpunkte sind echte Serverantworten, kein Proxy-Fehler. - 🔴 **`pvesm free` scheitert an geschützten PBS-Snapshots stillschweigend.** Entschützen: `pvesh set /nodes/pve/storage/pbs/content/ --protected 0`. - 🔴 **Startreihenfolge auf pve hängt NICHT an der VMID**, solange ein Gast `startup: order=` trägt. - ⚠️ **Core-Config läuft über Nautobot Golden Config** — DHCP- *und* Firewall-Änderung brauchen Template **und** ComplianceRule, sonst Drift. Letzter geprüfter Stand: **104/104, 0 Drifts (08-23)**; vor dem Cutover einmal `--refresh-compliance` fahren, damit die Ausgangslage sauber ist. - ⚠️ **Caddy in LXC 130 hat einen eigenen Netz-Namespace** und ist deshalb nicht von der macvlan/ipvlan-Blindheit betroffen — ein AGH **im Docker-LXC 400** wäre es. Ein weiterer Grund für eigene LXCs statt „Container dazu". - ⚠️ **Mit Split-Horizon greift CF Access innerhalb des Netzes nicht mehr.** Bewusster Preis (User 2026-08-25); innen tragen TP5-Segmentierung und die App-eigene Auth. ## Danach offen (TP31 Rest) Tunnel `bf-public` + cloudflared auf **ap1/ap2** (arm64, 95 MB Flash frei — ⚠️ je ein **physischer** `device-mode`-Wechsel am Gerät nötig), CNAMEs umhängen (`n8n` → `gitea` → `hass` → `vw`; **`hass` erst nach dem 400er-Fix**), dann `bf-nas`/`bf-pve`/`bf-mm` löschen und die alten Container entfernen. Danach: **`adguard_bf1` im Docker-LXC 400 abbauen** — sonst stehen zwei AdGuards mit widersprüchlichen Rewrites im selben Netz.