Files
bf-infra/docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md
Christoph Emsenhuber 3f95a7adf3 TP16.3 §6 Abbau durch, TP GESCHLOSSEN (User zog §6 vor)
Die 7-Tage-Frist wurde auf User-Entscheid aufgehoben ("es wird nichts mehr
sein"). Reihenfolge Container -> Tunnel eingehalten (umgekehrt gaebe es 530er).

Vorbedingung geprueft: alle vier Namen auf bf-public, kein Name mehr an den
Alttunneln -> Abbau gefahrlos.

7 Container entfernt, per exakter Namensliste (nicht per Filter):
  LXC 400 (pve): cloudflared-bfmm, cloudflared-bfnas
  macmini:       cloudflared-bfpve, cloudflared-bfnas
  NAS ep14:      cloudflared-bfpve, cloudflared-bfmm
  plus terpene-cloudflared -- auf zusaetzlichen User-Entscheid, weil
  420.teilzeitladen.xyz jetzt ueber Caddy/CF laeuft. Kein Stack dahinter, also
  kein Wiederauferstehen.

Beweis VOR der Tunnel-Loeschung: 420.teilzeitladen.xyz lieferte mit bereits
entferntem terpene-cloudflared echten Origin-Inhalt (assetlinks-JSON, 200) --
der Dienst haengt also nicht mehr am Tunnel.

4 Tunnel geloescht: bf-mm, bf-nas, bf-pve, terpene-db -- jede ID gegen die
Behalten-Liste (bf-public, fm) geprueft.

Schlusskontrolle: nur noch bf-public (12) + fm (4) healthy; alle vier BF-Namen
und 420 weiterhin 200.

Der terpene-db-Tunnel-Token stand kurz im docker-inspect-Output; mit der
Tunnel-Loeschung ungueltig, kein Rotationsbedarf.

TP16.3 damit vollstaendig abgeschlossen (Status ✅ 2026-09-01). Quick-Index,
Abschnittsheader, §6-Record, Ist-Stand, Runbook §6 und Handoff nachgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 01:08:34 +02:00

131 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handoff — TP16.3 §5 durch: alle vier Namen auf `bf-public`, plus ein 10-Sekunden-Fund
> **2026-08-31/09-01.** Nachfolger von
> [`handoff-20260831-tp16.3-paragraph2-3-durch.md`](handoff-20260831-tp16.3-paragraph2-3-durch.md).
> **Nicht** Teil dieser Session: §6 (Abbau).
---
## 1. Was jetzt steht
**Alle vier öffentlichen Namen laufen über `bf-public`** — der öffentliche Verkehr geht damit
erstmals über **Caddy** statt an ihm vorbei.
| Name | Nachweis von außen | Origin bewiesen? |
|---|---|---|
| `gitea` | 200, `i_like_gitea`-Cookie = echte Gitea-Antwort | ✅ |
| `hass` | 200 + `manifest.json` 200 + **WebSocket `101 Switching Protocols`** | ✅ inkl. Companion-App-Pfad |
| `vw` | `/`, `/alive`, `/api/config` je 200; WS-Hub `401` **von Vaultwarden** | ✅ |
| `n8n` | 302 zum Access-Login (vor *und* nach dem Flip) | ❌ — vom User im Browser bestätigt |
Antwortzeiten vorher/nachher unverändert ⇒ **Caddy im Pfad kostet nichts Messbares.**
🚫 **Die drei Alttunnel stehen bewusst weiter** (`bf-mm`/`bf-nas`/`bf-pve`, je healthy/8) — sie sind
die Rückfallebene. Rückweg je Name = ein `PATCH` auf die alte Tunnel-ID.
**Schicht davor, ebenfalls durch:** die sechs AP-Drifts sind ins Soll gehoben, **Compliance 139/140**
(28 Regeln × 5 Geräte). Übrig bleibt genau `crs326-core`/`wifi-security` = offene Transaktion
`TP25-fund-e-ft-over-ds`. Neu: ComplianceRule **`interface-veth`** + zwei `ConfigReplace`-Regeln, die
die gerätevergebenen veth-MACs normalisieren (`nautobot/ingest-veth-rule.py`).
---
## 2. 🔴 Der eigentliche Fund der Nacht: ein 10-Sekunden-Zoll auf drei Diensten
`gitea` hing bei ~10 % der Anfragen **exakt 10,1 s** — quer über Web-UI, `/api/healthz` **und** den
Git-Pfad. **Ursache:** MariaDB (LXC **302**) hatte `skip-name-resolve` auskommentiert und machte bei
**jeder neuen Verbindung** einen Reverse-Lookup, während ihr `/etc/resolv.conf` auf den **toten**
`10.40.41.254` zeigte. Gemessen: **10.010 ms je Lookup**.
**An derselben DB hängen `Vaultwarden` (.127), `Home Assistant` (.105) und `gitea` (.157)** —
über die Verbindungstabelle belegt.
**Fix (User-Freigabe, Wartungsfenster):** `pct set <id> --nameserver 10.40.20.1` + Reboot für
`302 mariadb`, `102 mqtt5`, `106 influxdb2`, `107 redis`, `150 iob-exposed`.
**Nachher: Lookup 21–24 ms; gitea 0 von 25 Proben langsam**, langsamste 75 ms.
✅ **Beseitigt 2026-09-01:** `skip-name-resolve` aktiviert (Drop-in
`/etc/mysql/mariadb.conf.d/90-skip-name-resolve.cnf`, `@@skip_name_resolve=1`). `mysql.user` vorher
geprüft — **kein Hostname-Grant**, alle `%`/IP/`localhost`, also gefahrlos. Wirkung: gitea/vw/hass
je 0 von 12 frischen Anfragen langsam, max 0,25 s. Der Reverse-Lookup ist damit nicht mehr schnell,
sondern **abgeschafft**.
🔴 **Dabei ist das root-DB-Passwort ins Transkript geraten** (`.my.cnf` mit `password <wert>` ohne `=`,
Maskierung ankerte auf `=`) — **TP30 Posten #6**, zu rotieren. Ausserdem: **LXC 302 war 100 % voll**,
`+30G` online ⇒ 95 GB / 69 %; die Ursache (HA-Recorder, 41 GB `states`) ist **TP40**.
---
## 3. ✅ Latenter Fund — gefunden UND behoben: vier Container überlebten keinen Reboot sauber
`networking.service` und `ifupdown-wait-online.service` sind in **`101`, `102`, `106`, `107`**
fehlgeschlagen. Folge: alles mit `After=network-online.target` startet nach einem Reboot **nicht** —
**influxdb2 kam nicht hoch**, Unit `enabled`, **kein Startversuch im Journal**. Von Hand sofort ok.
🔑 **Nicht von dieser Session verursacht:** `101` wurde vor dem Fix nie angefasst und zeigte dieselben
Units. Die Container liefen nur 13+ Tage ohne Neustart, deshalb war es unsichtbar.
✅ **Behoben 2026-09-01.** **Ursache — dieselbe Altlast wie beim Resolver:** tote `auto`-Stanzas in
`/etc/network/interfaces` aus dem **alten VLAN1-Schema** (`eth0` → `10.40.41.x`) und aus früheren
Versuchen (`veth16`, `veth24`, Tippfehler `eth01`), alle auf **nicht existierende** Interfaces.
`ifup -a` scheiterte daran, während `veth20` sauber hochkam. Entfernt wurden ausschliesslich Stanzas,
deren Interface in `ip -br link` fehlt; Backup je Container `/etc/network/interfaces.bak-20260901`.
🔴 **Abnahme war ein echter Reboot, nicht der Servicestatus:** `106` neu gestartet ⇒ **influxdb kam
nach 5 s von selbst hoch**, `networking active`, null fehlgeschlagene Units.
Endstand: **alle 13 LXCs auf `dns=10.40.20.1`, `networking` überall sauber.** Rest ohne Netzbezug:
`run-rpc_pipefs.mount` (101, 150), `proxmox-regenerate-snakeoil.service` (108).
---
## 4. Drei Messfallen, die diese Session Zeit gekostet haben
1. **Split-Horizon:** der Haus-Resolver liefert für alle vier Namen direkt `10.40.20.40` — ein Test
von zuhause sieht Cloudflare **nie**. Prüfen nur mit `curl --resolve <name>:443:188.114.96.10`
oder von außerhalb. *(Guter Nebeneffekt: ein misslungener Flip bricht intern nichts.)*
2. **Access antwortet je nach Standort verschieden:** `n8n` aus dem Haus 200 (`bf4`-Policy),
von außen 302. `hass`/`vw`/`gitea` stehen auf **`bypass`** — dort **nie** ein Login.
⚠️ Die App `hass, vw, gitea` heisst **zu Recht** so: sie führt alle drei in `self_hosted_domains`,
das Feld `domain` zeigt nur den ersten. Ein Rename wäre eine Verschlechterung gewesen.
3. 🔴 **„Der Host ist ausgefallen" war der eigene Standortwechsel.** Ping/SSH/Caddy waren tot, weil
die Session-Maschine auf einen **Hotspot** gewandert war (`route -n get default` = `172.20.10.1`).
Daraufhin wurde ein **bereits erfolgreicher `n8n`-Flip grundlos zurückgerollt**.
**Merkregel: vor jeder Ausfallmeldung die eigene Default-Route lesen.**
Dazu zwei Werkzeug-Befunde: **der Zähler der Blocker-B-Firewallregel taugt nicht als Wegbeweis**
(cloudflared hält die Origin-Verbindung offen ⇒ kaum neue Verbindungen ⇒ Zähler steht still, obwohl
alles läuft; richtig ist die **Verbindungstabelle**), und **Caddy führt gar kein Access-Log** ⇒ der
alte §5.3-Punkt „Caddy sieht den Request" konnte nie funktionieren.
---
## 5. Nächste Schritte
1. **§6 Abbau** — sechs Container + drei Alttunnel. Frühestens nach störungsfreiem Betrieb;
Christoph hat den **Flip** vorgezogen freigegeben, **nicht** den Abbau.
🚫 `terpene-cloudflared` (LXC 400) und `fm.emsenhuber.net` bleiben. **Namen lesen, nicht Zeilen zählen.**
2. **TP39** (angelegt 2026-09-01, User-Okay) fasst die zwei Restpunkte aus §2 und §3 zusammen:
`skip-name-resolve` auf der MariaDB (vorher `mysql.user` gegen Hostname-Grants prüfen, DB-Zugang
fehlt). **Punkt 2 (`networking.service`) ist am 2026-09-01 bereits erledigt** — offen bleiben
`skip-name-resolve` und der Resolver-Sweep als **wiederkehrende** Kontrolle, auch über die
NAS-Container.
3. **TP30:** Nautobot-Tokens (#5) + **MariaDB-root-Passwort (#6, neu 09-01)** rotieren.
4. **TP40:** HA-Recorder-Retention — die 41-GB-`states`-Tabelle beschneiden (angelegt 09-01).
5. **TP14.4:** ohne Service-Token für die Wildcard-App ist `n8n` von außen nicht bis zum Origin prüfbar.
6. **Caddy-Access-Log** (TP31/TP34): der öffentliche Reverse Proxy protokolliert keine Requests.
7. `mcp/mikromcp/config/routers.yaml` meldet weiter `rosVersion: "7.24"`, live ist `7.24.1`.
---
## 6. Nachtrag 2026-09-01 abends: §6 Abbau vorgezogen und durch — TP16.3 GESCHLOSSEN
Der User zog §6 vor („es wird nichts mehr sein"). Reihenfolge Container→Tunnel eingehalten.
- **7 Container entfernt:** die sechs BF-cloudflared (LXC 400 / macmini / NAS ep14) **plus
`terpene-cloudflared`** — Letzterer auf zusätzlichen Entscheid, weil `420.teilzeitladen.xyz` jetzt
über Caddy/CF läuft. Kein Stack dahinter.
- **Beweis vor der Tunnel-Löschung:** `420.teilzeitladen.xyz` lieferte mit bereits entferntem
`terpene-cloudflared` echten Origin-Inhalt (assetlinks-JSON, 200).
- **4 Tunnel gelöscht:** `bf-mm`, `bf-nas`, `bf-pve`, `terpene-db` (jede ID gegen die Behalten-Liste
`bf-public`/`fm` geprüft).
- **Schlusskontrolle:** nur noch `bf-public` (12) + `fm` (4) healthy; alle vier BF-Namen und `420`
weiterhin 200.
**TP16.3 ist damit vollständig abgeschlossen** (Status ✅ 2026-09-01, wandert ins Archiv).