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>
131 lines
8.0 KiB
Markdown
131 lines
8.0 KiB
Markdown
# 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).
|