TP45 Doku: Schicht C (FQDN) als durch dokumentiert, Pflichtlektuere nachgezogen

- docs/teilprojekte.md: Schicht-C-Zeile auf C1-C3 durch; neuer Abschnitt mit
  C1 (27 Core-Statics, Job tp45-c-dns), C2 (AGH entdoppelt), C3 (ds-bf ueber
  Caddy), WARP-Abnahme, sowie den zwei offen gelassenen Befunden (AAAA-Leak,
  AGH-Doppeladresse) und der dig-Messfalle. ap3.bf-Bullet korrigiert.
- CLAUDE.md: Pflichtlektuere Block 0 beschrieb noch das ungeloeste FQDN-Problem.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-22 12:31:59 +02:00
parent 6d1d56e463
commit 7b365e1586
2 changed files with 72 additions and 7 deletions

View File

@@ -2742,7 +2742,7 @@ unter `*1A TP5-WOULD-DROP` / `*2D TP5: deny-by-default` (621 Pakete).
|---|---|---|
| **A** | VLAN20 virtuelle Gäste ins Schema — **Nautobot zuerst** (`.30–.34` → `.154–.156`/`.158`), dann AGH | 🔄 **Nautobot ✅ 2026-09-21** (s. u.) · AGH + übrige Gäste offen |
| **B** | VLAN30 — **nur die Pool-Grenze**, Geräte bleiben (Christoph 2026-09-21) | offen |
| **C** | DNS/FQDN: `ds-bf` über Caddy, `coolify.bf` neu, `.bf` vollständig auf den Core, AGH nur Filtering, TP34 | offen |
| **C** | DNS/FQDN: `ds-bf` über Caddy, `coolify.bf` neu, `.bf` vollständig auf den Core, AGH nur Filtering, TP34 | ✅ **C1–C3 durch 2026-09-22** (s. u.) · C4 (TP34) + `coolify.bf` offen |
| **D** | Tunnel-Inventar + GC + generische Namen, TP30 #10, Leak-Ursachen | offen |
| **E** | nas/pve/macmini — **neue IPs zuerst am Core** (Sekundär-IP + 1:1-NAT), dann messen und umstellen; nas zuletzt | offen |
| **F** | CF-/Tunnel-SSoT + Recovery → **TP46** | offen |
@@ -2832,6 +2832,66 @@ bleibt als Aufräumposten offen.
verschoben). Bei einem **erfolgreichen** Deploy ist das kosmetisch, bei einem **gescheiterten**
nimmt es die Fehlermeldung weg — genau dann, wenn man sie braucht.
#### ✅ Schicht C durch (2026-09-22) — FQDN-Wiederherstellung, vorgezogen (C1–C3, Commit `6d1d56e`)
Auslöser: die IP-Umstellung (A/B/E) dauert länger; die internen `*.bf.emsenhuber.net`-Namen mussten
**sofort** zurück. Drei Züge, jeder am **Gerät** *und* am **Client** belegt — nicht am Plan-Status.
**C1 — 17 Namen in den Core** (`nautobot/mikrotik_routeros.j2`, Deploy über den neuen GC-Job
`tp45-c-dns`). Der Core hält jetzt **27** `/ip dns static` (vorher 10): die 9 Caddy-Frontends
(`nautobot` `pbs` `portainer` `ccu` `iobroker` `z2m25` `ha-mcp` `n8n-mcp` `gitea-mcp`) → `.40` ·
`tv.bf`→`10.40.40.11` · `mfc.bf`→`10.40.10.6` · **`ap3.bf`→`.99.13`** (existierte in *keiner* Quelle) ·
`pve.bf`/`pve-mcp.bf` von Host-IP auf `.40` · dazu die **5 bare Namen** (`vw` `hass` `n8n` `gitea`
`ds-bf`) → `.40` (Entscheid 09-22: lokaler Split-Horizon ist **gewollt**, weil `/admin` nur header-frei
geht). 🔑 Der Job liest die Zeilen **aus dem Template selbst** und macht daraus einen **idempotenten
Upsert** (`:if ([:len [/ip dns static find where name=X]] = 0) do={ … }`) — `add` allein ist nicht
wiederholbar. Abnahme: Geräte-Read **27 Statics** · `--refresh-compliance` → **145/145, 0 Drifts**.
**C2 — AGH entdoppelt** (`adguard/AdGuardHome.yaml`, Weg `python3 adguard/agh-sync.py push`).
`upstream_dns` = **nur** `10.40.20.1`; CF-DoH-Zeile und conditional `[/bf.emsenhuber.net/]`-Forward
entfallen; **alle 26 Rewrites raus**. Der Core ist damit die **einzige** Quelle — auch für die bare
Namen, die vorher über DoH **öffentlich** aufgelöst wurden und den Client an den CF-Edge schickten
(dort setzt der Tunnel `CF-Connecting-IP` → `@cf_admin`-Guard → 404). Vorher/Nachher aller 26 Rewrites
geprüft: **verhaltensneutral**, identisches Ziel, eine Quelle statt zwei.
Abnahme: `agh-sync.py check` → `.36 == .37` · `/admin` **header-frei 200**, mit `CF-Connecting-IP`
weiter **404** · Filter intakt (`doubleclick` → `0.0.0.0`) · öffentliche Auflösung intakt.
**C3 — `ds-bf` über Caddy** (CF-Write am Tunnel `bf-public` `48d3b0b6`): Ingress-Origin von
`http://10.40.20.10:8080` auf `https://10.40.20.40:443` + `originRequest.originServerName`. Öffentlich
**200 in 0,24 s** (vorher `000` nach 20 s); `vw`/`hass`/`n8n`/`gitea` unverändert. ⚠️ Der **CF-MCP darf
lesen, aber nicht schreiben** (`1001: Not authorized` auf `PUT …/configurations`) — der Write lief über
`CF_API_TOKEN` aus `mcp/cloudflare/.env` (Wert nie ausgegeben); Original-Ingress vorher gesichert,
nachher gegengeprüft.
**WARP-Abnahme (Christophs Bedingung) ✅.** Unter verbundenem WARP löst `127.0.2.2/.3` den Namen auf
**`.40`** auf, die Route geht über `utun8` (Mesh), `/admin` = **200**. Der zuvor gemeldete 404 des Users
kam aus dem **Browser-/mDNSResponder-Cache** (dort lag noch die CF-Anycast-A); nach TTL-Ablauf sauber.
**Hebel (a) (Zero-Trust Local Domain Fallback) war nicht nötig.**
🔴 **Befund, bewusst offen — AAAA bleibt öffentlich.** Der Core hält nur **A**-Statics und ist kein
Zonen-Eigentümer: eine AAAA-Abfrage **reicht er weiter** und liefert für die bare Namen die **CF-IPv6**
(`2a06:98c1::`). **Heute wirkungslos** — im Netz läuft kein globales IPv6 (der Mac hat keine globale
Adresse; `curl -6` landet über `::ffff:10.40.20.40`). **Latent:** sobald IPv6 kommt, geht der
`/admin`-Weg wieder über die Edge und die Tür ist zu. Christoph-Entscheid 2026-09-22: **dokumentieren,
nicht ändern** — `aaaa_disabled: true` in AGH wäre die Ein-Zeilen-Abhilfe, ist aber netzweit „IPv4-only"
und passt nicht zu „AGH filtert nur".
🔴 **Zweiter Befund — AGH ist doppelt adressiert.** LXC 110/111 tragen im Container **zwei**
VLAN20-Adressen: `eth0` `.36`/`.37` (aus `net0`) **plus** `eth1` `.30`/`.31`. Schicht A ist dort
**halb** umgestellt — die neue IP ist live und wird per DHCP verteilt (`dns-server=10.40.20.30,10.40.20.31`),
die Alt-IP lebt noch. Gehört in die „siedeln"-Messung, nicht in C. ℹ️ **Korrektur einer eigenen
Fehlannahme:** `adguard/agh-sync.py` nennt `.36`/`.37` — das ist **kein** Drift, sondern die
`net0`-Adresse; nur die Konstante kennt die zweite Adresse nicht.
🧪 **Messfalle, die fast ein Fehlalarm wurde:** `dig nautobot.bf` **ohne** `.emsenhuber.net` fragt den
Namen `nautobot.bf.` im **Root** ab und liefert leer — sieht wie ein nicht gefixter Name aus, war aber
die eigene Abfrage. Dieselbe Klasse wie `nc -z` (09-01) und `pct push` (09-21): **erst das eigene
Werkzeug verdächtigen.**
**Offen in C:** `coolify.bf` (nicht ausgerollt, Port unbekannt — **nicht raten**) · **C4** (TP34: FQDN
als **Daten** in Nautobot). Kosmetisch zurückgestellt: die `ds-bf`-Site steht im `caddy/Caddyfile`
weiter im INTERN-Block (nur Beschriftung; ein Caddy-Redeploy allein dafür wäre unverhältnismäßig).
#### Soll-Oktette (Nachschlagetabelle, s. TP32 für die Herleitung)
| Oktett | Rolle | Soll |
|---|---|---|
@@ -2858,7 +2918,8 @@ NAT/mangle/WG sind Template-Literale, der Firewall-Filter kommt als ConfigContex
Lichterketten `.236`/`.237`, Withings `.230`/`.231` … → Christoph: **„VLAN30 nur Pool-Grenze"**.
- Pool-Fund: `pool-v20` `.100–.200` hat **`used=0`** (gratis verschiebbar); `pool-v30` `.100–.250`
enthält **~25 Statics** → Pool und Statics tauschen praktisch die Plätze.
- ⚠️ **`ap3.bf` existiert nirgends** — weder Core-Static noch AGH-Rewrite, obwohl ap3 seit 08-30 live ist.
- ⚠️ **`ap3.bf` existierte nirgends** — weder Core-Static noch AGH-Rewrite, obwohl ap3 seit 08-30 live
ist. ✅ **Behoben in C1 (09-22):** `ap3.bf` → `.99.13` als Core-Static.
- **Abh.:** TP32 (Systematik) · TP37 ✅ (Nautobot-Datenmodell) · TP21 ✅. **Blockiert:** TP34 (rendert
die FQDNs, die hier Daten werden). **Abgrenzung:** VMID-Umnummerierung bleibt draußen; Token-**Rotation**