Compare commits
81 Commits
0680ccabc8
...
claude/pri
| Author | SHA1 | Date | |
|---|---|---|---|
| 909e604ea6 | |||
| 614025eafb | |||
| 677dade184 | |||
| b20edd6b62 | |||
| a38ed0fe1d | |||
| 5a29c482bd | |||
| 4eba3673b7 | |||
| 2b856d3d42 | |||
| f1d565bc88 | |||
| 43c592e5d4 | |||
| 33b18a08db | |||
| 799b693ffa | |||
| 4aeced30b5 | |||
| 89d94dbd45 | |||
| 6f60e03679 | |||
| 2f4866ca9a | |||
| 8e41268b4b | |||
| b915d02a82 | |||
| efb03979a0 | |||
| 268fd859ab | |||
| 7a20a1db4f | |||
| bca8f6e27e | |||
| d63dc7bb78 | |||
| b200401c5a | |||
| 384f356290 | |||
| e96fca5a52 | |||
| 1625c30fd7 | |||
| 83fd69ef8d | |||
| 56746cb24d | |||
| a0ba87d555 | |||
| 674e5fff0d | |||
| c024f85579 | |||
| 9caf145341 | |||
| 7edf01b021 | |||
| f507c50623 | |||
| f8982df200 | |||
| c23628f62f | |||
| b75336c9db | |||
| 70afb165b7 | |||
| efb0f44fa7 | |||
| ac3a125c82 | |||
| 45e4540cf5 | |||
| e8f58b0e5e | |||
| 05a3fd957f | |||
| bf6d3605b7 | |||
| 8aae0f424f | |||
| 72db50fce2 | |||
| cce88bdcba | |||
| c7e173ec5a | |||
| 1b413b41f3 | |||
| e376651247 | |||
| fde9f1535a | |||
| ab01934c2d | |||
| 46e6a54ecb | |||
| 403b4528b2 | |||
| 20671aefd4 | |||
| c543819a90 | |||
| 012397f194 | |||
| faa4308223 | |||
| 155dbc08f2 | |||
| 284df839db | |||
| 07b595c45a | |||
| 724cfd9a98 | |||
| 3f95a7adf3 | |||
| 335c562323 | |||
| 3ea8d050d2 | |||
| ef19a95747 | |||
| 83bcfaabd0 | |||
| 73fec72abe | |||
| f6283fd813 | |||
| 4cd091379e | |||
| e474e5e38a | |||
| 17e8e9f72e | |||
| c8b2a15d5f | |||
| 6f6fa71ffa | |||
| 60360fc3cc | |||
| d5b3ce37ff | |||
| 452ea53576 | |||
| badf715f5a | |||
| 810126c01b | |||
| b697ffc6fa |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,3 +25,4 @@ caddy/caddy.env
|
||||
|
||||
# Config-Backups, die Sessions vor destruktiven Edits anlegen (2026-08-30)
|
||||
*.bak-*
|
||||
docs/macmini-vlan20/stacks
|
||||
|
||||
129
CLAUDE.md
129
CLAUDE.md
@@ -6,28 +6,58 @@ DNS/DHCP-Ablösung, WLAN via **CAPsMAN auf dem Core** (TP28, 2026-08-17 — der
|
||||
|
||||
## Pflichtlektüre pro Sitzung (Reihenfolge)
|
||||
|
||||
1. **`docs/teilprojekte.md`** (Quick-Index-Block) — kanonischer Stand, Scope, Abhängigkeiten, **offene** TPs. **1 Read reicht.**
|
||||
1. **Status/Index = Gitea-Board** (seit TP36-Cutover 2026-09-07): [`admin/bf-infra` · Issues](https://gitea.emsenhuber.net/admin/bf-infra/issues) — TP = Issue, Status = Label `status:*`, Gruppierung = `thema:*`. Für den **Detail/Kontext** eines TP dann den `### TPnn`-Prosa-Abschnitt in **`docs/teilprojekte.md`** (aktiv) bzw. **`docs/teilprojekte-archiv.md`** lesen. *(Die frühere „Quick-Index-Block, 1 Read reicht"-Zeile ist überholt — Index/Status stehen nicht mehr in der Datei.)*
|
||||
2. **`docs/handoff-*.md`** (neueste) — wo die letzte Session aufgehört hat.
|
||||
3. Bei Live-Writes oder Inventur: **`docs/cf-tunnel-mapping.md`**, **`docs/teilprojekte-archiv.md`**.
|
||||
4. 🔴 **WLAN/Fund E — HEBEL 1 GESCHEITERT + TP27 durchgezogen:**
|
||||
[`docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md`](docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md)
|
||||
— `ft-over-ds=no` hat **nicht** gegriffen (124 `reauthenticating` nach dem Eingriff, zwei erlebte
|
||||
Ausfälle um 13:16 und 14:23). Transaktion `TP25-fund-e-ft-over-ds` **bleibt offen**, **Compliance
|
||||
steht weiter absichtlich auf 134/135**. Nächste Entscheidung: Hebel 2 (`ft=no`) **oder**
|
||||
`wpa2-psk,wpa3-psk` — vorher prüfen, ob 7.24.1 das Verhalten schon verändert hat.
|
||||
Vorstufen: [Eingriff](docs/handoff-20260831-fund-e-hebel1-gezogen.md) · [Befund](docs/handoff-20260831-wlan-fund-e.md).
|
||||
5. ap3-Bring-up 2026-08-30: [`docs/handoff-20260830-ap3.md`](docs/handoff-20260830-ap3.md) — sechs Funde zu Werks-MikroTiks, CAPsMAN und Golden-Config-Lücken.
|
||||
6. Inventur-Befund 2026-08-27: [`docs/handoff-20260827-inventur-und-architektur.md`](docs/handoff-20260827-inventur-und-architektur.md) — Master-Struktur, Asymmetrie, Drift.
|
||||
4. ✅ **TP16.3 §5 durch (2026-09-01):** [`docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md`](docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md)
|
||||
— alle vier oeffentlichen Namen laufen ueber `bf-public`/Caddy; Alttunnel bleiben als Rueckfallebene
|
||||
(§6 offen). Enthaelt den 10-Sekunden-DNS-Fund und drei Messfallen.
|
||||
5. ✅ **WLAN/Fund E — GESCHLOSSEN 2026-09-02: 7.24.1 war die Ursache, nicht `ft-over-ds`:**
|
||||
[`docs/handoff-20260902-tp25-fund-e-messung.md`](docs/handoff-20260902-tp25-fund-e-messung.md)
|
||||
— die Abschlussmessung ergab am 09-02 nur **4 `reauthenticating` in 8,6 h** (alle iPhone `F2:62`,
|
||||
isolierte Einzel, 0 Ausfaelle), Verlauf **218 → 40 → 4**; Vorbedingung geprueft (Core-Uptime 1d18h,
|
||||
`caps joined=0`). Hebel 1 (`ft-over-ds=no`) war widerlegt (6,4 h allein → 124× + 2 Ausfaelle) und ist
|
||||
am 09-01 zurueckgebaut; Hebel 2–4 entfallen, **kein Geraete-Write** (Soll stand: `ft=yes ft-over-ds=yes`,
|
||||
**Compliance 140/140**). **Am 2026-09-04 hat Christoph `ft=no` auf `sec-main` als Dauerzustand
|
||||
entschieden** (Hebel 2 doch gezogen: Template + bf-golden-config + Nautobot-Sync, `wifi-security` gruen).
|
||||
🔴 **Nachtrag 09-04: `ft=no` war NICHT uniform.** ap3 trug einen Werks-Inline `security.ft=yes` auf
|
||||
`wifi1/wifi2` (Bring-up unset `!ft-over-ds`, aber nicht `!ft`; Abnahme zählt nur benannte
|
||||
security-Objekte → Inline-Wert unsichtbar). Gemischtes FT-ESS → Strong-Signal-Abbrüche (−43/−45 dBm)
|
||||
**nur auf ap3** bei 3/3 Strichen. Fix: `!security.ft` auf ap3 (uniform `ft=no`), Quelle
|
||||
`tp28-ap3-phase2-cap.rsc` korrigiert. **Merkregel: nach jeder `sec-main`-FT-Änderung jeden CAP einzeln
|
||||
`get wifiN security.ft` prüfen — CAP-lokale Inline-Overrides sind compliance-unsichtbar.**
|
||||
Der TP25-Kanalplan ist am 09-04 committed (DFS-Frequenzlisten + ap1-Provisioning, **140/140, 0 Drifts**).
|
||||
Offen in TP25 bleibt nur **ap2 unterperformt** (2 m/−80 dBm). Vorstufen:
|
||||
[Befund](docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md) ·
|
||||
[Eingriff](docs/handoff-20260831-fund-e-hebel1-gezogen.md) ·
|
||||
[Rueckbau](docs/handoff-20260901-fund-e-hebel1-zurueckgebaut.md).
|
||||
6. ap3-Bring-up 2026-08-30: [`docs/handoff-20260830-ap3.md`](docs/handoff-20260830-ap3.md) — sechs Funde zu Werks-MikroTiks, CAPsMAN und Golden-Config-Lücken.
|
||||
7. Inventur-Befund 2026-08-27: [`docs/handoff-20260827-inventur-und-architektur.md`](docs/handoff-20260827-inventur-und-architektur.md) — Master-Struktur, Asymmetrie, Drift.
|
||||
|
||||
## SSoT & Branch-Konvention (TP36-Cutover 2026-09-07)
|
||||
|
||||
- **SSoT-Dreiteilung:** **Index/Status = Gitea-Issues** (`admin/bf-infra`, Labels `status:*`/`thema:*`) ·
|
||||
**Prosa/Detail = Repo** (`docs/teilprojekte.md` aktiv + `teilprojekte-archiv.md`, `### TPnn`-Abschnitte) ·
|
||||
**Live-Gerätedaten = Nautobot** (Compliance-Zahl, RouterOS-Version …). Ein Status ändert sich **in Gitea**,
|
||||
nicht mehr in einer Repo-Datei. Sync-/Abgleich-Werkzeug fürs Archiv: `bin/gitea-tp-sync.py` (Dry-Run default,
|
||||
Token aus `~/.hermes/.env`, **nie ausgeben**).
|
||||
- **Branch-Konvention:** Branch `tpNN-kurz` **jederzeit** mitten in der Session möglich (`git switch -c`,
|
||||
uncommittete Arbeit wandert mit); für Multi-Session-TPs der Normalfall. **Merge nach `main`, sobald der
|
||||
Code/Config des TP steht.** Weil Steuerungs-Updates nach **Gitea** gehen (nicht in `teilprojekte.md`),
|
||||
kollidieren TP-Branches nicht mehr auf der Steuerungs-Doku — nur noch der eigene `### TPnn`-Prosa-Abschnitt
|
||||
wird angefasst.
|
||||
- **TP anlegen/schließen:** neues aktives TP = **direkt als Gitea-Issue** (Labels setzen), Prosa-Abschnitt
|
||||
im Repo dazu; abschließen = Issue `closed`, Prosa wandert bei Bedarf ins Archiv. **Keine Handtabelle mehr.**
|
||||
|
||||
## Was du sofort wissen musst (Inventur 2026-08-27)
|
||||
|
||||
- **`bf-infra`** ist aktiver Master **mit Gitea-Remote**: `origin` = `https://gitea.emsenhuber.net/admin/bf-infra.git` (live verifiziert 2026-08-30). ⚠️ **Die frühere Zeile „lokal, kein Gitea-Remote → verloren bei Festplattencrash" ist überholt** — sie stammt aus der Inventur vom 2026-08-27 und war damals richtig; das Remote existiert seit spätestens 2026-08-28 (`origin/main` = `b917691`). **Die Backup-Lücke ist damit keine Struktur-, sondern eine Disziplinfrage: `git push`.** Am 2026-08-30 lagen vier Commits nur lokal. 🔴 **Merkregel:** diese Zeile hat eine Session dazu gebracht, „kein Remote" zu behaupten, statt `git remote -v` zu tippen — vor jeder Aussage über Remotes/Backups **live prüfen**.
|
||||
- **`bf-infra`** ist aktiver Master **mit Gitea-Remote**: `origin` = `https://gitea.emsenhuber.net/admin/bf-infra.git` (live verifiziert 2026-08-30). ⚠️ **Die frühere Zeile „lokal, kein Gitea-Remote → verloren bei Festplattencrash" ist überholt** — sie stammt aus der Inventur vom 2026-08-27 und war damals richtig; das Remote existiert seit spätestens 2026-08-28 (`origin/main` = `b917691`). **Die Backup-Lücke ist damit keine Struktur-, sondern eine Disziplinfrage: `git push`.** Am 2026-08-30 lagen vier Commits nur lokal. 🔴 **Das Remote ist nur so viel wert wie der letzte Push** — der Backup-Guard (`~/dev/.bin/backup-guard.sh`, TP35 Schicht 5) bricht Commits ab, solange kein Backup markiert ist; **das ist die Erinnerung ans Pushen, kein Hindernis.** Nicht mit `--no-verify` umgehen. 🔴 **Merkregel:** diese Zeile hat eine Session dazu gebracht, „kein Remote" zu behaupten, statt `git remote -v` zu tippen — vor jeder Aussage über Remotes/Backups **live prüfen**.
|
||||
- **`admin/bf-network-r6`** (Gitea) ist Archiv, letzte aktive Commits 2026-08-25 → read-only-Header.
|
||||
- **`admin/bf-golden-config`** (Gitea) ist Bot-Master (Nautobot 2×/Tag), nicht manuell.
|
||||
- **`admin/blaueblueten-n8n`** (Gitea) ist Master für terpene-Repo.
|
||||
- **`inventory/` ist tot** (Pipeline seit 2025-06 stale). Live-Daten aus MikroMCP/CF/Portainer.
|
||||
- **`mcp/INVENTORY.md`** ist BF-Netz-SSoT; `~/.claude.json`/`opencode.jsonc` sind globalere Werkzeugkästen.
|
||||
- **terpene.teilzeitladen.xyz**: Worker läuft auf Mac mini (`10.40.20.167:8890`), **kein Caddy-Block, kein CF-Tunnel** — Backfill via DB-Migration blockiert (Handoff 2026-08-27).
|
||||
- **Terpenfinder = `420.teilzeitladen.xyz`** (CF-Worker, Repo `admin/blaueblueten-n8n`, hinter CF Access), **kein Caddy, kein Mac mini im Pfad**. `terpene.*` **existiert nicht und soll es nicht** (live geprüft 2026-09-10). Einziger terpene-benannter CF-Gegenstand: der **interne** Tunnel `terpene-db` (`f2d2fc8a`, ohne öffentlichen Hostname, Hyperdrive→VPC→Postgres, s. `docs/cf-tunnel-mapping.md` §17). ⚠️ **Grenze:** blaueblüten ist ein eigenes Projekt — nicht anfassen. *(Die frühere „terpene.teilzeitladen.xyz:8890 via Tunnel"-Zeile war veraltet — bf-mm ist gelöscht.)*
|
||||
- **shelly-mcp / portainer-mcp bewusst NICHT als MCP-Client** (User-Direktive 2026-08-28): shelly-mcp-Container auf DS923 wird via **Portainer-API** (Skript-Aufrufe, `mcp/portainer/.env` als Token-Quelle) deployt, nicht via MCP-Protokoll. Inventar-Eintrag spiegelt das. `mcp-host-policy.md` ist SSoT für die Host-/IP-Konvention.
|
||||
- **Mac mini `10.40.20.167`** ist der **n8n-Host** (n8n `:5678`, n8n-redis `:6379`, n8n-mcp `:3001`) — **NICHT** der zentrale MCP-Host. Performance-Überlegung: MCP-Clients würden auf dem macmini (User-Workstation) laufen und die Box zusätzlich belasten; deshalb liegt der MCP-Host auf der **DS923** (`nas-bf`, Portainer Endpoint 14). gitea-mcp läuft aktuell noch auf dem macmini (historisch, eigene Container-Definition dort) — gehört **bei Gelegenheit** auf die DS923 umgezogen (separater Punkt, **nicht** Teil dieser Session). Container-Definitionen für n8n leben auf dem macmini (Docker Desktop); FQDN→Backend-Mapping im `caddy/Caddyfile`.
|
||||
|
||||
@@ -35,12 +65,15 @@ DNS/DHCP-Ablösung, WLAN via **CAPsMAN auf dem Core** (TP28, 2026-08-17 — der
|
||||
|
||||
Wenn während einer Session ein neues Teilprojekt, eine Abhängigkeit oder ein Querschnittsthema sichtbar wird, das bisher in keinem TP abgebildet ist:
|
||||
- Vorschlagen und mit dir abstimmen (nicht eigenmächtig anlegen).
|
||||
- Auf dein Okay hin anlegen: Quick-Index-Zeile + `### TP<n>`-Abschnitt mit Status `🔜`, Scope,
|
||||
Abhängigkeiten, Abgrenzung. Nächste freie Nummer vergeben (höchste vergebene + 1; Lücken aus
|
||||
verworfenen TPs bleiben frei).
|
||||
- Ist-Stand-Block mitziehen (Datum, betroffene Zeilen).
|
||||
- Auf dein Okay hin anlegen: **Gitea-Issue** `TPnn — <Kurztitel>` mit Labels `status:🔜`(todo) +
|
||||
passendem `thema:*` + Body (Anriss + Verweis auf den Prosa-Abschnitt) **und** einen
|
||||
`### TP<n>`-Prosa-Abschnitt in `docs/teilprojekte.md` (Scope, Abhängigkeiten, Abgrenzung).
|
||||
Nächste freie Nummer vergeben (höchste vergebene + 1; Lücken aus verworfenen TPs bleiben frei).
|
||||
- **Status/Reihenfolge/„was lief zuletzt" gehen ins Gitea-Issue** (Label ändern, Kommentar), **nicht**
|
||||
in eine Quick-Index-Tabelle oder einen Ist-Stand-Block — die gibt es seit dem TP36-Cutover (2026-09-07)
|
||||
nicht mehr in der Datei.
|
||||
|
||||
**Abgeschlossene TPs** stehen seit 2026-08-23 in `docs/teilprojekte-archiv.md` (Volltext, unverändert, mit Inhaltsverzeichnis). **Ein TP wandert erst ins Archiv, wenn nichts mehr daran zu tun ist — und wieder zurück, sobald doch etwas dazukommt.** Ein archiviertes TP ist ein *geschlossenes Ticket, kein versiegeltes*: bei neuer Arbeit an derselben Baustelle wandert der **Volltext zurück** nach `teilprojekte.md` (Zeiger bleibt im Archiv), **kein** Zwillings-TP mit neuer Nummer (Christoph-Direktive 2026-08-30, erster Fall TP28/`ap3`) — und der **Ist-Stand-Block wird bei jeder Änderung mitgezogen**, nicht nur der betroffene TP-Abschnitt.
|
||||
**Abgeschlossene TPs** stehen seit 2026-08-23 in `docs/teilprojekte-archiv.md` (Volltext, unverändert, mit Inhaltsverzeichnis) und ihr Gitea-Issue ist `closed` (Label `status:✅`/`❌`). **Ein TP wandert erst ins Archiv, wenn nichts mehr daran zu tun ist — und wieder zurück, sobald doch etwas dazukommt** (Issue dann `reopen`). Ein archiviertes TP ist ein *geschlossenes Ticket, kein versiegeltes*: bei neuer Arbeit an derselben Baustelle wandert der **Volltext zurück** nach `teilprojekte.md` (Zeiger bleibt im Archiv), **kein** Zwillings-TP mit neuer Nummer (Christoph-Direktive 2026-08-30, erster Fall TP28/`ap3`) — nur noch der betroffene `### TPnn`-Prosa-Abschnitt wird angefasst.
|
||||
|
||||
---
|
||||
|
||||
@@ -206,6 +239,41 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
|
||||
Gesetz** — und ob sie dem konkreten Dienst überhaupt gilt.
|
||||
- **Schwere Container laufen weiterhin auf NAS/pve**, nicht am Router (Caddy, AdGuard: die eine Config
|
||||
ändert sich staendig, die andere schreibt dauernd Logs auf NAND).
|
||||
- ⏱️ **Ein konstanter 10-Sekunden-Hänger ist ein DNS-Timeout, kein Lastproblem** (Fund 2026-09-01,
|
||||
TP16.3-Randbefund). `gitea` hing bei ~10 % der Anfragen exakt 10,1 s — quer über Web-UI,
|
||||
`/api/healthz` **und** den Git-Pfad, also kein Rendering. Ursache: **MariaDB (LXC 302) hatte
|
||||
`skip-name-resolve` auskommentiert** und machte bei **jeder neuen Verbindung** einen
|
||||
Reverse-Lookup, während ihr `/etc/resolv.conf` noch auf den toten `10.40.41.254` zeigte
|
||||
(glibc: 5 s × 2 Versuche = 10 s). Pool-Verbindungen waren schnell ⇒ es wirkte sporadisch.
|
||||
🔑 **Drei Merkregeln daraus:** (a) **immer gegen eine zweite Sache messen, die denselben Weg
|
||||
nimmt** — `vw`/`hass` über dieselbe Strecke hatten 0 von 30 Hängern, das hat CF, Tunnel, Firewall
|
||||
und Caddy in einem Schritt entlastet; (b) **wer an einer DB hängt, sagt die Verbindungstabelle**
|
||||
(`ss -tn | grep 3306`), nicht die Vermutung — hier hingen **Vaultwarden, Home Assistant und gitea**
|
||||
an derselben MariaDB, und die Annahme „Vaultwarden nutzt SQLite" war schlicht falsch;
|
||||
(c) **ein toter Resolver ist selten allein** — der Sweep über alle LXCs fand **fünf** Container mit
|
||||
`10.40.41.254`. Sweep: `for c in $(pct list|awk 'NR>1{print $1}'); do pct exec $c -- grep ^nameserver /etc/resolv.conf; done`
|
||||
- 🔌 **`networking.service` failed bei funktionierendem Netz = tote `auto`-Stanzas in
|
||||
`/etc/network/interfaces`** (Ursache gefunden + behoben 2026-09-01). In vier LXCs standen dort noch
|
||||
Einträge aus dem **alten VLAN1-Schema** (`eth0` → `10.40.41.x`) und aus früheren Versuchen
|
||||
(`veth16`, `veth24`, Tippfehler `eth01`) — auf Interfaces, die es im Container gar nicht gibt.
|
||||
`ifup -a` scheitert daran, das echte `veth20` kommt trotzdem hoch. **Fix:** nur die Stanzas
|
||||
entfernen, deren Interface in `ip -br link` fehlt (`lo` und die echten behalten), Backup daneben.
|
||||
🔴 **Abnahme ist ein echter Reboot, nicht `systemctl is-active`** — der Servicestatus sagt nichts
|
||||
darüber, ob beim nächsten Start etwas hochkommt.
|
||||
- 🧪 **Ein Messwerkzeug, das etwas anderes beantwortet als die Frage, kostet mehr Zeit als der Fehler**
|
||||
(zweimal in einer Nacht, 2026-09-01). (a) **`nc -z` lieferte falsch-negative** „Port zu" für neun
|
||||
Dienste gleichzeitig — inklusive des SSH-Ports, über den die Session gerade arbeitete; `curl` bekam
|
||||
von demselben Host **HTTP 200 in 24 ms**. **Bei „alles gleichzeitig kaputt" zuerst das eigene
|
||||
Werkzeug verdächtigen**, dann das Netz: ein Python-Socket oder `curl` entscheidet in Sekunden.
|
||||
(b) **Ein Firewall-Zähler taugt nicht als Wegbeweis**, wenn der Client die Verbindung offenhält
|
||||
(`cloudflared`): er zählt nur NEUE Verbindungen und steht still, obwohl alles läuft — richtig ist
|
||||
die **Verbindungstabelle** (`/ip firewall connection`).
|
||||
- 🔌 **`networking.service` kann in einem LXC dauerhaft `failed` sein, ohne dass das Netz fehlt** —
|
||||
und dann startet alles mit `After=network-online.target` nach einem Reboot **nicht**
|
||||
(Fund 2026-09-01: `101`, `102`, `106`, `107`; **influxdb2 kam nach dem Neustart nicht hoch**,
|
||||
Unit `enabled`, **kein Startversuch im Journal**). Fällt nur auf, wenn man neu startet — die
|
||||
Container liefen 13+ Tage. **Vor jedem geplanten LXC-Neustart `systemctl --failed` lesen und
|
||||
danach die Ports gegen vorher vergleichen**, sonst verliert man still einen Dienst.
|
||||
- **VLAN20-Docker-Hosts: Host-DNS nach dem Umzug prüfen (2026-07-10, TP14.2a):** NAS + pve-LXC zeigten `/etc/resolv.conf` noch auf totes `.41.254` → `docker pull` ghcr scheitert (`EAI_AGAIN`, aber Egress ok!). Fix = `.20.1`: LXC `pct set 400 --nameserver 10.40.20.1`; **Synology-Falle: DSM-„Allgemein"-DNS ≠ was `dockerd` liest** — Interface zieht DNS per DHCP → Fix an der *Netzwerkschnittstelle* „DNS manuell". Laufende Container frieren den `127.0.0.11`-Upstream zum Erstellzeitpunkt ein (Recreate nötig). Merkregel: `docker-pull-hängt` + `dns.lookup EAI_AGAIN` aber `TCP zu ghcr-IP:443 ok` = toter Resolver, nicht Egress.
|
||||
- 📜 **~~ALLNET VLAN-DB (TP1)~~ — historisch.** Die VLAN-Semantik gilt weiter (**40=MEDIA, 50=UNTRUSTED**), die Portangaben (GE1/GE2/GE8) beziehen sich auf ein ausgebautes Gerät.
|
||||
- **ap2 hängt an `crs326-branch ether24`** (Trunk, native VLAN1 + tagged 10-99); **branch-Uplink `ether1` → `crs326-core ether8`** (korrigiert 2026-08-16 — die frühere Angabe „→ sw1 GE8" stammt aus der Zeit vor dem Core-Tausch; MAC-hart belegt in TP22 Schritt 5).
|
||||
@@ -289,6 +357,33 @@ Verhaltensregeln für nachfolgende AI-Sessions — kleiner, klarer, weniger Drif
|
||||
- **Manuell gepflegte Doku mit Live-Daten verliert gegen die Realität, wenn sie lang wird.** Befund 2026-08-28: der „Nächster Schritt (2026-08-26): TP31 Schritt 5"-Satz stand zwei Tage nach seiner Formulierung noch im Ist-Stand-Block, obwohl ich in derselben Zeit drei Folge-Sessions eröffnet hatte. **Merkregel pro Edit:** drei Stellen berücksichtigen — Quick-Index (Tabelle), TP-Abschnitt, Ist-Stand-Block. Keine schlägt die andere; wer eine ändert, **muss** die anderen mitlesen. Strukturelle Antwort = TP36 (SSoT via Nautobot, Datei wird read-only Snapshot) — eigene Session, nicht nebenbei. **Lessons-Block erweitert 2026-08-28 nach Skill-Verifikation in opencode.**
|
||||
- **`sed 's/=.*/=<set>/'` maskiert NICHT, wenn das `.*` greedy ist und der Wert Slashes/Backslashes enthält** (Befund 2026-08-28, shelly-mcp-Deploy). Ich habe `sed 's/SHELLY_DEVICE_PW=.*/<set>/'` auf die Stack-YML angewendet — der **Wert selbst** wurde in den Output geschrieben, weil mein Replacement-String nicht greedy genug war und ich die Pipe nicht mit `cat -v` oder `head -15 | sed 's|=.*|=<set>|'` abgesichert hatte. Folge: **`SHELLY_DEVICE_PW` ist jetzt als verbrannt zu betrachten** — wandert in **TP30 Posten #3** mit Hochstufung. **Merkregel:** bei jeder Ausgabe von Secret-haltigen Dateien entweder `head -c <n>` (Abbruch nach Bytes), oder die Datei vor dem Read mit `tr -d '\n' | sed 's|=.*|=<set>|'` über einen Stream-Filter schicken — **niemals** einfach `cat` und auf einen Replacement-Pattern vertrauen. Vergleichbar zum PSK-Leak 2026-08-24.
|
||||
|
||||
- **Vor jeder Drift-Bewertung `python3 nautobot/gc-transaktion.py status` lesen** (Befund 2026-08-31,
|
||||
zweimal am selben Tag gestolpert). **Drift aus einem laufenden Versuch sieht identisch aus wie ein
|
||||
Versehen** — die Compliance-Zahl unterscheidet nicht. Konkret: `crs326-core`/`wifi-security`
|
||||
(`ft-over-ds=no`) wurde dem 7.24.1-Upgrade zugeschrieben und als „braucht eine Entscheidung"
|
||||
weitergereicht; tatsächlich ist es **TP25 Fund E Hebel 1**, um 08:09 bewusst gesetzt, während der
|
||||
Core erst um 14:36 gehoben wurde, geführt als offene Transaktion `TP25-fund-e-ft-over-ds`.
|
||||
🔴 **Eine solche Drift grün zu machen macht den Versuch unsichtbar.** Umgekehrt gilt: was **dauerhaft**
|
||||
gelten soll (z.B. das `veth`/`masquerade` aus TP16.3 §3.4), gehört **nicht** in eine Transaktion,
|
||||
sondern ins **Soll** — Transaktion = befristeter Versuch, Template = Dauerzustand.
|
||||
⚠️ Das Skript löst den Token-Pfad gegen die Repo-Wurzel auf und findet ihn **aus einem Worktree
|
||||
heraus nicht** (`210-nautobot.yml` liegt nur im Haupt-Checkout) — die Transaktionsliste kommt
|
||||
trotzdem, nur die Compliance-Spalte fehlt dann.
|
||||
- **Maskierungs-Muster auf den SCHLÜSSELNAMEN ankern, nie auf ein Trennzeichen** (Befund 2026-08-31,
|
||||
zweiter Fall dieser Klasse nach `SHELLY_DEVICE_PW`). `grep -n "TOKEN" datei | sed 's/:.*TOKEN/…/'`
|
||||
maskiert **nicht**: `grep -n` stellt `<zeile>:` voran, und das `:.*TOKEN` matcht diesen Präfix statt
|
||||
den Wert — ein nachgeschaltetes `cut -c1-60` schneidet dann genau nichts weg. So sind zwei
|
||||
Nautobot-Tokens ins Transkript geraten. **Sicher ist nur**
|
||||
`sed -E 's/(TOKEN|PASSWORD|SECRET|KEY|PASS)=.*/\1=<redacted>/'`. Und: **Werte nie suchen, um sie zu
|
||||
sehen** — den Schlüssel per `sed -n 's/^…KEY=//p'` direkt in eine Variable holen, nie über `grep`
|
||||
mit Ausgabe. Vergleichbar zum PSK-Leak 2026-08-24 und zum `sed`-Fall 2026-08-28.
|
||||
- **Vor jedem Flash-Budget auf MikroTik `docker export | wc -c` messen, nicht `docker image inspect
|
||||
.Size`** (Befund 2026-08-31, TP16.3). `.Size` meldete für `cloudflared` 27,5 MB, entpackt waren es
|
||||
**69,5 MiB** — das offizielle Image passt damit auf keinen hAP/cAP. RouterOS braucht beim Import
|
||||
**Tar UND entpacktes Abbild gleichzeitig**. 🔴 **Und `docker save` schreibt seit Docker 25
|
||||
(containerd-Store) OCI statt docker-v1** → RouterOS meldet `no config found in manifest`, was nach
|
||||
kaputtem Image klingt und ein Formatproblem ist. Beides in `docs/tp16.3-bf-public-ap-connector-runbook.md` §2.2.
|
||||
|
||||
**Checkliste vor jedem Edit-Vorschlag:**
|
||||
|
||||
1. Habe ich die SSoT für die Datei/das Repo benannt?
|
||||
|
||||
@@ -8,7 +8,7 @@ unter OpenCode und anderem LLM weitergepflegt.
|
||||
|
||||
| Repo | Rolle | Stand |
|
||||
|---|---|---|
|
||||
| `~/dev/bf-infra/` (lokal) | Aktiver Master, Working-Copy | kein Gitea-Remote (Sicherheitslücke, offen) |
|
||||
| `~/dev/bf-infra/` + `admin/bf-infra` (Gitea) | Aktiver Master | **Remote seit 2026-08-30**, `main` synchron — Backup-Lücke geschlossen |
|
||||
| `admin/bf-network-r6` (Gitea) | Archiv, historischer Master | read-only-Header, letzte aktive Commits 2026-08-25 |
|
||||
| `admin/bf-golden-config` (Gitea) | Bot-Master (Nautobot 2×/Tag) | intended/ + backups/, nicht manuell |
|
||||
| `admin/blaueblueten-n8n` (Gitea) | Master für terpene-Repo | aktiv, lokal synchron |
|
||||
|
||||
18
__init__.py
Normal file
18
__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""Macht die bf-infra-Repo-Wurzel zu einem regulären Python-Paket.
|
||||
|
||||
🔴 LOAD-BEARING — NICHT löschen (sonst laden die Nautobot-Jobs nicht mehr).
|
||||
|
||||
Nautobot klont dieses Repo nach GIT_ROOT/bf_infra/ und lädt Jobs über
|
||||
`import_modules_privately()` → `pkgutil.walk_packages([GIT_ROOT])`. walk_packages
|
||||
entdeckt ausschließlich *reguläre* Pakete (mit __init__.py), niemals
|
||||
Namespace-Packages (Verzeichnisse ohne __init__.py). Ohne diese Datei ist
|
||||
`bf_infra` für den Loader unsichtbar und `jobs/` wird nie importiert — Symptom:
|
||||
Git-Sync SUCCESS, aber Log "No jobs were registered on loading the
|
||||
`bf_infra.jobs` submodule" und kein Job-DB-Eintrag.
|
||||
|
||||
Der module_path-Filter des Loaders (["bf_infra","jobs"]) importiert nur
|
||||
`bf_infra` + `bf_infra.jobs.*`; die übrigen Verzeichnisse (nautobot/, routeros/,
|
||||
bin/, …) bleiben unangetastet und laufen weiter als Standalone-Skripte.
|
||||
|
||||
Verifiziert 2026-09-10 (Nautobot 3.1.7, Python 3.14) — TP44 Teil B.
|
||||
"""
|
||||
@@ -13,7 +13,9 @@ http:
|
||||
session_ttl: 30d
|
||||
users:
|
||||
- name: admin
|
||||
password: $2a$10$ue8PEedG4t2JRyT83XiGHeqIU4PFRzhn8rjDOZGYGt0sFC2qju2fi
|
||||
password: '!on-device (siehe ~/.secrets + Gerät)'
|
||||
- name: automation
|
||||
password: '!on-device (siehe ~/.secrets + Gerät)'
|
||||
auth_attempts: 5
|
||||
block_auth_min: 15
|
||||
http_proxy: ""
|
||||
@@ -202,69 +204,9 @@ filtering:
|
||||
- domain: gitea.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: nautobot.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: ds-bf.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: ccu.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: iobroker.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: z2m25.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: pve-mcp.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: ha-mcp.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: n8n-mcp.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: gitea-mcp.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: pve.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: portainer.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: pbs.emsenhuber.net
|
||||
answer: 10.40.20.40
|
||||
enabled: true
|
||||
- domain: macmini.emsenhuber.net
|
||||
answer: 10.40.20.167
|
||||
enabled: true
|
||||
- domain: mfc.emsenhuber.net
|
||||
answer: 10.40.10.6
|
||||
enabled: true
|
||||
- domain: tv.emsenhuber.net
|
||||
answer: 10.40.40.11
|
||||
enabled: true
|
||||
- domain: docker.emsenhuber.net
|
||||
answer: 10.40.20.126
|
||||
enabled: true
|
||||
- domain: platform-pg.emsenhuber.net
|
||||
answer: 10.40.20.20
|
||||
enabled: true
|
||||
- domain: core.emsenhuber.net
|
||||
answer: 10.40.99.1
|
||||
enabled: true
|
||||
- domain: ap1.emsenhuber.net
|
||||
answer: 10.40.99.11
|
||||
enabled: true
|
||||
- domain: ap2.emsenhuber.net
|
||||
answer: 10.40.99.12
|
||||
enabled: true
|
||||
- domain: branch.emsenhuber.net
|
||||
answer: 10.40.99.2
|
||||
enabled: true
|
||||
- domain: nas.bf.emsenhuber.net
|
||||
answer: 10.40.20.10
|
||||
enabled: true
|
||||
@@ -316,7 +258,232 @@ clients:
|
||||
rdns: true
|
||||
dhcp: true
|
||||
hosts: true
|
||||
persistent: []
|
||||
persistent:
|
||||
- safe_search:
|
||||
enabled: false
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: dns-bypass-exempt
|
||||
ids:
|
||||
- 10.40.10.82
|
||||
- 10.40.10.183
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: 381d431a-1a43-41ea-adaa-2d67ada9aab0
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: false
|
||||
filtering_enabled: false
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
- safe_search:
|
||||
enabled: true
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: grp-guest
|
||||
ids:
|
||||
- 10.40.90.0/24
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: af70dd86-43a9-4165-8228-26c7b90db5e6
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: false
|
||||
filtering_enabled: true
|
||||
parental_enabled: true
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
- safe_search:
|
||||
enabled: false
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: grp-infra
|
||||
ids:
|
||||
- 10.40.20.0/24
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: 78b2da82-1946-41ee-b386-b04eaee49bc3
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: false
|
||||
filtering_enabled: false
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
- safe_search:
|
||||
enabled: false
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: grp-iot
|
||||
ids:
|
||||
- 10.40.30.0/24
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: 7a8ac674-4365-4b06-ad51-2516400903a1
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: true
|
||||
filtering_enabled: true
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
- safe_search:
|
||||
enabled: false
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: grp-main
|
||||
ids:
|
||||
- 10.40.10.0/24
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: 39955cc1-6ec2-4cf6-a757-233672b9dc3d
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: true
|
||||
filtering_enabled: true
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
- safe_search:
|
||||
enabled: false
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: grp-media
|
||||
ids:
|
||||
- 10.40.40.0/24
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: 44e4a1d7-d1b6-446c-a753-65e714ec93aa
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: false
|
||||
filtering_enabled: false
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
- safe_search:
|
||||
enabled: false
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: grp-mgmt
|
||||
ids:
|
||||
- 10.40.99.0/24
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: 4c5eeafb-f7f2-4fb1-ab87-fd2a2366d57a
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: false
|
||||
filtering_enabled: false
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
- safe_search:
|
||||
enabled: false
|
||||
bing: false
|
||||
duckduckgo: false
|
||||
ecosia: false
|
||||
google: false
|
||||
pixabay: false
|
||||
yandex: false
|
||||
youtube: false
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: Local
|
||||
ids: []
|
||||
name: grp-untrusted
|
||||
ids:
|
||||
- 10.40.50.0/24
|
||||
tags: []
|
||||
upstreams: []
|
||||
uid: 7f182498-7b82-4580-b1b0-0a2d46c205ef
|
||||
upstreams_cache_size: 0
|
||||
upstreams_cache_enabled: false
|
||||
use_global_settings: true
|
||||
filtering_enabled: true
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
use_global_blocked_services: true
|
||||
ignore_querylog: false
|
||||
ignore_statistics: false
|
||||
log:
|
||||
enabled: true
|
||||
file: ""
|
||||
|
||||
57
adguard/README.md
Normal file
57
adguard/README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# AdGuard Home — `agh-bf1` (.36) / `agh-bf2` (.37) · TP23 Stufe 2/4/5
|
||||
|
||||
Das AGH-**Paar** (pve LXC 110/111, `10.40.20.36` / `.37`) ist der Client-Resolver des BF-Netzes
|
||||
(DHCP liefert beide in allen 7 VLANs). Upstream: DoH zum CF-Gateway; conditional
|
||||
`[/bf.emsenhuber.net/] → 10.40.20.1`. **Kein natives HA** → Sync ist Betriebsaufwand.
|
||||
|
||||
## Dateien
|
||||
| Datei | Zweck |
|
||||
|---|---|
|
||||
| `AdGuardHome.yaml` | **Repo-SSoT** der Config. **Passwort-Hashes REDIGIERT** (`'<redacted>'`) — keine Secrets im Git. Echte Hashes leben auf den Geräten; Klartext des API-Users in `~/.secrets`. |
|
||||
| `agh-sync.py` | `check` (Drift `.36`↔`.37`) · `push` (SSoT auf beide, gestaffelter Restart, reinjiziert Hashes live). |
|
||||
| `agh-exception.py` | Exception-Primitive (Stufe 5) gegen **beide** Instanzen. |
|
||||
|
||||
## Client-Policy (Stufe 4, `clients.persistent`)
|
||||
Ein VLAN = eine CIDR-Gruppe. Alle nutzen denselben CF-Upstream-Filter; Divergenz = per-Client-Toggle.
|
||||
|
||||
| Gruppe | CIDR | filtering | safe_search | parental |
|
||||
|---|---|---|---|---|
|
||||
| grp-main | 10.40.10.0/24 | an (global) | – | – |
|
||||
| grp-infra | 10.40.20.0/24 | **aus** | – | – |
|
||||
| grp-iot | 10.40.30.0/24 | an | – | – |
|
||||
| grp-media | 10.40.40.0/24 | **aus** | – | – |
|
||||
| grp-untrusted | 10.40.50.0/24 | an | – | – |
|
||||
| grp-guest | 10.40.90.0/24 | an | **on** | **on** |
|
||||
| grp-mgmt | 10.40.99.0/24 | **aus** | – | – |
|
||||
| dns-bypass-exempt | 10.40.10.183 + .82 | **aus** | – | – |
|
||||
|
||||
`filtering aus` bei INFRA/MEDIA/MGMT = bewusste Reduktion (Streaming/Server/Mgmt nicht brechen), per Gruppe rückholbar.
|
||||
|
||||
## Sync-Invariante
|
||||
AGH **schreibt die YAML beim Restart um** (normalisiert) → **nicht** gegen die Repo-Datei diffen,
|
||||
sondern **`.36` == `.37`**. Genau das prüft `agh-sync.py check`.
|
||||
|
||||
## Exception-Contract (Stufe 5 — was die HA-Schicht auslöst)
|
||||
Auth: Basic, User `automation` (`~/.secrets` → `AGH_AUTOMATION_*`). **Immer auf `.36` UND `.37`.**
|
||||
|
||||
🔴 **Wichtig für D:** die beiden AGH-Endpunkte sind **read-modify-write**, kein simples Append —
|
||||
`set_rules` **ersetzt die ganze Liste**, `clients/update` braucht das **volle Client-Objekt**.
|
||||
Ein zustandsloses HA-`rest_command` reicht deshalb **nicht**; `agh-exception.py` ist die
|
||||
Referenz-RMW-Implementierung, die D aufruft (Deploy-Weg auf HAOS in Etappe D zu entscheiden:
|
||||
`shell_command`/`command_line` gegen die deployte CLI **oder** ein dünner Wrapper-Endpunkt).
|
||||
|
||||
| Aktion | CLI | AGH-API (RMW) |
|
||||
|---|---|---|
|
||||
| Domain global entsperren | `allow-domain <d>` | `GET /control/filtering/status` → +`@@\|\|<d>^` → `POST /control/filtering/set_rules` |
|
||||
| Entsperrung zurück | `unallow-domain <d>` | dito, Regel entfernen |
|
||||
| Client entfiltern | `unfilter <ip>` | `GET /control/clients` → Objekt, `filtering_enabled=false` → `POST /control/clients/update` |
|
||||
| Client wieder filtern | `refilter <ip>` | dito, zurück auf global |
|
||||
|
||||
**Kein Timing in der CLI** — Ablauf/Revert macht der Aufrufer (HA-Timer) und, ab Stufe 6, der
|
||||
RouterOS-Backstop.
|
||||
|
||||
## RouterOS-Backstop (Stufe 6, noch NICHT gebaut)
|
||||
Analog `jit-admin` (`routeros/tp5-etappe4-input-mgmt.rsc`): Address-List `jit-dns-bypass` mit
|
||||
`timeout` + Forward-Regel, die dieser Liste 53/853 nach außen erlaubt — der Fail-safe, falls HA
|
||||
den Revert verpasst. Gebaut via **Nautobot GC** (kein Direkt-Write), erst wenn die Bypass-Sperre
|
||||
scharf geschaltet wird.
|
||||
129
adguard/agh-exception.py
Executable file
129
adguard/agh-exception.py
Executable file
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
agh-exception.py — TP23 Stufe 5 Exception-Primitive gegen das AGH-Paar (.36 + .37).
|
||||
|
||||
Von der HA-Self-Service-Schicht (rest_command) ODER von Hand aufrufbar. Wirkt IMMER auf
|
||||
BEIDE Instanzen (kein Sync im Datenpfad). KEIN eigenes Timing — Ablauf/Revert macht der
|
||||
Aufrufer (HA-Timer) bzw. der RouterOS-Backstop (Stufe 6). Diese CLI ist reines add/remove.
|
||||
|
||||
allow-domain <domain> → user_rules += @@||domain^ (Domain für ALLE entsperren)
|
||||
unallow-domain <domain> → user_rules -= @@||domain^
|
||||
unfilter <ip> → Client (dessen ids <ip> enthält) filtering_enabled=false
|
||||
refilter <ip> → denselben Client wieder filtern (use_global_settings=true)
|
||||
status → user_rules + Client-Policy beider Instanzen
|
||||
|
||||
Auth: AGH_AUTOMATION_USER/_PASS aus ~/.secrets/credentials.env (nie in argv).
|
||||
"""
|
||||
import sys, os, json, base64, urllib.request, urllib.error, pathlib, re
|
||||
|
||||
DOMAIN_RE = re.compile(r"^(?=.{1,253}$)([a-z0-9](-?[a-z0-9]+)*\.)+[a-z]{2,}$", re.I)
|
||||
IP_RE = re.compile(r"^\d{1,3}(\.\d{1,3}){3}$")
|
||||
|
||||
INST = ["10.40.20.36", "10.40.20.37"]
|
||||
# Creds-Quellen in Reihenfolge: erste, die User+Pass liefert, gewinnt.
|
||||
# So läuft derselbe Code auf dem Mac (~/.secrets) und auf HAOS (/config).
|
||||
CRED_FILES = [
|
||||
os.environ.get("AGH_CREDS_FILE"),
|
||||
str(pathlib.Path.home() / ".secrets/credentials.env"),
|
||||
"/config/agh-exception.secrets",
|
||||
]
|
||||
|
||||
|
||||
def _from_file(path):
|
||||
u = p = None
|
||||
try:
|
||||
for line in open(path).read().splitlines():
|
||||
if line.startswith("AGH_AUTOMATION_USER="): u = line.split("=", 1)[1].strip()
|
||||
if line.startswith("AGH_AUTOMATION_PASS="): p = line.split("=", 1)[1].strip()
|
||||
except OSError:
|
||||
return None
|
||||
return (u, p) if (u and p) else None
|
||||
|
||||
|
||||
def creds():
|
||||
eu, ep = os.environ.get("AGH_AUTOMATION_USER"), os.environ.get("AGH_AUTOMATION_PASS")
|
||||
if eu and ep:
|
||||
return eu, ep
|
||||
for f in CRED_FILES:
|
||||
if f and (r := _from_file(f)):
|
||||
return r
|
||||
sys.exit("AGH_AUTOMATION_USER/_PASS: weder Env noch eine Creds-Datei gefunden")
|
||||
|
||||
|
||||
AUTH = "Basic " + base64.b64encode(":".join(creds()).encode()).decode()
|
||||
|
||||
|
||||
def api(ip, path, method="GET", body=None):
|
||||
url = f"http://{ip}{path}"
|
||||
data = json.dumps(body).encode() if body is not None else None
|
||||
req = urllib.request.Request(url, data=data, method=method,
|
||||
headers={"Authorization": AUTH,
|
||||
"Content-Type": "application/json"})
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=8) as r:
|
||||
raw = r.read()
|
||||
return json.loads(raw) if raw else {}
|
||||
except urllib.error.HTTPError as e:
|
||||
sys.exit(f"{ip} {path} → HTTP {e.code}: {e.read().decode()[:200]}")
|
||||
except Exception as e:
|
||||
sys.exit(f"{ip} {path} → {e}")
|
||||
|
||||
|
||||
def rule(domain):
|
||||
return f"@@||{domain}^"
|
||||
|
||||
|
||||
def allow(domain, remove=False):
|
||||
domain = domain.strip().lower()
|
||||
if not DOMAIN_RE.match(domain):
|
||||
sys.exit(f"ungültige Domain: {domain!r}")
|
||||
r = rule(domain)
|
||||
for ip in INST:
|
||||
st = api(ip, "/control/filtering/status")
|
||||
rules = st.get("user_rules", [])
|
||||
if remove:
|
||||
rules = [x for x in rules if x != r]
|
||||
elif r not in rules:
|
||||
rules = rules + [r]
|
||||
api(ip, "/control/filtering/set_rules", "POST", {"rules": rules})
|
||||
print(f"{ip}: {'entfernt' if remove else 'gesetzt'} {r} (user_rules={len(rules)})")
|
||||
|
||||
|
||||
def set_filter(ip_addr, enabled):
|
||||
if not IP_RE.match(ip_addr):
|
||||
sys.exit(f"ungültige IP: {ip_addr!r}")
|
||||
for ip in INST:
|
||||
data = api(ip, "/control/clients")
|
||||
c = None
|
||||
for cand in data.get("clients", []):
|
||||
if ip_addr in cand.get("ids", []):
|
||||
c = cand; break
|
||||
if not c:
|
||||
sys.exit(f"{ip}: kein Client mit id exakt {ip_addr} — für Gruppen die CIDR angeben")
|
||||
c = dict(c)
|
||||
c["use_global_settings"] = enabled
|
||||
c["filtering_enabled"] = enabled
|
||||
api(ip, "/control/clients/update", "POST", {"name": c["name"], "data": c})
|
||||
print(f"{ip}: {c['name']} filtering={'an' if enabled else 'AUS'}")
|
||||
|
||||
|
||||
def status():
|
||||
for ip in INST:
|
||||
st = api(ip, "/control/filtering/status")
|
||||
allows = [r for r in st.get("user_rules", []) if r.startswith("@@")]
|
||||
cl = api(ip, "/control/clients").get("clients", [])
|
||||
print(f"== {ip} == allow-rules={allows or '—'}")
|
||||
for c in cl:
|
||||
print(f" {c['name']:16} ids={c['ids']} global={c['use_global_settings']} filt={c['filtering_enabled']}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
a = sys.argv[1:]
|
||||
if not a: sys.exit(__doc__)
|
||||
cmd = a[0]
|
||||
if cmd == "allow-domain": allow(a[1])
|
||||
elif cmd == "unallow-domain": allow(a[1], remove=True)
|
||||
elif cmd == "unfilter": set_filter(a[1], False)
|
||||
elif cmd == "refilter": set_filter(a[1], True)
|
||||
elif cmd == "status": status()
|
||||
else: sys.exit(f"unbekannt: {cmd}\n{__doc__}")
|
||||
113
adguard/agh-sync.py
Executable file
113
adguard/agh-sync.py
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
agh-sync.py — AdGuard-Home-Paar agh-bf1 (.36) / agh-bf2 (.37) synchron halten.
|
||||
|
||||
TP23 Stufe 2/4: die beiden AGH-Instanzen (pve LXC 110/111) haben KEIN natives HA →
|
||||
Config-Sync ist Betriebsaufwand. Dieses Werkzeug ist der Sync.
|
||||
|
||||
SSoT = adguard/AdGuardHome.yaml (Passwort-Hashes REDIGIERT — keine Secrets im Git).
|
||||
Wahrheit im Datenpfad = die beiden Live-Instanzen; die Invariante ist .36 == .37
|
||||
(AGH normalisiert die YAML beim Restart, daher NICHT gegen die Repo-Datei vergleichen,
|
||||
sondern die beiden Live-Configs gegeneinander).
|
||||
|
||||
check pull .36 + .37, Passwörter redigiert diffen → meldet Drift (exit 1 bei Drift)
|
||||
push Repo-SSoT nehmen, echte users-Hashes aus .36 (live) reinjizieren, validieren,
|
||||
auf beide pushen, GESTAFFELT neu starten (110 → prüfen → 111), .36==.37 + API prüfen
|
||||
|
||||
Kein Direkt-`sshpass -p` (Leak). SSH-Key zu root@pve vorausgesetzt.
|
||||
"""
|
||||
import subprocess, sys, tempfile, base64, os, re, pathlib, urllib.request
|
||||
|
||||
PVE = "root@10.40.20.100"
|
||||
INST = {"110": "10.40.20.36", "111": "10.40.20.37"} # ct-id -> ip
|
||||
PRIMARY = "110" # Reihenfolge: primary zuerst
|
||||
SVC = "AdGuardHome.service"
|
||||
CFG = "/opt/AdGuardHome/AdGuardHome.yaml"
|
||||
REPO = pathlib.Path(__file__).resolve().parent
|
||||
SSOT = REPO / "AdGuardHome.yaml"
|
||||
PW_RE = re.compile(r"^( password: ).*$")
|
||||
|
||||
|
||||
def sh(*args, inp=None):
|
||||
return subprocess.run(args, input=inp, capture_output=True, text=True)
|
||||
|
||||
|
||||
def pull(ct):
|
||||
r = sh("ssh", "-o", "ConnectTimeout=8", PVE, f"pct exec {ct} -- cat {CFG}")
|
||||
if r.returncode:
|
||||
sys.exit(f"pull {ct} fehlgeschlagen: {r.stderr.strip()}")
|
||||
return r.stdout
|
||||
|
||||
|
||||
def redact(text):
|
||||
return "\n".join(PW_RE.sub(r"\1'<redacted>'", l) for l in text.splitlines())
|
||||
|
||||
|
||||
def live_users_hashes(ct):
|
||||
"""echte password-Zeilen (in Reihenfolge) aus der Live-Config von ct."""
|
||||
out, inusers = [], False
|
||||
for l in pull(ct).splitlines():
|
||||
if l.startswith("users:"): inusers = True; continue
|
||||
if inusers and l and not l.startswith((" ", "\t")): break
|
||||
if inusers:
|
||||
m = PW_RE.match(l)
|
||||
if m: out.append(l)
|
||||
return out
|
||||
|
||||
|
||||
def cmd_check():
|
||||
a, b = redact(pull("110")), redact(pull("111"))
|
||||
if a == b:
|
||||
print("✅ .36 == .37 (synchron)")
|
||||
return 0
|
||||
print("🔴 DRIFT zwischen .36 und .37:")
|
||||
import difflib
|
||||
for line in difflib.unified_diff(a.splitlines(), b.splitlines(),
|
||||
".36", ".37", lineterm=""):
|
||||
print(line)
|
||||
return 1
|
||||
|
||||
|
||||
def cmd_push():
|
||||
if not SSOT.exists():
|
||||
sys.exit(f"SSoT fehlt: {SSOT}")
|
||||
ssot = SSOT.read_text()
|
||||
# echte Hashes aus dem primary reinjizieren (SSoT trägt nur Redaktions-Platzhalter)
|
||||
hashes = live_users_hashes(PRIMARY)
|
||||
red = [i for i, l in enumerate(ssot.splitlines()) if PW_RE.match(l)]
|
||||
if len(red) != len(hashes):
|
||||
sys.exit(f"users-Anzahl SSoT({len(red)}) != live({len(hashes)}) — manuell prüfen")
|
||||
lines = ssot.splitlines()
|
||||
for idx, real in zip(red, hashes):
|
||||
lines[idx] = real
|
||||
merged = "\n".join(lines) + "\n"
|
||||
# validieren
|
||||
try:
|
||||
import yaml
|
||||
doc = yaml.safe_load(merged)
|
||||
assert doc["users"] and doc["clients"]["persistent"]
|
||||
except Exception as e:
|
||||
sys.exit(f"merge invalide: {e}")
|
||||
b64 = base64.b64encode(merged.encode()).decode()
|
||||
order = [PRIMARY] + [c for c in INST if c != PRIMARY]
|
||||
for ct in order:
|
||||
print(f"→ push + restart {ct} ({INST[ct]}) …")
|
||||
r = sh("ssh", "-o", "ConnectTimeout=10", PVE,
|
||||
f"pct exec {ct} -- sh -c 'base64 -d > {CFG}.new && "
|
||||
f"cp -a {CFG} {CFG}.presync && mv {CFG}.new {CFG} && "
|
||||
f"systemctl restart {SVC} && sleep 2 && systemctl is-active {SVC}'",
|
||||
inp=b64)
|
||||
if r.returncode or "active" not in r.stdout:
|
||||
sys.exit(f"push {ct} fehlgeschlagen: {r.stdout} {r.stderr}")
|
||||
print(f" {ct} active")
|
||||
print(cmd_check_msg())
|
||||
return cmd_check()
|
||||
|
||||
|
||||
def cmd_check_msg():
|
||||
return "— Verifikation:"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmd = sys.argv[1] if len(sys.argv) > 1 else "check"
|
||||
sys.exit({"check": cmd_check, "push": cmd_push}.get(cmd, cmd_check)())
|
||||
63
adguard/ha-self-service.md
Normal file
63
adguard/ha-self-service.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# TP23 Stufe 5 — HA-Self-Service für DNS-Ausnahmen
|
||||
|
||||
Home Assistant (HAOS-VM 100, `10.40.20.105`) gibt eine Ein-Klick-Oberfläche, um eine Domain
|
||||
temporär (JIT) über das AGH-Paar `.36`/`.37` zu entsperren. Ablauf/Revert nativ per `timer`.
|
||||
|
||||
**Warum kein `rest_command`:** die AGH-Endpunkte sind read-modify-write (`set_rules` ersetzt die
|
||||
ganze Liste). HA ruft deshalb die deployte RMW-CLI `agh-exception.py` per `shell_command`.
|
||||
|
||||
## Bausteine (alle in HA .storage, via ha-mcp angelegt — keine YAML außer shell_command)
|
||||
| Typ | entity_id | Zweck |
|
||||
|---|---|---|
|
||||
| input_text | `input_text.dns_ausnahme_domain` | einzugebende Domain |
|
||||
| input_text | `input_text.dns_ausnahme_aktiv` | aktuell aktive Ausnahme (für leak-freien Revert; init `""`) |
|
||||
| input_select | `input_select.dns_ausnahme_dauer` | 15 Minuten / 1 Stunde / 4 Stunden |
|
||||
| timer | `timer.dns_ausnahme` | JIT-Countdown (restore=false) |
|
||||
| input_button | `input_button.dns_ausnahme_starten` | Auslöser |
|
||||
| automation | `automation.dns_ausnahme_starten` | Button → validieren, alte Ausnahme aufräumen, `agh_allow_domain`, Timer starten |
|
||||
| automation | `automation.dns_ausnahme_ablauf` | `timer.finished`/`timer.cancelled` → `agh_unallow_domain`, `_aktiv` leeren |
|
||||
|
||||
## `configuration.yaml` (der einzige YAML-Teil, Backup `.bak-tp23-*`)
|
||||
```yaml
|
||||
shell_command:
|
||||
agh_allow_domain: "python3 /config/agh-exception.py allow-domain '{{ domain }}'"
|
||||
agh_unallow_domain: "python3 /config/agh-exception.py unallow-domain '{{ domain }}'"
|
||||
agh_unfilter_client: "python3 /config/agh-exception.py unfilter '{{ ip }}'"
|
||||
agh_refilter_client: "python3 /config/agh-exception.py refilter '{{ ip }}'"
|
||||
```
|
||||
Neue Domain → **HA-Neustart** nötig (reload_all lädt eine erstmals hinzugefügte Domain nicht).
|
||||
|
||||
## Deploy auf HAOS (Zugang `ssh admin@10.40.20.105`, sudo passwortlos)
|
||||
- `/config/agh-exception.py` — Kopie von `adguard/agh-exception.py` (liest Creds via `/config/agh-exception.secrets`).
|
||||
- `/config/agh-exception.secrets` (chmod 600, root) — `AGH_AUTOMATION_USER`/`_PASS`.
|
||||
- Redeploy nach Script-Änderung: `base64 < adguard/agh-exception.py | ssh admin@10.40.20.105 "base64 -d | sudo tee /config/agh-exception.py >/dev/null"`.
|
||||
|
||||
## Bedienung
|
||||
Domain eintragen → Dauer wählen → **DNS-Ausnahme starten**. Bei Ablauf/Abbruch wird die Regel auf
|
||||
beiden AGH automatisch zurückgenommen. Ungültige Domains werden HA- **und** CLI-seitig abgelehnt.
|
||||
|
||||
## Dashboard (1. Draft, 2026-09-06)
|
||||
Eigenes storage-mode Dashboard `url_path: dns-ausnahmen` (Sidebar, `require_admin: false`),
|
||||
angelegt via `ha_config_set_dashboard`. Da es in HA-`.storage` lebt, hier die Repro-Quelle:
|
||||
```json
|
||||
{"views":[{"title":"DNS-Ausnahmen","path":"dns","type":"sections","icon":"mdi:dns","max_columns":2,"sections":[
|
||||
{"type":"grid","cards":[
|
||||
{"type":"heading","heading":"Domain temporaer freigeben","icon":"mdi:lock-open-variant"},
|
||||
{"type":"entities","entities":[{"entity":"input_text.dns_ausnahme_domain","name":"Domain"},{"entity":"input_select.dns_ausnahme_dauer","name":"Dauer"}]},
|
||||
{"type":"button","name":"DNS-Ausnahme starten","icon":"mdi:lock-open-check","tap_action":{"action":"perform-action","perform_action":"input_button.press","target":{"entity_id":"input_button.dns_ausnahme_starten"}},"grid_options":{"columns":"full"}}]},
|
||||
{"type":"grid","cards":[
|
||||
{"type":"heading","heading":"Status","icon":"mdi:information-outline"},
|
||||
{"type":"tile","entity":"timer.dns_ausnahme","name":"Restlaufzeit"},
|
||||
{"type":"tile","entity":"input_text.dns_ausnahme_aktiv","name":"Aktive Ausnahme"},
|
||||
{"type":"markdown","content":"**AGH-Resolver-Paar** — .36: {{ states('binary_sensor.adguard_bf1_status') }} / .37: {{ states('binary_sensor.adguard_bf2_status') }}"}]},
|
||||
{"type":"grid","cards":[
|
||||
{"type":"heading","heading":"VLAN-Filter-Policy (AGH-Gruppen)","heading_style":"subtitle"},
|
||||
{"type":"markdown","content":"MAIN/IOT/UNTRUSTED=an · INFRA/MEDIA/MGMT=aus · GUEST=an+SafeSearch/Parental · dns-bypass-exempt=aus"}]}
|
||||
]}]}
|
||||
```
|
||||
⚠️ Draft-Notiz: `binary_sensor.adguard_bf1_status` ist stale (hing am alten `.16`-Container, TP42) —
|
||||
zeigt evtl. `unavailable`, obwohl `.36` läuft. Sensor-Quelle gehört bei Gelegenheit auf `.36` gefixt.
|
||||
|
||||
## Verifiziert (2026-09-04)
|
||||
Button → `@@||doubleclick.net^` auf `.36`+`.37`, Timer 15:00, `_aktiv` gesetzt; Timer-Abbruch →
|
||||
Regel auf beiden entfernt, `_aktiv` geleert, `.36==.37`.
|
||||
218
bin/gitea-tp-sync.py
Normal file
218
bin/gitea-tp-sync.py
Normal file
@@ -0,0 +1,218 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
TP36 (reframed) — teilprojekte.md Index/Status → Gitea Issues (admin/bf-infra).
|
||||
|
||||
Idempotenter Sync (get-or-create, Match ueber "TPnn" im Titel):
|
||||
- Archiv-Header in docs/teilprojekte-archiv.md -> closed Issues (nur TPs, die in Gitea
|
||||
NICHT offen sind; ein reopentes TP mit Archiv-Zeiger bleibt offen).
|
||||
- Labels status:* (Marker) + thema:* (Gruppierung) werden vorab get-or-create.
|
||||
|
||||
SSoT-Modell (seit TP36-Cutover 2026-09-07): Gitea fuehrt Index+Status — aktive TPs werden
|
||||
DIREKT als Gitea-Issue angelegt/gepflegt, NICHT mehr aus einer Datei-Tabelle abgeleitet
|
||||
(die Quick-Index-Tabelle wurde aus teilprojekte.md entfernt). Dieses Werkzeug haelt nur noch
|
||||
die ARCHIVIERTEN (closed) TPs mit teilprojekte-archiv.md idempotent abgeglichen und fasst
|
||||
offene Issues nie an. Die per-TP-Prosa bleibt in docs/teilprojekte.md / teilprojekte-archiv.md.
|
||||
Token: ~/.hermes/.env (GITEA_ACCESS_TOKEN, GITEA_HOST) — wird NIE ausgegeben.
|
||||
|
||||
Aufruf:
|
||||
python3 bin/gitea-tp-sync.py # Dry-Run (default) — zeigt, was passieren wuerde
|
||||
python3 bin/gitea-tp-sync.py --commit # legt Labels + Issues an / gleicht sie ab
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parent.parent
|
||||
ACTIVE = REPO / "docs" / "teilprojekte.md"
|
||||
ARCHIV = REPO / "docs" / "teilprojekte-archiv.md"
|
||||
HERMES = Path.home() / ".hermes" / ".env"
|
||||
OWNER_REPO = "admin/bf-infra"
|
||||
COMMIT = "--commit" in sys.argv
|
||||
|
||||
# Marker -> (status-label, gitea-state)
|
||||
MARKER = {
|
||||
"🔜": ("status:todo", "open"),
|
||||
"⏳": ("status:wip", "open"),
|
||||
"⏸️": ("status:paused", "open"),
|
||||
"💡": ("status:idea", "open"),
|
||||
"🟢": ("status:concept", "open"),
|
||||
"✅": ("status:done", "closed"),
|
||||
"❌": ("status:dropped", "closed"),
|
||||
}
|
||||
LABEL_COLORS = {
|
||||
"status:todo": "#ededed", "status:wip": "#fbca04", "status:paused": "#c5def5",
|
||||
"status:idea": "#d4c5f9", "status:concept": "#bfdadc", "status:done": "#0e8a16",
|
||||
"status:dropped": "#e11d21",
|
||||
"thema:firewall-dns": "#b60205", "thema:wlan": "#1d76db", "thema:cloudflare-proxy": "#f9a825",
|
||||
"thema:nautobot-doku": "#5319e7", "thema:infra": "#0e8a16", "thema:ipv6-matter": "#006b75",
|
||||
"thema:identity": "#e99695", "thema:backlog": "#cccccc",
|
||||
}
|
||||
# TP-Nummer -> Themen-Label (aus dem Statusbaum-Gruppierung; nur aktive TPs brauchen ein Board-Thema)
|
||||
THEME = {
|
||||
"5.1": "firewall-dns", "23": "firewall-dns",
|
||||
"25": "wlan", "28": "wlan", "13": "wlan", "17.1": "wlan", "17.3": "wlan",
|
||||
"16": "cloudflare-proxy", "16.2": "cloudflare-proxy", "16.3": "cloudflare-proxy",
|
||||
"31": "cloudflare-proxy", "41": "cloudflare-proxy", "14.4": "cloudflare-proxy",
|
||||
"42": "cloudflare-proxy", "43": "cloudflare-proxy", "44": "cloudflare-proxy",
|
||||
"32": "nautobot-doku", "34": "nautobot-doku", "35": "nautobot-doku",
|
||||
"36": "nautobot-doku", "37": "nautobot-doku",
|
||||
"30": "infra", "40": "infra", "20.1": "infra", "18": "infra",
|
||||
"24": "infra", "38": "infra", "11": "infra",
|
||||
"12": "ipv6-matter", "12.1": "ipv6-matter",
|
||||
"8": "identity",
|
||||
"29": "backlog", "33": "backlog",
|
||||
}
|
||||
|
||||
|
||||
def hermes_env():
|
||||
tok = host = None
|
||||
for line in HERMES.read_text().splitlines():
|
||||
m = re.match(r"\s*(GITEA_ACCESS_TOKEN|GITEA_HOST)\s*=\s*(.+?)\s*$", line)
|
||||
if not m:
|
||||
continue
|
||||
if m.group(1) == "GITEA_ACCESS_TOKEN":
|
||||
tok = m.group(2).strip().strip('"').strip("'")
|
||||
else:
|
||||
host = m.group(2).strip().strip('"').strip("'")
|
||||
if not tok:
|
||||
sys.exit("GITEA_ACCESS_TOKEN nicht in %s gefunden." % HERMES)
|
||||
host = (host or "https://gitea.emsenhuber.net").rstrip("/")
|
||||
if not host.startswith("http"):
|
||||
host = "https://" + host
|
||||
return tok, host
|
||||
|
||||
|
||||
TOKEN, HOST = hermes_env()
|
||||
API = HOST + "/api/v1"
|
||||
|
||||
|
||||
def api(method, path, body=None):
|
||||
url = API + path
|
||||
data = json.dumps(body).encode() if body is not None else None
|
||||
req = urllib.request.Request(url, data=data, method=method, headers={
|
||||
"Authorization": "token " + TOKEN,
|
||||
"Accept": "application/json", "Content-Type": "application/json"})
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=30) as r:
|
||||
return r.status, json.load(r)
|
||||
except urllib.error.HTTPError as e:
|
||||
return e.code, (json.load(e) if e.headers.get("content-type", "").startswith("application/json") else {})
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- parse
|
||||
def parse_archiv(exclude_nums):
|
||||
"""Archiv-Header -> archivierte TPs. exclude_nums = TP-Nummern, die in Gitea OFFEN sind
|
||||
(reopente TPs mit Archiv-Zeiger) -> die bleiben offen, nicht als closed abgleichen."""
|
||||
out = []
|
||||
hdr = re.compile(r"^#{2,4}\s*(TP[\d.\-A-Za-z]+)\s*—\s*(.+?)\s*▸", )
|
||||
seen = set()
|
||||
for line in ARCHIV.read_text().splitlines():
|
||||
m = hdr.match(line)
|
||||
if not m:
|
||||
continue
|
||||
tp, title = m.groups()
|
||||
num = tp[2:]
|
||||
if num in exclude_nums or num in seen:
|
||||
continue
|
||||
seen.add(num)
|
||||
short = re.sub(r"\*\*|`", "", title).strip()[:80]
|
||||
out.append({"tp": tp, "num": num, "marker": "✅",
|
||||
"title": short, "date": "", "src": "archiv"})
|
||||
return out
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- gitea sync
|
||||
def ensure_labels(existing):
|
||||
by_name = {l["name"]: l for l in existing}
|
||||
for name, color in LABEL_COLORS.items():
|
||||
if name in by_name:
|
||||
continue
|
||||
if COMMIT:
|
||||
api("POST", f"/repos/{OWNER_REPO}/labels",
|
||||
{"name": name, "color": color.lstrip("#")})
|
||||
print(f" [{'+' if COMMIT else 'DRY'}] label {name}")
|
||||
st, cur = api("GET", f"/repos/{OWNER_REPO}/labels?limit=100")
|
||||
return {l["name"]: l["id"] for l in (cur if isinstance(cur, list) else [])}
|
||||
|
||||
|
||||
def all_issues():
|
||||
out, page = [], 1
|
||||
while True:
|
||||
st, d = api("GET", f"/repos/{OWNER_REPO}/issues?state=all&type=issues&limit=50&page={page}")
|
||||
if not isinstance(d, list) or not d:
|
||||
break
|
||||
out += d
|
||||
page += 1
|
||||
return out
|
||||
|
||||
|
||||
def main():
|
||||
print(f"Gitea {HOST} repo {OWNER_REPO} mode={'COMMIT' if COMMIT else 'DRY-RUN'}")
|
||||
|
||||
st, existing_labels = api("GET", f"/repos/{OWNER_REPO}/labels?limit=100")
|
||||
label_id = ensure_labels(existing_labels if isinstance(existing_labels, list) else [])
|
||||
|
||||
issues = all_issues()
|
||||
by_tp = {}
|
||||
open_nums = set()
|
||||
for iss in issues:
|
||||
# Titel ist "TPxx — …"; volle ID inkl. Buchstaben/Bindestrich (TP14.2a, TP-R) bis zum " — "
|
||||
m = re.match(r"^(TP[\w.\-]*?)\s+—", iss["title"])
|
||||
if m:
|
||||
by_tp[m.group(1)] = iss
|
||||
if iss.get("state") == "open":
|
||||
open_nums.add(m.group(1)[2:])
|
||||
|
||||
# Aktive TPs sind seit dem TP36-Cutover SSoT direkt in Gitea -> nur das Archiv abgleichen,
|
||||
# und offene (reopente) TPs davon ausschliessen, damit sie nicht faelschlich geschlossen werden.
|
||||
items = parse_archiv(open_nums)
|
||||
print(f"Geparst: {len(items)} archivierte TP (aktive TPs = SSoT in Gitea: "
|
||||
f"{len(open_nums)} offen, nicht angetastet)\n")
|
||||
|
||||
created = updated = 0
|
||||
for it in items:
|
||||
status_label, state = MARKER.get(it["marker"], ("status:todo", "open"))
|
||||
labels = [status_label]
|
||||
th = THEME.get(it["num"])
|
||||
if th:
|
||||
labels.append(f"thema:{th}")
|
||||
title = f"{it['tp']} — {it['title']}"
|
||||
body = (f"Steuerungs-SSoT: Index/Status hier in Gitea; **Prosa/Detail** im Repo unter "
|
||||
f"`docs/{'teilprojekte-archiv.md' if it['src']=='archiv' else 'teilprojekte.md'}` "
|
||||
f"(Abschnitt `{it['tp']}`).\n\n"
|
||||
f"- Status: {it['marker']} ({status_label})\n"
|
||||
+ (f"- Abschluss: {it['date']}\n" if it["date"] else ""))
|
||||
want_ids = [label_id[l] for l in labels if l in label_id]
|
||||
|
||||
cur = by_tp.get(it["tp"])
|
||||
if cur is None:
|
||||
print(f" [{'+' if COMMIT else 'DRY'}] NEW {title} {labels} state={state}")
|
||||
if COMMIT:
|
||||
sc, res = api("POST", f"/repos/{OWNER_REPO}/issues",
|
||||
{"title": title, "body": body, "labels": want_ids})
|
||||
if state == "closed" and isinstance(res, dict) and res.get("number"):
|
||||
api("PATCH", f"/repos/{OWNER_REPO}/issues/{res['number']}", {"state": "closed"})
|
||||
created += 1
|
||||
else:
|
||||
have = {l["name"] for l in cur.get("labels", [])}
|
||||
drift = (have != set(labels)) or (cur.get("state") != state)
|
||||
if drift:
|
||||
print(f" [{'~' if COMMIT else 'DRY'}] UPD #{cur['number']} {title} "
|
||||
f"{sorted(have)}->{labels} state {cur.get('state')}->{state}")
|
||||
if COMMIT:
|
||||
api("PATCH", f"/repos/{OWNER_REPO}/issues/{cur['number']}",
|
||||
{"labels": want_ids, "state": state})
|
||||
updated += 1
|
||||
|
||||
print(f"\n{'Angelegt' if COMMIT else 'Wuerde anlegen'}: {created} · "
|
||||
f"{'Abgeglichen' if COMMIT else 'Wuerde abgleichen'}: {updated}")
|
||||
if not COMMIT:
|
||||
print("Dry-Run — nichts geschrieben. Mit --commit ausfuehren.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -21,6 +21,13 @@
|
||||
# OEFFENTLICH (via Cloudflare Tunnel + Access; Clients ohne WARP)
|
||||
# =========================================================================
|
||||
vw.emsenhuber.net {
|
||||
# TP41 T2: /admin nur lokal/WARP-intern (kein CF-Header). Via CF (Header CF-Connecting-IP
|
||||
# gesetzt) -> 404 statt Vault-Admin. Ersetzt die frühere WAF-Edge-Regel (403).
|
||||
@cf_admin {
|
||||
header CF-Connecting-IP *
|
||||
path /admin /admin/*
|
||||
}
|
||||
respond @cf_admin 404
|
||||
reverse_proxy http://10.40.20.127
|
||||
}
|
||||
|
||||
@@ -39,7 +46,7 @@ gitea.emsenhuber.net {
|
||||
# =========================================================================
|
||||
# INTERN (Mesh/LAN; Split-Horizon zeigt diese Namen auf 10.40.20.40)
|
||||
# =========================================================================
|
||||
nautobot.emsenhuber.net, nautobot.bf.emsenhuber.net {
|
||||
nautobot.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.30:8080
|
||||
}
|
||||
|
||||
@@ -51,49 +58,49 @@ ds-bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.10:8080
|
||||
}
|
||||
|
||||
ccu.emsenhuber.net, ccu.bf.emsenhuber.net {
|
||||
ccu.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.232
|
||||
}
|
||||
|
||||
iobroker.emsenhuber.net, iobroker.bf.emsenhuber.net {
|
||||
iobroker.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.107:8081
|
||||
}
|
||||
|
||||
z2m25.emsenhuber.net, z2m25.bf.emsenhuber.net {
|
||||
z2m25.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.106:8080
|
||||
}
|
||||
|
||||
# --- MCP-Endpunkte: heute spricht ~/.claude.json diese IPs roh --------------
|
||||
pve-mcp.emsenhuber.net, pve-mcp.bf.emsenhuber.net {
|
||||
pve-mcp.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.173:3000
|
||||
}
|
||||
|
||||
ha-mcp.emsenhuber.net, ha-mcp.bf.emsenhuber.net {
|
||||
ha-mcp.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.105:9583
|
||||
}
|
||||
|
||||
n8n-mcp.emsenhuber.net, n8n-mcp.bf.emsenhuber.net {
|
||||
n8n-mcp.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.167:3001
|
||||
}
|
||||
|
||||
gitea-mcp.emsenhuber.net, gitea-mcp.bf.emsenhuber.net {
|
||||
gitea-mcp.bf.emsenhuber.net {
|
||||
reverse_proxy http://10.40.20.167:3000
|
||||
}
|
||||
|
||||
# --- HTTPS-Backends (Selbstsignat) -----------------------------------------
|
||||
pve.emsenhuber.net, pve.bf.emsenhuber.net {
|
||||
pve.bf.emsenhuber.net {
|
||||
reverse_proxy https://10.40.20.100:8006 {
|
||||
import selfsigned
|
||||
}
|
||||
}
|
||||
|
||||
portainer.emsenhuber.net, portainer.bf.emsenhuber.net {
|
||||
portainer.bf.emsenhuber.net {
|
||||
reverse_proxy https://10.40.20.126:9443 {
|
||||
import selfsigned
|
||||
}
|
||||
}
|
||||
|
||||
pbs.emsenhuber.net, pbs.bf.emsenhuber.net {
|
||||
pbs.bf.emsenhuber.net {
|
||||
reverse_proxy https://10.40.20.135:8007 {
|
||||
import selfsigned
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ def main():
|
||||
continue
|
||||
if host not in caddy:
|
||||
drift.append(f"NUR-CF {host:<32} {tun}: {svc} (in Caddy nicht vorhanden)")
|
||||
elif not svc.startswith(f"http://{CADDY_IP}"):
|
||||
elif not (svc.startswith(f"http://{CADDY_IP}") or svc.startswith(f"https://{CADDY_IP}")):
|
||||
drift.append(f"ABWEICHEND {host:<32} CF={svc} (zeigt nicht auf Caddy {CADDY_IP})")
|
||||
# Caddy-Sites ohne CF-Ingress: nur die suffixlosen Namen sind potenziell Drift.
|
||||
# *.bf.*-Namen sind bewusst intern (Split-Horizon) und brauchen keinen Ingress.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result": {
|
||||
"tunnel_id": "7a322261-380a-447b-97d2-8ebce99f5ed1",
|
||||
"version": 4,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{
|
||||
"service": "http://10.40.20.167:5678",
|
||||
"hostname": "n8n.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.167:3001",
|
||||
"hostname": "n8n-mcp.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.167:3000",
|
||||
"hostname": "gitea-mcp.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "ssh://10.40.20.167:22",
|
||||
"hostname": "82unkpb5.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "https://10.40.20.135:8007",
|
||||
"hostname": "pbs.emsenhuber.net",
|
||||
"originRequest": {
|
||||
"noTLSVerify": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"service": "http_status:404"
|
||||
}
|
||||
],
|
||||
"warp-routing": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"source": "cloudflare",
|
||||
"created_at": "2026-07-27T13:53:23.512528Z"
|
||||
}
|
||||
}
|
||||
@@ -1 +1,20 @@
|
||||
{"success":true,"errors":[],"messages":[],"result":{"tunnel_id":"7a322261-380a-447b-97d2-8ebce99f5ed1","version":4,"config":{"ingress":[{"service":"http://10.40.20.167:5678","hostname":"n8n.emsenhuber.net"},{"service":"http://10.40.20.167:3001","hostname":"n8n-mcp.emsenhuber.net"},{"service":"http://10.40.20.167:3000","hostname":"gitea-mcp.emsenhuber.net"},{"service":"ssh://10.40.20.167:22","hostname":"82unkpb5.emsenhuber.net"},{"service":"https://10.40.20.135:8007","hostname":"pbs.emsenhuber.net","originRequest":{"noTLSVerify":true}},{"service":"http_status:404"}],"warp-routing":{"enabled":false}},"source":"cloudflare","created_at":"2026-07-27T13:53:23.512528Z"}}
|
||||
{
|
||||
"tunnel_id": "7a322261-380a-447b-97d2-8ebce99f5ed1",
|
||||
"version": 6,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{
|
||||
"service": "http://10.40.20.167:5678",
|
||||
"hostname": "n8n.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http_status:404"
|
||||
}
|
||||
],
|
||||
"warp-routing": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"source": "cloudflare",
|
||||
"created_at": "2026-08-30T10:19:30.297725Z"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result": {
|
||||
"tunnel_id": "220c9958-401b-4111-9451-f3db09bba2d5",
|
||||
"version": 6,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{
|
||||
"service": "http://10.40.20.157:3000",
|
||||
"hostname": "gitea.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.173:3000",
|
||||
"hostname": "pve-mcp.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.127",
|
||||
"hostname": "vw.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.10:8080",
|
||||
"hostname": "ds-bf.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "ssh://10.40.20.10:22",
|
||||
"hostname": "3k23uow7.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http_status:404"
|
||||
}
|
||||
],
|
||||
"warp-routing": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"source": "cloudflare",
|
||||
"created_at": "2026-08-29T17:30:22.531419Z"
|
||||
}
|
||||
}
|
||||
@@ -1 +1,24 @@
|
||||
{"success":true,"errors":[],"messages":[],"result":{"tunnel_id":"220c9958-401b-4111-9451-f3db09bba2d5","version":6,"config":{"ingress":[{"service":"http://10.40.20.157:3000","hostname":"gitea.emsenhuber.net"},{"service":"http://10.40.20.173:3000","hostname":"pve-mcp.emsenhuber.net"},{"service":"http://10.40.20.127","hostname":"vw.emsenhuber.net"},{"service":"http://10.40.20.10:8080","hostname":"ds-bf.emsenhuber.net"},{"service":"ssh://10.40.20.10:22","hostname":"3k23uow7.emsenhuber.net"},{"service":"http_status:404"}],"warp-routing":{"enabled":true}},"source":"cloudflare","created_at":"2026-08-29T17:30:22.531419Z"}}
|
||||
{
|
||||
"tunnel_id": "220c9958-401b-4111-9451-f3db09bba2d5",
|
||||
"version": 7,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{
|
||||
"service": "http://10.40.20.157:3000",
|
||||
"hostname": "gitea.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.127",
|
||||
"hostname": "vw.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http_status:404"
|
||||
}
|
||||
],
|
||||
"warp-routing": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"source": "cloudflare",
|
||||
"created_at": "2026-08-30T08:50:21.241084Z"
|
||||
}
|
||||
|
||||
@@ -1 +1,44 @@
|
||||
{"success":true,"errors":[],"messages":[],"result":{"tunnel_id":"48d3b0b6-7233-4781-a76a-1de4a5e957ce","version":2,"config":{"ingress":[{"service":"http://10.40.20.40:80","hostname":"vw.emsenhuber.net","originRequest":{"noTLSVerify":true}},{"service":"http://10.40.20.40:80","hostname":"hass.emsenhuber.net","originRequest":{"noTLSVerify":true}},{"service":"http://10.40.20.40:80","hostname":"n8n.emsenhuber.net","originRequest":{"noTLSVerify":true}},{"service":"http://10.40.20.40:80","hostname":"gitea.emsenhuber.net","originRequest":{"noTLSVerify":true}},{"service":"http_status:404"}],"warp-routing":{"enabled":false}},"source":"cloudflare","created_at":"2026-08-27T05:45:54.534390Z"}}
|
||||
{
|
||||
"tunnel_id": "48d3b0b6-7233-4781-a76a-1de4a5e957ce",
|
||||
"version": 2,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{
|
||||
"service": "http://10.40.20.40:80",
|
||||
"hostname": "vw.emsenhuber.net",
|
||||
"originRequest": {
|
||||
"noTLSVerify": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.40:80",
|
||||
"hostname": "hass.emsenhuber.net",
|
||||
"originRequest": {
|
||||
"noTLSVerify": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.40:80",
|
||||
"hostname": "n8n.emsenhuber.net",
|
||||
"originRequest": {
|
||||
"noTLSVerify": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.40:80",
|
||||
"hostname": "gitea.emsenhuber.net",
|
||||
"originRequest": {
|
||||
"noTLSVerify": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"service": "http_status:404"
|
||||
}
|
||||
],
|
||||
"warp-routing": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"source": "cloudflare",
|
||||
"created_at": "2026-08-27T05:45:54.534390Z"
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"success":true,"errors":[],"messages":[],"result":{"tunnel_id":"48d3b0b6-7233-4781-a76a-1de4a5e957ce","version":3,"config":{"ingress":[{"service":"https://10.40.20.40:443","hostname":"vw.emsenhuber.net","originRequest":{"originServerName":"vw.emsenhuber.net"}},{"service":"https://10.40.20.40:443","hostname":"hass.emsenhuber.net","originRequest":{"originServerName":"hass.emsenhuber.net"}},{"service":"https://10.40.20.40:443","hostname":"n8n.emsenhuber.net","originRequest":{"originServerName":"n8n.emsenhuber.net"}},{"service":"https://10.40.20.40:443","hostname":"gitea.emsenhuber.net","originRequest":{"originServerName":"gitea.emsenhuber.net"}},{"service":"http_status:404"}],"warp-routing":{"enabled":false}},"source":"cloudflare","created_at":"2026-08-31T05:56:47.739644Z"}}
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result": {
|
||||
"tunnel_id": "f7fdf3a6-b67d-4567-93b1-b0f273794d09",
|
||||
"version": 3,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{
|
||||
"service": "https://10.40.20.100:8006",
|
||||
"hostname": "pve.emsenhuber.net",
|
||||
"originRequest": {
|
||||
"noTLSVerify": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"service": "ssh://10.40.20.100:22",
|
||||
"hostname": "j44d6tua.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.232",
|
||||
"hostname": "ccu.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.107:8081",
|
||||
"hostname": "iobroker.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.106:8080",
|
||||
"hostname": "z2m25.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "https://10.40.20.126:9443",
|
||||
"hostname": "portainer.emsenhuber.net",
|
||||
"originRequest": {
|
||||
"noTLSVerify": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.105:8123",
|
||||
"hostname": "hass.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http://10.40.20.105:9583",
|
||||
"hostname": "ha-mcp.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http_status:404"
|
||||
}
|
||||
],
|
||||
"warp-routing": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"source": "cloudflare",
|
||||
"created_at": "2026-07-16T11:36:24.193655Z"
|
||||
}
|
||||
}
|
||||
@@ -1 +1,20 @@
|
||||
{"success":true,"errors":[],"messages":[],"result":{"tunnel_id":"f7fdf3a6-b67d-4567-93b1-b0f273794d09","version":3,"config":{"ingress":[{"service":"https://10.40.20.100:8006","hostname":"pve.emsenhuber.net","originRequest":{"noTLSVerify":true}},{"service":"ssh://10.40.20.100:22","hostname":"j44d6tua.emsenhuber.net"},{"service":"http://10.40.20.232","hostname":"ccu.emsenhuber.net"},{"service":"http://10.40.20.107:8081","hostname":"iobroker.emsenhuber.net"},{"service":"http://10.40.20.106:8080","hostname":"z2m25.emsenhuber.net"},{"service":"https://10.40.20.126:9443","hostname":"portainer.emsenhuber.net","originRequest":{"noTLSVerify":true}},{"service":"http://10.40.20.105:8123","hostname":"hass.emsenhuber.net"},{"service":"http://10.40.20.105:9583","hostname":"ha-mcp.emsenhuber.net"},{"service":"http_status:404"}],"warp-routing":{"enabled":true}},"source":"cloudflare","created_at":"2026-07-16T11:36:24.193655Z"}}
|
||||
{
|
||||
"tunnel_id": "f7fdf3a6-b67d-4567-93b1-b0f273794d09",
|
||||
"version": 4,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{
|
||||
"service": "http://10.40.20.105:8123",
|
||||
"hostname": "hass.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"service": "http_status:404"
|
||||
}
|
||||
],
|
||||
"warp-routing": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"source": "cloudflare",
|
||||
"created_at": "2026-08-30T08:50:25.151983Z"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
[
|
||||
{
|
||||
"name": "ds-fm.emsenhuber.net",
|
||||
"type": "CNAME",
|
||||
"content": "b697d124-53bf-4a33-8fcf-384cced4db1a.cfargotunnel.com",
|
||||
"proxied": true,
|
||||
"id": "0da61c6143bfd0d5f9c47ca4b4147b06"
|
||||
},
|
||||
{
|
||||
"name": "gateway-fm.emsenhuber.net",
|
||||
"type": "CNAME",
|
||||
"content": "b697d124-53bf-4a33-8fcf-384cced4db1a.cfargotunnel.com",
|
||||
"proxied": true,
|
||||
"id": "54ac8b816765b45191469678891389bd"
|
||||
},
|
||||
{
|
||||
"name": "gitea.emsenhuber.net",
|
||||
"type": "CNAME",
|
||||
"content": "220c9958-401b-4111-9451-f3db09bba2d5.cfargotunnel.com",
|
||||
"proxied": true,
|
||||
"id": "3d6053529f99fc5832d9956ee6e8834c"
|
||||
},
|
||||
{
|
||||
"name": "hass.emsenhuber.net",
|
||||
"type": "CNAME",
|
||||
"content": "f7fdf3a6-b67d-4567-93b1-b0f273794d09.cfargotunnel.com",
|
||||
"proxied": true,
|
||||
"id": "0841148f401b5db40fa02f69d0f0e848"
|
||||
},
|
||||
{
|
||||
"name": "n8n.emsenhuber.net",
|
||||
"type": "CNAME",
|
||||
"content": "7a322261-380a-447b-97d2-8ebce99f5ed1.cfargotunnel.com",
|
||||
"proxied": true,
|
||||
"id": "40b311a40e41fbeae85ca097a4036e6c"
|
||||
},
|
||||
{
|
||||
"name": "vw.emsenhuber.net",
|
||||
"type": "CNAME",
|
||||
"content": "220c9958-401b-4111-9451-f3db09bba2d5.cfargotunnel.com",
|
||||
"proxied": true,
|
||||
"id": "2971d3ba9410e841b35ec58ffda59be4"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
},
|
||||
{
|
||||
"created_at": "2026-05-09T06:45:22Z",
|
||||
"decision": "non_identity",
|
||||
"exclude": [],
|
||||
"id": "5165d139-8733-4d31-a3a5-f6f1d0fd8643",
|
||||
"include": [
|
||||
{
|
||||
"ip": {
|
||||
"ip": "90.146.33.177/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "bf4",
|
||||
"require": [],
|
||||
"uid": "5165d139-8733-4d31-a3a5-f6f1d0fd8643",
|
||||
"updated_at": "2026-08-07T21:36:42Z",
|
||||
"reusable": true,
|
||||
"precedence": 2
|
||||
},
|
||||
{
|
||||
"created_at": "2026-05-15T13:11:36Z",
|
||||
"decision": "non_identity",
|
||||
"exclude": [],
|
||||
"id": "39fe0e9d-6f63-414d-9d6d-440a7a151f5d",
|
||||
"include": [
|
||||
{
|
||||
"service_token": {
|
||||
"token_id": "65f1821a-f134-4e20-aa66-baf31daddbed"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "claude-mcp",
|
||||
"require": [],
|
||||
"uid": "39fe0e9d-6f63-414d-9d6d-440a7a151f5d",
|
||||
"updated_at": "2026-07-31T15:44:48Z",
|
||||
"reusable": true,
|
||||
"precedence": 3
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 200,
|
||||
"count": 3,
|
||||
"total_count": 3,
|
||||
"total_pages": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"result": {
|
||||
"id": "16aaec78-5951-4cf3-aad5-79f63163b5ea",
|
||||
"uid": "16aaec78-5951-4cf3-aad5-79f63163b5ea",
|
||||
"type": "self_hosted",
|
||||
"name": "*.emsenhuber.net",
|
||||
"aud": "d5bb8c4852895834a0010d6f63882f140cf27faf41f94374532c1f013a15c02d",
|
||||
"created_at": "2026-05-05T11:44:38Z",
|
||||
"updated_at": "2026-05-15T13:30:13Z",
|
||||
"domain": "*.emsenhuber.net",
|
||||
"self_hosted_domains": [
|
||||
"*.emsenhuber.net"
|
||||
],
|
||||
"destinations": [
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "*.emsenhuber.net"
|
||||
}
|
||||
],
|
||||
"app_launcher_visible": true,
|
||||
"allowed_idps": [],
|
||||
"tags": [],
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
},
|
||||
{
|
||||
"created_at": "2026-05-09T06:45:22Z",
|
||||
"decision": "non_identity",
|
||||
"exclude": [],
|
||||
"id": "5165d139-8733-4d31-a3a5-f6f1d0fd8643",
|
||||
"include": [
|
||||
{
|
||||
"ip": {
|
||||
"ip": "90.146.33.177/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "bf4",
|
||||
"require": [],
|
||||
"uid": "5165d139-8733-4d31-a3a5-f6f1d0fd8643",
|
||||
"updated_at": "2026-08-07T21:36:42Z",
|
||||
"reusable": true,
|
||||
"precedence": 2
|
||||
},
|
||||
{
|
||||
"created_at": "2026-05-15T13:11:36Z",
|
||||
"decision": "non_identity",
|
||||
"exclude": [],
|
||||
"id": "39fe0e9d-6f63-414d-9d6d-440a7a151f5d",
|
||||
"include": [
|
||||
{
|
||||
"service_token": {
|
||||
"token_id": "65f1821a-f134-4e20-aa66-baf31daddbed"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "claude-mcp",
|
||||
"require": [],
|
||||
"uid": "39fe0e9d-6f63-414d-9d6d-440a7a151f5d",
|
||||
"updated_at": "2026-07-31T15:44:48Z",
|
||||
"reusable": true,
|
||||
"precedence": 3
|
||||
}
|
||||
],
|
||||
"session_duration": "24h",
|
||||
"enable_binding_cookie": false,
|
||||
"http_only_cookie_attribute": false,
|
||||
"options_preflight_bypass": false,
|
||||
"oauth_configuration": {
|
||||
"enabled": false,
|
||||
"dynamic_client_registration": {
|
||||
"enabled": true,
|
||||
"allowed_uris": [
|
||||
"https://ha-mcp.emsenhuber.net"
|
||||
],
|
||||
"allow_any_on_localhost": true,
|
||||
"allow_any_on_loopback": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": []
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"created_at": "2026-06-13T08:34:00Z",
|
||||
"decision": "bypass",
|
||||
"exclude": [],
|
||||
"id": "a8129e37-d3c2-456d-8630-3c6a3449d3f2",
|
||||
"include": [
|
||||
{
|
||||
"everyone": {}
|
||||
}
|
||||
],
|
||||
"name": "bypass",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"uid": "a8129e37-d3c2-456d-8630-3c6a3449d3f2",
|
||||
"updated_at": "2026-06-13T08:48:05Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 200,
|
||||
"count": 1,
|
||||
"total_count": 1,
|
||||
"total_pages": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"result": {
|
||||
"id": "1dbc45ca-1376-4a0d-b608-69db58f1875c",
|
||||
"uid": "1dbc45ca-1376-4a0d-b608-69db58f1875c",
|
||||
"type": "self_hosted",
|
||||
"name": "hass, vw, gitea",
|
||||
"aud": "817b2b82d2b1aa9c12de854c7bce9f608b33721f0827cfded68bdc7c5eb92a46",
|
||||
"created_at": "2026-06-13T08:32:39Z",
|
||||
"updated_at": "2026-07-12T12:43:25Z",
|
||||
"domain": "vw.emsenhuber.net",
|
||||
"self_hosted_domains": [
|
||||
"vw.emsenhuber.net",
|
||||
"hass.emsenhuber.net",
|
||||
"gitea.emsenhuber.net"
|
||||
],
|
||||
"destinations": [
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "vw.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "hass.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "gitea.emsenhuber.net"
|
||||
}
|
||||
],
|
||||
"app_launcher_visible": true,
|
||||
"allowed_idps": [],
|
||||
"tags": [],
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-06-13T08:34:00Z",
|
||||
"decision": "bypass",
|
||||
"exclude": [],
|
||||
"id": "a8129e37-d3c2-456d-8630-3c6a3449d3f2",
|
||||
"include": [
|
||||
{
|
||||
"everyone": {}
|
||||
}
|
||||
],
|
||||
"name": "bypass",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"uid": "a8129e37-d3c2-456d-8630-3c6a3449d3f2",
|
||||
"updated_at": "2026-06-13T08:48:05Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"session_duration": "24h",
|
||||
"enable_binding_cookie": false,
|
||||
"http_only_cookie_attribute": true,
|
||||
"options_preflight_bypass": false
|
||||
},
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": []
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 200,
|
||||
"count": 1,
|
||||
"total_count": 1,
|
||||
"total_pages": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"result": {
|
||||
"id": "6c32fe23-24d8-433f-b00b-0a3d1558bb30",
|
||||
"uid": "6c32fe23-24d8-433f-b00b-0a3d1558bb30",
|
||||
"type": "warp",
|
||||
"name": "Warp Login App",
|
||||
"aud": "fdfaa967d4118469dc994257f65831caa0162d6c45a14b5205af45e1aeca723b",
|
||||
"created_at": "2026-06-04T18:48:59Z",
|
||||
"updated_at": "2026-06-06T16:53:32Z",
|
||||
"domain": "emsenhuber.cloudflareaccess.com/warp",
|
||||
"allowed_idps": [],
|
||||
"session_duration": "24h",
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"tags": []
|
||||
},
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": []
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 200,
|
||||
"count": 1,
|
||||
"total_count": 1,
|
||||
"total_pages": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"result": {
|
||||
"id": "6df5c431-adcf-4dde-805d-4eb22d7c19b4",
|
||||
"uid": "6df5c431-adcf-4dde-805d-4eb22d7c19b4",
|
||||
"type": "app_launcher",
|
||||
"name": "App Launcher",
|
||||
"aud": "015e805251579e50a49668775c2255facb5bc56007ce49f90885f4114584bae2",
|
||||
"created_at": "2026-03-28T16:20:27Z",
|
||||
"updated_at": "2026-07-08T11:56:56Z",
|
||||
"domain": "emsenhuber.cloudflareaccess.com",
|
||||
"allowed_idps": [],
|
||||
"session_duration": "730h",
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"landing_page_design": {},
|
||||
"skip_app_launcher_login_page": false
|
||||
},
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": []
|
||||
}
|
||||
449
docs/cf-backup/tp41-20260901/apps-all.json
Normal file
449
docs/cf-backup/tp41-20260901/apps-all.json
Normal file
@@ -0,0 +1,449 @@
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"id": "86287661-7b23-4f38-874c-926cab1c0535",
|
||||
"uid": "86287661-7b23-4f38-874c-926cab1c0535",
|
||||
"type": "self_hosted",
|
||||
"name": "Terpenfinder v3 assetlinks",
|
||||
"aud": "353385474c9665c498f2c2477b0236a14a363aff5a700017ee5def5792587c62",
|
||||
"created_at": "2026-07-31T07:50:12Z",
|
||||
"updated_at": "2026-07-31T07:50:12Z",
|
||||
"domain": "420.teilzeitladen.xyz/.well-known/assetlinks.json",
|
||||
"self_hosted_domains": [
|
||||
"420.teilzeitladen.xyz/.well-known/assetlinks.json"
|
||||
],
|
||||
"destinations": [
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "420.teilzeitladen.xyz/.well-known/assetlinks.json"
|
||||
}
|
||||
],
|
||||
"app_launcher_visible": false,
|
||||
"allowed_idps": [],
|
||||
"tags": [],
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-07-31T07:50:12Z",
|
||||
"decision": "bypass",
|
||||
"exclude": [],
|
||||
"id": "8f7c4929-376b-4e8f-b0cf-36fb4c686d69",
|
||||
"include": [
|
||||
{
|
||||
"everyone": {}
|
||||
}
|
||||
],
|
||||
"name": "public-bypass",
|
||||
"require": [],
|
||||
"uid": "8f7c4929-376b-4e8f-b0cf-36fb4c686d69",
|
||||
"updated_at": "2026-07-31T07:50:12Z",
|
||||
"reusable": false,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"session_duration": "730h",
|
||||
"enable_binding_cookie": false,
|
||||
"http_only_cookie_attribute": true,
|
||||
"options_preflight_bypass": false,
|
||||
"eager_redirect_cookie_setting": true
|
||||
},
|
||||
{
|
||||
"id": "e6a7991f-466c-4d1d-bac6-4b30fafccce4",
|
||||
"uid": "e6a7991f-466c-4d1d-bac6-4b30fafccce4",
|
||||
"type": "self_hosted",
|
||||
"name": "Terpenfinder v3",
|
||||
"aud": "e4515f7a7740558bf51ff6056e9c52fec25e67d23607209250a92e10cdf574e7",
|
||||
"created_at": "2026-06-22T20:47:31Z",
|
||||
"updated_at": "2026-07-31T07:50:10Z",
|
||||
"domain": "420.teilzeitladen.xyz",
|
||||
"self_hosted_domains": [
|
||||
"420.teilzeitladen.xyz"
|
||||
],
|
||||
"destinations": [
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "420.teilzeitladen.xyz"
|
||||
}
|
||||
],
|
||||
"app_launcher_visible": true,
|
||||
"allowed_idps": [],
|
||||
"tags": [],
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
},
|
||||
{
|
||||
"created_at": "2026-03-06T20:11:40Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "99839886-4ef1-4bad-8cc6-dc864d4dceeb",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "angelikahy@outlook.de"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ip": {
|
||||
"ip": "10.95.10.0/24"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ip": {
|
||||
"ip": "94.154.138.0/24"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "geli",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "99839886-4ef1-4bad-8cc6-dc864d4dceeb",
|
||||
"updated_at": "2026-07-31T07:27:53Z",
|
||||
"reusable": true,
|
||||
"precedence": 2
|
||||
},
|
||||
{
|
||||
"created_at": "2026-07-27T11:37:45Z",
|
||||
"decision": "non_identity",
|
||||
"exclude": [],
|
||||
"id": "bf7d2e5e-3a53-4af1-a64c-a0f0d00703dc",
|
||||
"include": [
|
||||
{
|
||||
"service_token": {
|
||||
"token_id": "1082bad1-6a25-4188-bf6b-220075679e0f"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "terpene-svc",
|
||||
"require": [],
|
||||
"uid": "bf7d2e5e-3a53-4af1-a64c-a0f0d00703dc",
|
||||
"updated_at": "2026-08-05T18:33:01Z",
|
||||
"reusable": true,
|
||||
"precedence": 3
|
||||
}
|
||||
],
|
||||
"session_duration": "730h",
|
||||
"enable_binding_cookie": false,
|
||||
"http_only_cookie_attribute": true,
|
||||
"options_preflight_bypass": false
|
||||
},
|
||||
{
|
||||
"id": "1dbc45ca-1376-4a0d-b608-69db58f1875c",
|
||||
"uid": "1dbc45ca-1376-4a0d-b608-69db58f1875c",
|
||||
"type": "self_hosted",
|
||||
"name": "hass, vw, gitea",
|
||||
"aud": "817b2b82d2b1aa9c12de854c7bce9f608b33721f0827cfded68bdc7c5eb92a46",
|
||||
"created_at": "2026-06-13T08:32:39Z",
|
||||
"updated_at": "2026-07-12T12:43:25Z",
|
||||
"domain": "vw.emsenhuber.net",
|
||||
"self_hosted_domains": [
|
||||
"vw.emsenhuber.net",
|
||||
"hass.emsenhuber.net",
|
||||
"gitea.emsenhuber.net"
|
||||
],
|
||||
"destinations": [
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "vw.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "hass.emsenhuber.net"
|
||||
},
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "gitea.emsenhuber.net"
|
||||
}
|
||||
],
|
||||
"app_launcher_visible": true,
|
||||
"allowed_idps": [],
|
||||
"tags": [],
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-06-13T08:34:00Z",
|
||||
"decision": "bypass",
|
||||
"exclude": [],
|
||||
"id": "a8129e37-d3c2-456d-8630-3c6a3449d3f2",
|
||||
"include": [
|
||||
{
|
||||
"everyone": {}
|
||||
}
|
||||
],
|
||||
"name": "bypass",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"uid": "a8129e37-d3c2-456d-8630-3c6a3449d3f2",
|
||||
"updated_at": "2026-06-13T08:48:05Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"session_duration": "24h",
|
||||
"enable_binding_cookie": false,
|
||||
"http_only_cookie_attribute": true,
|
||||
"options_preflight_bypass": false
|
||||
},
|
||||
{
|
||||
"id": "6df5c431-adcf-4dde-805d-4eb22d7c19b4",
|
||||
"uid": "6df5c431-adcf-4dde-805d-4eb22d7c19b4",
|
||||
"type": "app_launcher",
|
||||
"name": "App Launcher",
|
||||
"aud": "015e805251579e50a49668775c2255facb5bc56007ce49f90885f4114584bae2",
|
||||
"created_at": "2026-03-28T16:20:27Z",
|
||||
"updated_at": "2026-07-08T11:56:56Z",
|
||||
"domain": "emsenhuber.cloudflareaccess.com",
|
||||
"allowed_idps": [],
|
||||
"session_duration": "730h",
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"landing_page_design": {},
|
||||
"skip_app_launcher_login_page": false
|
||||
},
|
||||
{
|
||||
"id": "6c32fe23-24d8-433f-b00b-0a3d1558bb30",
|
||||
"uid": "6c32fe23-24d8-433f-b00b-0a3d1558bb30",
|
||||
"type": "warp",
|
||||
"name": "Warp Login App",
|
||||
"aud": "fdfaa967d4118469dc994257f65831caa0162d6c45a14b5205af45e1aeca723b",
|
||||
"created_at": "2026-06-04T18:48:59Z",
|
||||
"updated_at": "2026-06-06T16:53:32Z",
|
||||
"domain": "emsenhuber.cloudflareaccess.com/warp",
|
||||
"allowed_idps": [],
|
||||
"session_duration": "24h",
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
}
|
||||
],
|
||||
"tags": []
|
||||
},
|
||||
{
|
||||
"id": "16aaec78-5951-4cf3-aad5-79f63163b5ea",
|
||||
"uid": "16aaec78-5951-4cf3-aad5-79f63163b5ea",
|
||||
"type": "self_hosted",
|
||||
"name": "*.emsenhuber.net",
|
||||
"aud": "d5bb8c4852895834a0010d6f63882f140cf27faf41f94374532c1f013a15c02d",
|
||||
"created_at": "2026-05-05T11:44:38Z",
|
||||
"updated_at": "2026-05-15T13:30:13Z",
|
||||
"domain": "*.emsenhuber.net",
|
||||
"self_hosted_domains": [
|
||||
"*.emsenhuber.net"
|
||||
],
|
||||
"destinations": [
|
||||
{
|
||||
"type": "public",
|
||||
"uri": "*.emsenhuber.net"
|
||||
}
|
||||
],
|
||||
"app_launcher_visible": true,
|
||||
"allowed_idps": [],
|
||||
"tags": [],
|
||||
"auto_redirect_to_identity": false,
|
||||
"policies": [
|
||||
{
|
||||
"created_at": "2026-02-28T21:26:56Z",
|
||||
"decision": "allow",
|
||||
"exclude": [],
|
||||
"id": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"include": [
|
||||
{
|
||||
"email": {
|
||||
"email": "christoph@emsenhuber.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login_method": {
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "christoph",
|
||||
"require": [],
|
||||
"connection_rules": {
|
||||
"rdp": {}
|
||||
},
|
||||
"session_duration": "730h",
|
||||
"uid": "8e44f5d1-8257-443e-a797-b3de939952ee",
|
||||
"updated_at": "2026-07-31T07:27:41Z",
|
||||
"reusable": true,
|
||||
"precedence": 1
|
||||
},
|
||||
{
|
||||
"created_at": "2026-05-09T06:45:22Z",
|
||||
"decision": "non_identity",
|
||||
"exclude": [],
|
||||
"id": "5165d139-8733-4d31-a3a5-f6f1d0fd8643",
|
||||
"include": [
|
||||
{
|
||||
"ip": {
|
||||
"ip": "90.146.33.177/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "bf4",
|
||||
"require": [],
|
||||
"uid": "5165d139-8733-4d31-a3a5-f6f1d0fd8643",
|
||||
"updated_at": "2026-08-07T21:36:42Z",
|
||||
"reusable": true,
|
||||
"precedence": 2
|
||||
},
|
||||
{
|
||||
"created_at": "2026-05-15T13:11:36Z",
|
||||
"decision": "non_identity",
|
||||
"exclude": [],
|
||||
"id": "39fe0e9d-6f63-414d-9d6d-440a7a151f5d",
|
||||
"include": [
|
||||
{
|
||||
"service_token": {
|
||||
"token_id": "65f1821a-f134-4e20-aa66-baf31daddbed"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "claude-mcp",
|
||||
"require": [],
|
||||
"uid": "39fe0e9d-6f63-414d-9d6d-440a7a151f5d",
|
||||
"updated_at": "2026-07-31T15:44:48Z",
|
||||
"reusable": true,
|
||||
"precedence": 3
|
||||
}
|
||||
],
|
||||
"session_duration": "24h",
|
||||
"enable_binding_cookie": false,
|
||||
"http_only_cookie_attribute": false,
|
||||
"options_preflight_bypass": false,
|
||||
"oauth_configuration": {
|
||||
"enabled": false,
|
||||
"dynamic_client_registration": {
|
||||
"enabled": true,
|
||||
"allowed_uris": [
|
||||
"https://ha-mcp.emsenhuber.net"
|
||||
],
|
||||
"allow_any_on_localhost": true,
|
||||
"allow_any_on_loopback": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 1000,
|
||||
"count": 6,
|
||||
"total_count": 6,
|
||||
"total_pages": 1
|
||||
}
|
||||
}
|
||||
68
docs/cf-backup/tp41-20260901/identity_providers.json
Normal file
68
docs/cf-backup/tp41-20260901/identity_providers.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"id": "72c1291b-a38d-4bc7-af97-5dee04a4f84a",
|
||||
"type": "github",
|
||||
"uid": "72c1291b-a38d-4bc7-af97-5dee04a4f84a",
|
||||
"name": "github",
|
||||
"version": "2c72ea4133061227e63696fb2559488b",
|
||||
"config": {
|
||||
"client_id": "Ov23li2h96hAkGRPJXYV",
|
||||
"redirect_url": "https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback"
|
||||
},
|
||||
"scim_config": {
|
||||
"scim_base_url": "https://emsenhuber.cloudflareaccess.com/scim/72c1291b-a38d-4bc7-af97-5dee04a4f84a",
|
||||
"enabled": false,
|
||||
"user_deprovision": false,
|
||||
"seat_deprovision": false,
|
||||
"group_member_deprovision": false,
|
||||
"identity_update_behavior": "no_action"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "9024c7a6-2d1f-4432-9f48-51593acd1361",
|
||||
"type": "onetimepin",
|
||||
"uid": "9024c7a6-2d1f-4432-9f48-51593acd1361",
|
||||
"name": "",
|
||||
"version": "04b0d281756f552d156faa58ce97f913",
|
||||
"config": {
|
||||
"redirect_url": "https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback"
|
||||
},
|
||||
"scim_config": {
|
||||
"enabled": false,
|
||||
"user_deprovision": false,
|
||||
"seat_deprovision": false,
|
||||
"group_member_deprovision": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c7571880-2c63-4b66-a52a-0051802f7444",
|
||||
"type": "google",
|
||||
"uid": "c7571880-2c63-4b66-a52a-0051802f7444",
|
||||
"name": "google",
|
||||
"version": "6c1595b3026ae3196c70977c3924befb",
|
||||
"config": {
|
||||
"client_id": "276709275903-b3q55lsj203v4strbhh5mub76cib867e.apps.googleusercontent.com",
|
||||
"redirect_url": "https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback"
|
||||
},
|
||||
"scim_config": {
|
||||
"scim_base_url": "https://emsenhuber.cloudflareaccess.com/scim/c7571880-2c63-4b66-a52a-0051802f7444",
|
||||
"enabled": false,
|
||||
"user_deprovision": false,
|
||||
"seat_deprovision": false,
|
||||
"group_member_deprovision": false,
|
||||
"identity_update_behavior": "no_action"
|
||||
}
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 200,
|
||||
"count": 3,
|
||||
"total_count": 3,
|
||||
"total_pages": 1
|
||||
}
|
||||
}
|
||||
29
docs/cf-backup/tp41-20260901/organizations.json
Normal file
29
docs/cf-backup/tp41-20260901/organizations.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"result": {
|
||||
"auth_domain": "emsenhuber.cloudflareaccess.com",
|
||||
"created_at": "2024-02-22T13:41:46Z",
|
||||
"login_design": {
|
||||
"background_color": "#eeeeee"
|
||||
},
|
||||
"name": "bf4.cloudflareaccess.com",
|
||||
"updated_at": "2026-07-09T17:34:55Z",
|
||||
"is_ui_read_only": false,
|
||||
"has_migrated_private_apps": true,
|
||||
"allow_authenticate_via_warp": false,
|
||||
"warp_auth_non_browser_401": false,
|
||||
"cache_device_posture": true,
|
||||
"deny_unmatched_requests": false,
|
||||
"deny_unmatched_requests_exempted_zone_names": [],
|
||||
"mfa_config": {
|
||||
"allowed_authenticators": [
|
||||
"biometrics",
|
||||
"security_key",
|
||||
"totp"
|
||||
],
|
||||
"session_duration": "24h"
|
||||
}
|
||||
},
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": []
|
||||
}
|
||||
51
docs/cf-backup/tp41-20260901/service_tokens.json
Normal file
51
docs/cf-backup/tp41-20260901/service_tokens.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"client_id": "ad1b47dee8ba9625eebb30247d163dda.access",
|
||||
"created_at": "2026-05-15T13:09:45Z",
|
||||
"expires_at": "2027-05-15T13:19:03Z",
|
||||
"id": "65f1821a-f134-4e20-aa66-baf31daddbed",
|
||||
"name": "claude-mcp",
|
||||
"updated_at": "2026-07-31T14:32:11Z",
|
||||
"duration": "8760h",
|
||||
"client_secret_version": 4,
|
||||
"previous_client_secret_expires_at": "2026-07-31T14:32:11Z",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"client_id": "e8a56791f7f534f3eaff8629d8fe902c.access",
|
||||
"created_at": "2026-07-27T11:36:26Z",
|
||||
"expires_at": "2027-08-05T18:32:14Z",
|
||||
"id": "a6be7efa-8367-446d-99b8-67f25f173371",
|
||||
"name": "terpene-verify",
|
||||
"updated_at": "2026-08-05T18:32:14Z",
|
||||
"duration": "8760h",
|
||||
"last_seen_at": "2026-08-02T20:49:21Z",
|
||||
"client_secret_version": 3,
|
||||
"previous_client_secret_expires_at": "2026-07-31T10:00:00Z",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"client_id": "0ec06d3a6dc6d689c13407591b286e5b.access",
|
||||
"created_at": "2026-08-05T18:32:36Z",
|
||||
"expires_at": "2027-08-05T18:32:36Z",
|
||||
"id": "1082bad1-6a25-4188-bf6b-220075679e0f",
|
||||
"name": "terpene-verify-v2",
|
||||
"updated_at": "2026-08-05T18:32:36Z",
|
||||
"duration": "8760h",
|
||||
"last_seen_at": "2026-08-27T12:47:30Z",
|
||||
"client_secret_version": 1,
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 1000,
|
||||
"count": 3,
|
||||
"total_count": 3,
|
||||
"total_pages": 1
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,40 @@
|
||||
# Cloudflare-Tunnel — Mapping & #1033-Diagnose (Single Source of Truth)
|
||||
|
||||
> **Aktueller Stand: → §10 (2026-07-10, TP16 UMGESETZT ✅).** §9 = Analyse/Zielbild, §10 = As-Built.
|
||||
> Abschnitte 1–8 sind Historie (Track A, 2026-06-30); die „3 Connectors gut/Zielbild"-Aussagen dort sind
|
||||
> durch §9/§10 **überholt** (Round-Robin = macvlan-Host-Isolation → 1/N-Ausfälle). Track A aus `docs/handoff-cf-tunnel-1033.md`.
|
||||
> 🆕 **SSoT-Wechsel im Aufbau (TP44, seit 2026-09-02):** Die CF-Estate (Tunnel, WARP-Connector,
|
||||
> VPC-Services, Hyperdrive, Workers, Access-Apps) wird als **native `nautobot.cloud`-Objekte** in
|
||||
> Nautobot (`10.40.20.30`) geführt — Etappe 1 (manuelle Erstbefüllung) ✅. Seeder:
|
||||
> `nautobot/tp44-cf-estate-seed.py`, Detail: `docs/handoff-20260902-cf-estate-nautobot-ssot.md`.
|
||||
> **CF bleibt operativer Master, Nautobot = Dokumentations-SSoT.** Dieses File bleibt gültige Historie
|
||||
> und As-Built-Log; die *strukturierte* Estate liest man ab jetzt in Nautobot. Etappe 2 (CF-API→Nautobot-Sync)
|
||||
> ist offen.
|
||||
|
||||
> **Aktueller Stand: → §0 (unten).** §1–16 sind Historie/As-Built-Log früherer Sessions und beschreiben
|
||||
> Topologien, die **nicht mehr live** sind (v.a. das 3-Tunnel-HA `bf-mm`/`bf-nas`/`bf-pve`). §9 = Analyse,
|
||||
> §10–15 = As-Built des inzwischen abgelösten 3-Tunnel-Designs. Track A aus `docs/handoff-cf-tunnel-1033.md`.
|
||||
|
||||
## §0 — Live-Ist-Stand (2026-09-08, maßgeblich)
|
||||
|
||||
> Der einzige aktuelle Topologie-Stand. **§1–16 nicht als aktuelle Konfiguration lesen** — insbesondere das
|
||||
> 3-Tunnel-HA `bf-mm`/`bf-nas`/`bf-pve` (§10–15) existiert seit dem TP16.3-Cutover (bf-public/Caddy,
|
||||
> 2026-08-27) **nicht mehr**. Strukturierte Estate = Nautobot (TP44, deckt sich mit diesem Stand);
|
||||
> operativer Master = Cloudflare. Read-only gemessen gegen die CF-API (`cfd_tunnel`, `warp_connector`,
|
||||
> `teamnet/routes`) am 2026-09-08.
|
||||
|
||||
**cloudflared-Tunnel (live) — es gibt genau drei:**
|
||||
|
||||
| Tunnel | ID | Conns | Zweck |
|
||||
|---|---|---|---|
|
||||
| **bf-public** | `48d3b0b6-7233-4781-a76a-1de4a5e957ce` | 2, healthy | **einziger öffentlicher BF-Tunnel** (TP31/TP16.3), erstellt 2026-08-27 |
|
||||
| **fm.emsenhuber.net** | `b697d124-53bf-4a33-8fcf-384cced4db1a` | 1, healthy | Standort FM (`ds-fm`, `gateway-fm`), separat |
|
||||
| **terpene-db** | `f2d2fc8a-54ae-41df-b09a-97312cdb9fe2` | 1, healthy | DB-Pfad (Hyperdrive→VPC-Service), Rebuild 2026-09-01 — s. §17 |
|
||||
|
||||
**bf-public-Ingress** → alle vier auf **Caddy `10.40.20.40:443`** (Caddy macht das Fan-out), catch-all 404:
|
||||
`vw` · `hass` · `n8n` · `gitea` (`.emsenhuber.net`).
|
||||
|
||||
**WARP / Private Access — nativer Mesh, KEIN cloudflared:**
|
||||
- warp_connector **bf-core-mesh** `d1da7c8a-2736-4cbb-8af1-32db5393fb9c`, healthy — nativer
|
||||
WireGuard-Mesh-Node auf dem Core (TP16.1). **Live und produktiv** (nicht mehr „gated/Konzept" wie in §14).
|
||||
- Routen: `10.40.0.0/16` → **bf-core-mesh** · `10.101.0.0/24` → **fm**. Ein vnet `vnetemsenhuber` (default).
|
||||
|
||||
## 1. Alle Tunnel im Account (`393c…66c36`)
|
||||
| Tunnel | ID | Status | Conns | Verwendung |
|
||||
@@ -226,6 +258,9 @@ Der macmini ist vollwertiger dritter Knoten (nicht „vergessen").
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>🗄️ <b>ARCHIV (§10–16)</b> — überholtes 3-Tunnel-HA <code>bf-mm</code>/<code>bf-nas</code>/<code>bf-pve</code>. Seit dem TP16.3-Cutover (2026-08-27) nicht mehr live — siehe §0. Aufklappen nur für die Historie.</summary>
|
||||
|
||||
## 10. AS-BUILT 2026-07-10 (TP16 umgesetzt) — reziprokes 3-Tunnel-HA ✅
|
||||
> Gebaut & verifiziert in eigener Session. Round-Robin-#1033 **strukturell weg** (Loop-Gegentest 0×530 über alle 19 Live-FQDNs, HA per Host-Ausfall-Sim bewiesen). Schritte 1–4+HA durch; **Schritt 5 (Access/WARP + `vw`) offen** (user-gated).
|
||||
|
||||
@@ -329,6 +364,10 @@ Letzte in §9.2/§8 als „bleibt `.41`" geführte Origin-Klasse (`pve .41.100`,
|
||||
|
||||
## 14. Richtungsentscheid 2026-07-16 — Private Access via native Cloudflare Mesh (WARP Connector) auf dem CRS326 Core-Switch (TP16.1)
|
||||
|
||||
> ✅ **Nachtrag 2026-09-08 (live):** umgesetzt. warp_connector **bf-core-mesh** (`d1da7c8a-…`) ist healthy
|
||||
> und trägt die Route `10.40.0.0/16` — der „Scharfschalten = eigene Session, gated"-Status unten ist
|
||||
> überholt. Siehe §0.
|
||||
|
||||
> ✅ **Update 2026-07-22 (User-Entscheid):** Ziel-Device retargeted von **ap1** auf den **CRS326 Core-Switch** — konsistent mit TP15-Endstand (kein RB5009, Router bleibt ap1/ap2) und TP21s Kabel-Fabric-Modell. Reine Ziel-Doku-Änderung, Scharfschalten bleibt gated bis TP21 den CRS326 abdeckt. Der Rest dieser Sektion ist entsprechend auf den neuen Zielhost umgeschrieben; CRS326 ist aktuell noch Werkszustand, Management-IP/Interface TBD.
|
||||
|
||||
**Trennung der Concerns (wichtig):**
|
||||
@@ -443,3 +482,42 @@ SSoT und hat eine ganze Architektur getragen.
|
||||
Netzwerk-Namespace, sieht ohnehin alles), und die cloudflared-Connectoren laufen auf **ap1/ap2** —
|
||||
eigene Maschinen, auf denen die Blindheit prinzipiell nicht auftreten kann. Der Shim bleibt als Option
|
||||
für den Fall, dass später doch ein Dienst neben macvlan-Nachbarn einziehen soll.
|
||||
|
||||
</details>
|
||||
|
||||
## 17. Terpenfinder-DB-Pfad neu aufgebaut 2026-09-02 (Fremdprojekt-Handout blaueblüten)
|
||||
|
||||
**Auslöser:** Handout `blaueblueten-n8n/docs/handout-bf-infra-db-pfad-20260902.md` — der Cloudflare-Worker
|
||||
`terpene` (`420.teilzeitladen.xyz`) lieferte `503 CONNECTION_CLOSED …hyperdrive.local:5432` auf allen
|
||||
`/api/*`-Reads.
|
||||
|
||||
**Root-Cause:** TP16.3 §6 hat beim Alttunnel-Abbau den Container **`terpene-cloudflared` (LXC 400)** mit
|
||||
abgeräumt, obwohl das Runbook ihn ausdrücklich als „nicht anfassen" markierte. Damit war der Tunnel
|
||||
`terpene-db` (`b83b68f0`) `deleted_at 2026-08-31`. Der **VPC-Service** `terpene-db` (`019fa3d5`) zeigte
|
||||
weiter auf diese tote ID. Der Public-Weg (PWA→`bf-public`/Caddy) und der **DB-Weg**
|
||||
(Hyperdrive→VPC-Service→cloudflared→Postgres) wurden verwechselt — der DB-Weg ist unabhängig und blieb
|
||||
ungesichert.
|
||||
|
||||
**Verworfene Optionen (live geprüft):**
|
||||
- **Mesh (`bf-core-mesh`, warp_connector):** CF lehnt ab — `5101: Tunnel is not a cloudflared tunnel`.
|
||||
Ein VPC-Service akzeptiert im `host.network.tunnel_id` **nur einen cloudflared-Tunnel**, keinen
|
||||
warp_connector. (Mesh geht nur über *VPC Networks*, die Hyperdrive nicht nutzt.)
|
||||
- **`bf-public` (AP-Endpoints) wiederverwenden:** bräuchte eine neue Firewallregel `vlan99→10.40.20.20:5432`
|
||||
(Loch mgmt→INFRA, heute nur `.20.40:443` offen, Regel `*42`) **plus** `warp-routing` auf dem geteilten
|
||||
Public-Tunnel (steht auf `false`) — Projekt-Vermischung. Verworfen.
|
||||
|
||||
**Umgesetzt (Option B):** eigener neuer cloudflared-Tunnel neben der DB.
|
||||
|
||||
| Objekt | Wert |
|
||||
|---|---|
|
||||
| cfd_tunnel `terpene-db` (neu) | **`f2d2fc8a-54ae-41df-b09a-97312cdb9fe2`**, remotely-managed, healthy/4 Conns |
|
||||
| Connector | Container `terpene-cloudflared` auf **LXC 400** (VLAN20, `.20.126`), `restart=unless-stopped`, Token per `--env-file` |
|
||||
| VPC-Service `terpene-db` | `019fa3d5-…` `host.network.tunnel_id` → `f2d2fc8a` (PUT 200, 2026-09-01T23:57Z) |
|
||||
| Firewall | **0 Änderungen** — Connector und DB im selben VLAN20, kein Cross-VLAN |
|
||||
| Tombstone | Alttunnel `b83b68f0` bleibt soft-deleted, kein Aufräumbedarf |
|
||||
|
||||
🔑 **Gotcha 1:** VPC-Service = `/accounts/{id}/connectivity/directory/services/{id}`, Update ist **PUT**
|
||||
(voller Body), **nicht** unter `/vpc/…`. 🔑 **Gotcha 2:** der Repo-`CF_API_TOKEN` (`mcp/cloudflare/.env`)
|
||||
darf `cfd_tunnel` (Create lief per curl), aber **nicht** die Workers-VPC-Resource — dort `10000 Auth error`;
|
||||
der PUT lief über den `cloudflare`-MCP-Credential. 🔑 **Merkregel:** vor einem AP-basierten Weg immer die
|
||||
Egress-VLAN-Seite der Connectoren prüfen — `bf-public` sitzt auf **vlan99**, nicht vlan20.
|
||||
|
||||
146
docs/handoff-20260831-tp16.3-paragraph2-3-durch.md
Normal file
146
docs/handoff-20260831-tp16.3-paragraph2-3-durch.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Handoff — TP16.3 §2/§3 durch: drei Connectoren live, eine Entscheidung offen
|
||||
|
||||
> **2026-08-31, Vor-Ort-Session.** Nachfolger von
|
||||
> [`handoff-20260831-tp16.3-vorort-session.md`](handoff-20260831-tp16.3-vorort-session.md).
|
||||
> **Nicht** Teil dieser Session: §5 (CNAME-Flip) und §6 (Abbau).
|
||||
|
||||
---
|
||||
|
||||
## 1. Was jetzt steht
|
||||
|
||||
`bf-public` ist **healthy mit 12 Connectoren** (3 APs × 4 CF-Edges) — der Tunnel hatte vorher
|
||||
**null**. Je ein `cloudflared 2026.6.1` läuft auf ap1, ap2 und ap3.
|
||||
|
||||
| | ap1 | ap2 | ap3 |
|
||||
|---|---|---|---|
|
||||
| `container`-Paket | 7.24.1 ✅ | 7.24.1 ✅ | 7.24.1 ✅ |
|
||||
| `device-mode container` | `yes` ✅ | `yes` ✅ | `yes` ✅ |
|
||||
| Container | `R` running | `R` running | `R` running |
|
||||
| `.tar` gelöscht | ✅ | ✅ | ✅ |
|
||||
| Flash frei | 54,0 MiB | 54,6 MiB | 55,0 MiB |
|
||||
|
||||
WLAN auf allen drei zurück, CAPs `state=Ok` am Manager. Backups je AP liegen auf dem Gerät
|
||||
(`vor-tp16.3-apN.backup`) **und** lokal unter `~/tp16.3/backups/` — inklusive vollständigem
|
||||
`/export` (nicht der MCP-Export, s. Punkt 4).
|
||||
|
||||
---
|
||||
|
||||
## 2. 🔴 Die eine offene Entscheidung: Compliance steht auf 128/135
|
||||
|
||||
Nach vollem Refresh (Backup → Intended → Compliance, **nicht** die stale Zahl von vorher):
|
||||
|
||||
| Gerät | Regel | Inhalt |
|
||||
|---|---|---|
|
||||
| ap1 / ap2 / ap3 | `ip-address` | `/ip address add address=172.17.0.1/24 interface=veth-cf` |
|
||||
| ap1 / ap2 / ap3 | `ip-firewall-nat` | `masquerade`, Kommentar `TP31: cloudflared egress` |
|
||||
| crs326-core | `wifi-security` | `ft-over-ds` — **offene Transaktion `TP25-fund-e-ft-over-ds`**, kein Versehen |
|
||||
|
||||
**Ursache ist ein Widerspruch zwischen zwei Dokumenten**, kein Ausrutscher: Runbook §3.4 schreibt
|
||||
Direkt-Writes für `veth`/`ip address`/`nat` vor, die Governance stellt `/ip address` und
|
||||
`/ip firewall` unter GC-Pflicht. Ich bin dem Runbook gefolgt.
|
||||
|
||||
⚠️ **Korrektur 2026-08-31 (nachgetragen):** die siebte Drift wurde hier zuerst dem 7.24.1-Upgrade
|
||||
zugeschrieben — falsch. `gc-transaktion.py status` führt **`TP25-fund-e-ft-over-ds` als OFFEN**
|
||||
(gesetzt 08:09, Core-Upgrade erst 14:36). Sie ist Absicht einer laufenden Messung und braucht **keine**
|
||||
Entscheidung. **Merkregel: vor jeder Drift-Bewertung `gc-transaktion.py status` lesen** — Drift aus
|
||||
einem laufenden Versuch sieht identisch aus wie ein Versehen.
|
||||
|
||||
**Die sechs Drifts sind inhaltlich richtig** — die Config *soll* dort stehen, ohne sie läuft kein
|
||||
Container. Der saubere Weg ist, sie ins **Soll** zu heben (AP-Template bzw. ConfigContext
|
||||
`ap-common`), damit die Compliance sie als konform sieht.
|
||||
🔴 **Kein Re-Baseline** (macht die Drift-Erkennung wertlos) und **kein Rückbau** (killt die Tunnel).
|
||||
⚠️ `/interface veth` erzeugt **keine** Drift — dafür existiert keine ComplianceRule. Wenn das Soll
|
||||
angepasst wird, gehört die Frage dazu, ob `veth` überhaupt erfasst sein soll.
|
||||
|
||||
---
|
||||
|
||||
## 3. 🔴 Drei Runbook-Fehler, die diese Session aufgedeckt hat
|
||||
|
||||
**(a) Die Flash-Rechnung war um Faktor 2,5 zu optimistisch.** §3.5 rechnete mit „28 MB `.tar`
|
||||
+ ~28 MB entpackt ≈ 39 MB Rest". Die 28 MB sind die **komprimierte** Archivgrösse; entpackt misst
|
||||
`cloudflare/cloudflared:2026.6.1` **72.926.208 B = 69,5 MiB**. Der Import braucht Tar **und**
|
||||
entpacktes Abbild gleichzeitig ⇒ 95,7 MiB gegen ~90 MiB frei. **Das offizielle Image passt auf
|
||||
keinen der drei APs.**
|
||||
⚠️ **`docker image inspect .Size` führt in die Irre** (meldete 27.463.950). Für Flash-Budgets
|
||||
`docker export | wc -c` messen.
|
||||
|
||||
**Lösung, ausgerollt:** eigenes `FROM scratch`-Image aus dem — nachweislich **statisch gelinkten** —
|
||||
Binary (36,8 MB) plus CA-Bundle: **35,3 MiB**, Spitzenbedarf 70,6 MiB. Build-Skript liegt jetzt im
|
||||
Repo (`tools/build-cfd-image.py`), ein Neubau ist **byte-identisch** (`f818bf40…`).
|
||||
🔑 Der Pin ist die **Binary-SHA256 `e93824f6…`**, und cloudflared bestätigt sie beim Start selbst
|
||||
(`Version 2026.6.1 (Checksum e93824f6…)`) — im Log aller drei APs nachlesbar.
|
||||
|
||||
**(b) `docker save` taugt seit Docker 25 nicht mehr als Quelle.** Mit containerd-Image-Store schreibt
|
||||
es OCI-Layout (`blobs/sha256/`, gzip-Layer); RouterOS will docker-v1 und meldet
|
||||
**`no config found in manifest`** — klingt nach kaputtem Image, ist das Format.
|
||||
(Konverter für den Fall, dass man doch ein Docker-Image braucht: `tools/oci2docker.py`, prüft die
|
||||
Layer-Digests gegen `rootfs.diff_ids`.)
|
||||
|
||||
**(c) `/container/envs` heisst auf ROS 7.24.1 `list=`, nicht `name=`.** Mit `name=` kommt
|
||||
`bad parameter name` bzw. `unknown parameter name`. **Auch MikroMCPs `manage_container_env` benutzt
|
||||
`name=` und ist damit für dieses Feld unbrauchbar.**
|
||||
|
||||
---
|
||||
|
||||
## 4. Vier weitere Funde
|
||||
|
||||
- 🔴 **Der `device-mode`-Bestätigungs-Boot installiert KEINE Pakete.** Auf ap1 lag die `.npk` schon
|
||||
bereit, als `device-mode` gesetzt wurde — der Stromzyklus hat `container: yes` bestätigt und die
|
||||
Datei **verbraucht, ohne zu installieren**. **Reihenfolge ist Pflicht: erst Paket-Reboot, dann
|
||||
`device-mode`.** (Nachholen ging per SSH, ohne zweiten Gang zum Gerät.)
|
||||
- 🟡 **`A - AVAILABLE` in `/system package print` ist ein Download-Katalog, kein Paket auf dem Gerät.**
|
||||
Gegenprobe: `crs326-core` hat 2,9 MB frei von 16 MB, listet aber `wifi-qcom` (10,1 MB) und
|
||||
`rose-storage` (4,3 MB) als „available"; die Grössen sind arch-spezifisch. `enable` löste einen
|
||||
Internet-Fetch aus — auf ap1/ap2 per `device-mode=home` gesperrt. **Der `.npk`-Weg bleibt richtig.**
|
||||
- 🟡 **MikroMCPs `export_config` exportiert unvollständig:** 301 Bytes gegen 6,2 KiB bei direktem
|
||||
`/export`. Ein Rollback-Artefakt, das existiert und trotzdem fast leer ist — dieselbe Klasse wie
|
||||
„Lücke statt Fehlermeldung". Für Backups `/export file=…` per SSH.
|
||||
- ⚠️ **WLAN-Abnahme nur teilweise belegbar:** `main` (3 Clients) und `iot` (27) haben frische Leases;
|
||||
`media`/`untrusted`/`guest` hatten **schon vor** dem Umbau null Clients. Kein Rückschritt, aber
|
||||
auch kein Beleg — nicht als „grün" buchen.
|
||||
|
||||
---
|
||||
|
||||
## 5. 🔴 Sicherheitsvorfall in dieser Session — Rotation nötig
|
||||
|
||||
Beim Suchen des Nautobot-Tokens hat eine unzureichende `sed`-Maskierung
|
||||
(`grep -n … | sed 's/:.*TOKEN/…/' | cut -c1-60`) **zwei Werte im Klartext ins Transkript geschrieben**:
|
||||
|
||||
- `NAUTOBOT_SUPERUSER_API_TOKEN`
|
||||
- `NAUTOBOT_GITEA_TOKEN`
|
||||
|
||||
beide aus `docs/nas-vlan20/stacks/210-nautobot.yml`. **Als verbrannt behandeln → TP30.**
|
||||
Das ist exakt die Falle, die seit 2026-08-28 in der CLAUDE.md steht (der `SHELLY_DEVICE_PW`-Fall).
|
||||
**Merkregel, die offenbar noch nicht scharf genug formuliert war:** ein Maskierungs-Muster, das auf
|
||||
`:` ankert, matcht bei `grep -n` den **Zeilennummer-Präfix** statt den Wert. Sicher ist nur
|
||||
`sed -E 's/(TOKEN|PASSWORD|SECRET|KEY|PASS)=.*/\1=<redacted>/'` — auf den **Schlüsselnamen** ankern,
|
||||
nie auf ein Trennzeichen, das auch im Präfix vorkommt.
|
||||
|
||||
---
|
||||
|
||||
## 6. Repo-Zustand
|
||||
|
||||
- Branch `claude/nervous-williams-acf000` ist hier **hereingemergt**. Konflikte aufgelöst:
|
||||
- **Nummernkonflikt TP37**: `main` hatte TP37 = *Nautobot als Netzwerkdoku* (User-Okay 08-30),
|
||||
der Branch TP37 = *OOB-Mgmt*. Letzterer ist auf **TP38** umnummeriert.
|
||||
✅ **Von Christoph bestätigt (2026-08-31).**
|
||||
- **Drei CF-Rollback-Snapshots hatten denselben Dateinamen bei verschiedenem Inhalt**
|
||||
(`bf-mm` v4/6 Regeln vs. v6/2 Regeln, analog `bf-nas`, `bf-pve`) — zwei Zeitpunkte, beide
|
||||
„vor-tp16.3-schnitt" genannt. **Keiner verworfen:** der ältere liegt jetzt als
|
||||
`*-vor-hostname-schnitt.json` daneben.
|
||||
- Neu: `tools/build-cfd-image.py`, `tools/oci2docker.py`.
|
||||
- `mcp/mikromcp/config/routers.yaml` meldet weiter `rosVersion: "7.24"` für alle fünf (live 7.24.1) —
|
||||
kosmetisch, unangetastet gelassen.
|
||||
|
||||
---
|
||||
|
||||
## 7. Nächste Schritte
|
||||
|
||||
1. **Entscheidung zu Punkt 2** (sechs Drifts ins Soll heben) — vor dem Flip, sonst geht man mit
|
||||
erklärter, aber ungeklärter Drift in den Produktivpfad.
|
||||
2. **§5 CNAME-Flip**, einzeln mit Abnahme dazwischen, Testname zuerst (§5.1).
|
||||
▸ Fertiger Übergabeprompt: [`tp16.3-paragraph5-session-handoff-prompt.md`](tp16.3-paragraph5-session-handoff-prompt.md).
|
||||
🔴 `healthy` beweist nur, dass der Connector mit Cloudflare redet — **nicht**, dass das Origin
|
||||
antwortet. Der Streckenbeweis bis Caddy ist §5.1.
|
||||
3. **§6 Abbau** frühestens 7 Tage nach dem Flip.
|
||||
4. **TP30**: die zwei Tokens aus Punkt 5 rotieren.
|
||||
139
docs/handoff-20260831-tp16.3-vorort-session.md
Normal file
139
docs/handoff-20260831-tp16.3-vorort-session.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Handover — TP16.3 §2/§3: Container-Bootstrap auf ap1 / ap2 / ap3
|
||||
|
||||
> ✅ **ERLEDIGT am 2026-08-31.** Nachfolge-Dokument mit Ergebnis, drei korrigierten Runbook-Fehlern
|
||||
> und der einen offenen Entscheidung (Compliance 128/135):
|
||||
> [`handoff-20260831-tp16.3-paragraph2-3-durch.md`](handoff-20260831-tp16.3-paragraph2-3-durch.md).
|
||||
> Dieses Dokument bleibt als Ausgangslage stehen — **Abschnitt 3 und 7 sind inhaltlich überholt**
|
||||
> (Flash-Budget, `docker save`, `envs`-Parametername, Reihenfolge Paket/device-mode).
|
||||
|
||||
> **Erstellt 2026-08-31.** Zielsession: **§2 + §3** des Runbooks
|
||||
> [`tp16.3-bf-public-ap-connector-runbook.md`](tp16.3-bf-public-ap-connector-runbook.md) — also
|
||||
> `container.npk`, `device-mode`, Container. **Vor Ort**, weil jeder AP eine physische Bestätigung braucht.
|
||||
> **Nicht** Teil dieser Session: der CNAME-Flip (§5) und der Abbau (§6).
|
||||
|
||||
---
|
||||
|
||||
## 1. Was vor dir schon erledigt ist — nicht nochmal machen
|
||||
|
||||
| Punkt | Stand | Nachweis |
|
||||
|---|---|---|
|
||||
| **§1 Blocker A** — Redirect-Schleife | ✅ 08-31 | `bf-public`-Ingress → `https://10.40.20.40:443`, `originServerName` je Regel, zurückgelesen |
|
||||
| **§1 Blocker B** — Firewall `vlan99→vlan20:443` | ✅ 08-31 | via **Nautobot GC** (Plan `Completed`), Position vor `TP5: log-only` geprüft, funktional gegen Caddy nachgewiesen |
|
||||
| **§1 Blocker C** — `ROUTER_AP3_PASS` | ✅ 08-31 | in `~/.secrets/credentials.env`, REST-Auth ap3 = **200** |
|
||||
| Rollback-Snapshots | ✅ 08-30 | `docs/cf-backup/*-20260830-vor-tp16.3-schnitt.json` |
|
||||
| ROS-Upgrade auf **7.24.1** | ✅ 08-31 (User) | alle fünf Geräte, RouterBOOT mitgezogen |
|
||||
|
||||
**⇒ Die Session startet bei §2.** Wer §1 nochmal anfasst, arbeitet doppelt.
|
||||
|
||||
---
|
||||
|
||||
## 2. Die eine Änderung gegenüber dem Runbook-Stand vom 08-30
|
||||
|
||||
🎉 **Aus zwei `container.npk` ist eine geworden.** Christoph hat am 08-31 alle fünf MikroTik auf
|
||||
**7.24.1** gehoben. Damit gilt:
|
||||
|
||||
```
|
||||
container-7.24.1-arm64.npk → ap1, ap2 UND ap3
|
||||
```
|
||||
|
||||
Die frühere Zwei-Dateien-Regel war **rein versionsbedingt**, nicht modellbedingt — `cAP ax` und
|
||||
`hAP ax²` teilen sich die `arm64`-Pakete. Das Runbook ist entsprechend umgeschrieben (§0, §2.1, §3.1,
|
||||
Falle 1).
|
||||
|
||||
⚠️ **Die Regel dahinter bleibt:** `container.npk` muss **exakt** zur ROS-Version passen. Vor dem Upload
|
||||
`/system resource print` lesen. Falsche Datei ⇒ Paket ist nach dem Reboot **inaktiv, ohne Fehlermeldung**.
|
||||
|
||||
---
|
||||
|
||||
## 3. Ablauf in einem Satz
|
||||
|
||||
Je AP, **einzeln und vollständig, Reihenfolge ap3 → ap2 → ap1**:
|
||||
`.npk` hoch → Reboot (SSH, **nicht** MikroMCP) → `/system package print` prüfen →
|
||||
`device-mode update container=yes` → **physisch bestätigen** → `veth` + `masquerade` →
|
||||
`.tar` hoch → `/container add file=` → starten → `.tar` löschen → Log prüfen.
|
||||
|
||||
**Details, Befehle und Abnahmekriterien: Runbook §2 und §3.** Hier nur die Punkte, die man
|
||||
erfahrungsgemäß falsch macht:
|
||||
|
||||
- 🔴 **Reboot geht NICHT über MikroMCP** (ROS kennt den `delay`-Parameter nicht, `run_command` ist für
|
||||
`/system reboot*` gesperrt) → `SSHPASS="$PW" sshpass -e ssh admin@<ip> "/system reboot"`.
|
||||
**Niemals `sshpass -p`** — das schreibt das Passwort in `ps`.
|
||||
- 🔴 **`~/.secrets/credentials.env` in zsh sourcen schlägt still fehl** (rohe WireGuard-Zeilen ab ~Z. 69).
|
||||
Variablen bleiben **leer**, und der Fehler sieht aus wie ein ungültiger Token. **Immer `bash -c`.**
|
||||
- 🔴 **Kein PoE an den CRS326** (beide haben gar kein PoE-Menü) ⇒ kein Remote-Power-Cycle. Die
|
||||
Bestätigung ist wirklich physisch: **Stecker ziehen/stecken** (Weg A, eindeutig) oder Reset-Knopf am
|
||||
*laufenden* Gerät kurz drücken (Weg B). Weg B **nie während des Bootens** — das wäre ein Werksreset.
|
||||
- 🔴 **Ein Container pro AP.** Nach dem Import bleiben ~39 MB. Kein Caddy, kein AGH dazu.
|
||||
- ⚠️ **Jeder AP rebootet zweimal** → WLAN dieses APs ist je ~1–2 min weg. Die CAPs holen ihre Config
|
||||
per L2-Discovery vom Core. **Nicht ungeduldig nachprovisionieren.**
|
||||
- ⚠️ **WLAN-Abnahme ist eine frische DHCP-Lease je SSID, nicht die Registration-Table.**
|
||||
|
||||
**Erwartetes Ergebnis am Ende:** `bf-public` meldet `healthy` mit Connectoren (Richtung 12 = 3 APs × 4
|
||||
CF-Edge). 🔴 **`healthy` heißt nur „Connector redet mit Cloudflare", nicht „Origin antwortet"** — der
|
||||
Beweis für die Strecke bis Caddy ist §5.1, und der gehört in die **Folge**session.
|
||||
|
||||
---
|
||||
|
||||
## 4. Was du unterwegs sehen wirst und **nicht** als Fehler behandeln darfst
|
||||
|
||||
**`/tool fetch` von einem AP auf `https://10.40.20.40` schlägt mit einem TLS-Alert fehl.**
|
||||
Das ist **korrekt und erwartet**: Caddy weist Handshakes ohne passenden SNI ab (gemessen: ohne SNI
|
||||
`000`, mit korrektem SNI `200`). Der Alert **beweist sogar**, dass das Paket ankommt — ein TLS-Alert
|
||||
kann nur vom Server kommen, die Firewall-Freigabe trägt also. cloudflared schickt den richtigen SNI
|
||||
über `originServerName`. **Nicht „reparieren".**
|
||||
|
||||
---
|
||||
|
||||
## 5. Offene Punkte, die NICHT in diese Session gehören
|
||||
|
||||
1. ✅ **Die 134/135 sind ABSICHT — nichts tun.** `crs326-core` / `wifi-security`: `sec-main` hat
|
||||
`ft-over-ds=no` statt `yes`. Das ist **TP25 Fund E, Hebel 1**, am 2026-08-31 um 08:09 bewusst gesetzt
|
||||
und als **offene Transaktion `TP25-fund-e-ft-over-ds`** geführt (Scope `wifi-security`, Ablauf
|
||||
2026-09-03, gehört einer anderen Session). **Nicht anfassen, nicht grün machen, nicht re-baselinen** —
|
||||
das würde einen laufenden Versuch unsichtbar machen.
|
||||
*(Eine frühere Fassung dieses Handovers schrieb die Drift dem 7.24.1-Upgrade zu. Falsch: der Hebel
|
||||
kam um 08:09, der Core wurde erst 14:36 gehoben.)*
|
||||
🔑 **Merkregel für die Session:** wenn Compliance nicht 135/135 zeigt, **zuerst**
|
||||
`nautobot/gc-transaktion.py status` lesen. Drift aus einem laufenden Versuch sieht genauso aus wie
|
||||
ein Versehen.
|
||||
2. 🆕 **[TP37](teilprojekte.md#tp37) — OOB-Management, angelegt 2026-08-31.** Je ein untagged-VLAN99-Port
|
||||
auf beiden Switches (Kandidat `ether23`, auf core **und** branch frei). Auslöser: beim Core-Neustart
|
||||
war `crs326-branch` nicht erreichbar, weil sein Mgmt **ausschließlich** über den Core läuft.
|
||||
🔴 Nebenbefund mit eigenem Gewicht: **der Branch hat gar keine `input`-Firewallregeln** — sein Schutz
|
||||
ist heute allein die Erreichbarkeit über den gehärteten Core.
|
||||
💡 **Berührt diese Session, ist aber keine Voraussetzung:** hier rebooten dreimal Geräte, deren Mgmt
|
||||
am Core hängt. Wer vor Ort ist, kann `ether23` schon mal beschriften — gebaut wird TP37 separat.
|
||||
3. 🟡 **`mcp/mikromcp/config/routers.yaml` hält `rosVersion: "7.24"`** für alle fünf — jetzt `7.24.1`.
|
||||
⚠️ **Die Datei liegt auf `main`, nicht auf diesem Branch** (der Worktree hat eine ältere Kopie
|
||||
**ohne** ap3). Der Fix gehört auf `main`, nicht hierher — sonst gibt es einen Konflikt.
|
||||
4. **CNAME-Flip (§5) und Abbau (§6)** — eigene Session, §6 frühestens 7 Tage nach dem Flip.
|
||||
|
||||
---
|
||||
|
||||
## 6. Zugänge und Werkzeuge
|
||||
|
||||
| Was | Wie |
|
||||
|---|---|
|
||||
| APs | MikroMCP `ap1`/`ap2`/`ap3` (Reads), SSH `admin@10.40.99.11/.12/.13`, Creds `ROUTER_AP{1,2,3}_PASS` in `~/.secrets` |
|
||||
| Reboot | `bash -c 'set -a; . ~/.secrets/credentials.env; set +a; SSHPASS="$ROUTER_AP3_PASS" sshpass -e ssh admin@10.40.99.13 "/system reboot"'` |
|
||||
| Config-Änderungen an MikroTik | **ausschließlich Nautobot GC** (`nautobot/gc-manual-plan.py`), Token aus `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored, **nur im Haupt-Checkout**) |
|
||||
| Cloudflare | `CF_API_TOKEN` / `CF_ACCOUNT_ID` in `~/.secrets`, Zone `1b5bc02fdf61b6b989afde543f3f4134` |
|
||||
| Caddy | `caddy-bf1`, LXC 130 auf pve, `10.40.20.40`; Logs `ssh root@10.40.20.100 'pct exec 130 -- journalctl -u caddy -n 50'` |
|
||||
|
||||
⚠️ **`device-mode`- und Container-Schritte sind KEINE Golden-Config-Sache** — sie sind Bootstrapping am
|
||||
Gerät (wie die genehmigte Ausnahme #2 beim CRS326-Bring-up). Die GC-Pflicht gilt für
|
||||
`/ip firewall`, `/interface` & Co. **Wenn die Session eine Firewall- oder Interface-Zeile braucht:
|
||||
über `gc-manual-plan.py`, nicht per Direkt-Write.**
|
||||
|
||||
---
|
||||
|
||||
## 7. Abnahme dieser Session
|
||||
|
||||
- [ ] `/system package print` zeigt auf **allen drei** APs `container` in **7.24.1**, nicht disabled
|
||||
- [ ] `/system device-mode print` zeigt `container: yes` auf allen dreien
|
||||
- [ ] `/container print` zeigt je AP **einen** Container `running`
|
||||
- [ ] `.tar` je AP gelöscht (Flash zurück)
|
||||
- [ ] `bf-public` meldet `healthy` mit Connectoren > 0
|
||||
- [ ] WLAN je AP zurück — **frische DHCP-Lease pro SSID**, nicht Registration-Table
|
||||
- [ ] Compliance nicht schlechter als **134/135** — die `wifi-security`-Drift ist die offene
|
||||
TP25-Transaktion aus Punkt 5.1 und **muss** bestehen bleiben
|
||||
186
docs/handoff-20260901-fund-e-hebel1-zurueckgebaut.md
Normal file
186
docs/handoff-20260901-fund-e-hebel1-zurueckgebaut.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Handoff 2026-09-01 — Hebel 1 widerlegt und zurückgebaut, 7.24.1 ist der Verdächtige
|
||||
|
||||
> Vorgänger: [`handoff-20260831-tp27-upgrade-und-hebel1-befund.md`](handoff-20260831-tp27-upgrade-und-hebel1-befund.md).
|
||||
> **Dieses Dokument ist der Stand danach.** Offene Aufgabe: **eine Messung am 2026-09-02 früh.**
|
||||
|
||||
## Die Messung, die Hebel 1 widerlegt
|
||||
|
||||
| Fenster | Bedingung | iPhone-`reauthenticating` | pro Stunde |
|
||||
|---|---|---|---|
|
||||
| 31.08. 07:00–08:00 | Baseline | **79** | 79 |
|
||||
| 31.08. 08:09–14:36 | **nur Hebel 1** (ROS 7.24) | **124** | ~19 |
|
||||
| 31.08. 14:37–24:00 | Hebel 1 + **7.24.1** | 17 | ~1,8 |
|
||||
| 01.09. 00:00–07:57 | Hebel 1 + 7.24.1 | **0** | 0 |
|
||||
|
||||
6,4 Stunden Hebel 1 **allein** haben nichts verbessert. Der Einbruch fällt exakt auf den
|
||||
Core-Reboot um 14:36 — also auf das TP27-Upgrade, nicht auf den Hebel.
|
||||
|
||||
**Beide Gegenproben bestanden** — ohne sie wäre die Null wertlos:
|
||||
- **War das Telefon da?** Ja: 27 Zeilen am 01.09., mehrfaches Roaming, live verbunden.
|
||||
- **Lief das Logging?** Ja: keine Lücke > 15 min in der Tagesdatei.
|
||||
|
||||
## 🔴 Widerspruch zu einer Parallelsession — und wie er aufzulösen ist
|
||||
|
||||
Eine zweite Session hat in der Nacht denselben Fall bearbeitet und kam zum **gegenteiligen**
|
||||
Schluss: [`handoff-20260901-tp25-ap2-verdacht.md`](handoff-20260901-tp25-ap2-verdacht.md) wertet
|
||||
Fund E als **geheilt durch Hebel 1** und empfiehlt, ihn zu **committen**.
|
||||
|
||||
**Ihr Beleg war eine Fehlmessung.** Zitiert wird
|
||||
`get_log topics=[wireless] prefix=reauthenticating sinceMinutes=1440` → `total 0`. Das ist der
|
||||
**flüchtige Ringpuffer des Routers**, nicht der Kollektor:
|
||||
|
||||
```
|
||||
/log am Core, live geprüft 2026-09-01 09:1x:
|
||||
1000 Zeilen im Ringpuffer, ältester Eintrag 2026-09-01 00:38:58 ← keine 9 Stunden Tiefe
|
||||
```
|
||||
|
||||
Der Core wurde am 31.08. um **14:36** neu gestartet; der Puffer war danach leer und um 01:18
|
||||
längst überschrieben. Eine 1440-Minuten-Abfrage konnte den 31.08. Vormittag **nicht sehen** —
|
||||
`total 0` heißt „im Puffer nichts", nicht „in 24 h nichts". Genau diese Falle war der Anlass, am
|
||||
30.08. das persistente Logging einzurichten (CLAUDE.md: „ein seit Wochen gemeldetes Client-Problem
|
||||
war rückwirkend nicht diagnostizierbar").
|
||||
|
||||
**Der zweite Einwand — die 124 seien Reboot-Artefakte — trägt ebenfalls nicht.** Die Upgrade-Reboots
|
||||
waren ap2 08:56, core 14:36, ap1 14:50, branch 14:52. Zwischen **09:00 und 14:36 gab es keinen
|
||||
Reboot**, und in diesem Fenster stehen im Kollektor 09h=1, 11h=2, 12h=20, 13h=31, 14h=70 — **alle
|
||||
vom iPhone allein**, also nach dem eigenen Gotcha der Session (viele MACs = Infrastruktur, eine MAC
|
||||
= Client) ein Client-Befund. Dazu Christophs **zwei erlebte Ausfälle** um 13:16 und 14:23.
|
||||
|
||||
⚖️ **Auflösung: der Rückbau IST das Experiment, das den Streit entscheidet.** Steht `ft-over-ds`
|
||||
wieder auf `yes` und bleibt es trotzdem ruhig, war 7.24.1 die Ursache. Kommt das Hämmern zurück,
|
||||
hatte die Parallelsession recht und Hebel 1 wird als neue Transaktion erneut gezogen. **Vor dem
|
||||
2026-09-02 früh sollte niemand committen.**
|
||||
|
||||
✅ **Unabhängig davon wertvoll: ihr `ap2`-Befund.** Am 31.08. um 23:02 meldete Christoph eine
|
||||
Störung am Schreibtisch; die Session maß **−80 dBm bei 2 m Abstand** zu ap2, `not responding` bei
|
||||
−82, und **0 Clients auf ap2** bei 29 auf ap3. Das ist weder Coverage noch FT, sondern ein
|
||||
Hardware-/Störungsverdacht (Kandidat: DTU auf ch11, Transaktion `TP17.1-dtu-pin-ap2`). **Das
|
||||
erklärt den 23:02-Schmerz, den mein Rückbau nicht adressiert** — eigener Strang, braucht eine
|
||||
In-situ-Messung.
|
||||
|
||||
## Was heute getan wurde: Rückbau statt Commit
|
||||
|
||||
**Warum nicht committen:** Solange Hebel 1 steht, sind zwei Änderungen gleichzeitig aktiv. Der
|
||||
Rückbau isoliert das Upgrade — **er ist der Test**, nicht bloß Aufräumen. Und weil das GC-Template
|
||||
in Z. 220 ohnehin `ft-over-ds=yes` führt, kommt die Compliance **ohne Template-Änderung** zurück.
|
||||
|
||||
Weg **symmetrisch zum Hinweg** (Christoph-Entscheid), also am Gerät, nicht über GC:
|
||||
|
||||
```
|
||||
/system backup save name=pre-tp25-funde-rollback # 0
|
||||
/interface wifi security set [find name="sec-main"] ft-over-ds=yes
|
||||
/interface wifi capsman remote-cap provision [find]
|
||||
```
|
||||
|
||||
Der Rückbau-Vorschlag aus dem Snapshot zeigte **genau eine** Abweichung — kein Kollateral-Drift:
|
||||
```
|
||||
JETZT NUR AM GERAET ... ft=yes ft-over-ds=no name=sec-main
|
||||
IM SNAPSHOT, FEHLT ... ft=yes ft-over-ds=yes name=sec-main
|
||||
```
|
||||
|
||||
### Abnahme
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| `ft-over-ds` am Core | **`ft=yes ft-over-ds=yes`** ✓ |
|
||||
| CAPs | 3 × `Ok`, CAPWAP-Verbindung **ununterbrochen** (17 h) — `provision` trennt sie nicht |
|
||||
| VAPs **am CAP** gelesen | ap2 **9/9** `running`, ap3 **9/9** `running` |
|
||||
| **Frische DHCP-Lease** (die vorgeschriebene Abnahme) | iPhone `10.40.10.196`, `bound`, `expires-after 23h58m56s` bei 24 h Laufzeit ⇒ **~1 min alt** |
|
||||
| Clients | 25 → 28 zurück |
|
||||
| Transaktion | `gc-transaktion.py status` → **`zurueckgebaut`**, kein Drift im Scope |
|
||||
| Compliance | **140/140, 0 Drifts** — ohne jede Template-Änderung, wie vorhergesagt |
|
||||
|
||||
### ⚠️ Zwei Nebenbefunde beim Compliance-Lauf
|
||||
|
||||
**1. `gc-configplan.py --refresh-compliance` scheitert STILL, wenn `NAUTOBOT_TOKEN` fehlt** —
|
||||
Ausgabe „NAUTOBOT_TOKEN nicht gesetzt", danach **Exit-Code 0**. Wer nur den Rückgabewert prüft,
|
||||
hält einen nie gelaufenen Compliance-Check für erfolgreich. Behelf in dieser Session:
|
||||
```bash
|
||||
NAUTOBOT_TOKEN="$(sed -n 's/^[[:space:]]*-[[:space:]]*NAUTOBOT_SUPERUSER_API_TOKEN=//p' \
|
||||
docs/nas-vlan20/stacks/210-nautobot.yml | head -1)" python3 nautobot/gc-configplan.py --refresh-compliance
|
||||
```
|
||||
Dauerhafte Antwort wäre `NAUTOBOT_TOKEN` in `~/.secrets/exports.zsh` (steht schon im Handoff vom
|
||||
31.08. als offener Punkt). ⇒ **Der Exit-Code gehört gefixt**, sonst wiederholt sich das.
|
||||
|
||||
**2. Die Compliance-Zahl ist von 135 auf 140 gestiegen — das ist erklärt, nicht übergangen.**
|
||||
Es gibt jetzt **28 ComplianceRules** statt 27 (5 Geräte × 28 = 140). Neu ist **`interface-veth`**,
|
||||
angelegt **2026-08-31 20:04**, also **nach** der Session vom 31.08. und **nicht** in dieser hier.
|
||||
🔴 **Wer sie angelegt hat, ist offen** — `veth` betrifft Container auf RouterOS. Bitte klären,
|
||||
bevor jemand die Zahl als Basislinie zitiert.
|
||||
|
||||
## 🔴 Die `cap-wifiN`-Karte ist beim Provisionieren SOFORT wieder gewandert
|
||||
|
||||
Innerhalb dieser Session, zwischen zwei Reads im Abstand von Minuten:
|
||||
|
||||
| | vor dem Rückbau (galt 31.08. 14:52 – 01.09. 08:2x) | **ab jetzt** |
|
||||
|---|---|---|
|
||||
| ap3 | `cap-wifi3` / `cap-wifi4` | `cap-wifi3` / **`cap-wifi5`** |
|
||||
| ap2 | `cap-wifi5` / `cap-wifi6` | **`cap-wifi4`** / `cap-wifi6` |
|
||||
| ap1 | `cap-wifi1` / `cap-wifi2` | **getauscht** (`cap-wifi2` / `cap-wifi1`) |
|
||||
|
||||
Belastbar ist nur die **`radio-mac`**, weil sie am Gerät hängt:
|
||||
`ap3 …:9F` = 5 GHz → `cap-wifi3` · `ap3 …:A0` = 2,4 GHz → `cap-wifi5` ·
|
||||
`ap2 …:3E` → `cap-wifi4` · `ap2 …:3F` → `cap-wifi6` · `ap1 …:E5` → `cap-wifi2` · `…:E6` → `cap-wifi1`
|
||||
*(Bandzuordnung für ap2/ap1 in dieser Session **nicht** nachgemessen — nicht raten.)*
|
||||
|
||||
⚠️ **Folge für die Auswertung:** Logzeilen vom 01.09. **vor** ca. 08:25 gehören zur linken Spalte.
|
||||
Sie sind zuschreibbar, weil im ganzen Messfenster **0 `caps`-Ereignisse** standen — das war
|
||||
Glück, kein Verdienst.
|
||||
|
||||
## Die Messung am 2026-09-02
|
||||
|
||||
```bash
|
||||
ssh root@10.40.20.100 "pct exec 400 -- sh -c '
|
||||
D=/opt/tp5-syslog/log/10.40.20.1;
|
||||
echo -n \"caps: \"; grep -c \" caps,\" $D/2026-09-02.log;
|
||||
echo -n \"reauth: \"; grep reauthenticating $D/2026-09-02.log | grep -c E1:AF:09;
|
||||
echo -n \"iPhone da? \"; grep -c E1:AF:09 $D/2026-09-02.log'"
|
||||
```
|
||||
**Reihenfolge einhalten:** erst `caps` (Rejoins erzeugen Bursts, die wie ein Client-Problem
|
||||
aussehen), dann `reauth`, dann die Anwesenheitsprobe. Vergleichszeitraum ist **07:00–08:00** —
|
||||
dort standen am 31.08. 79 Ereignisse, am 01.09. null.
|
||||
|
||||
| Ergebnis | Schluss | Nächster Schritt |
|
||||
|---|---|---|
|
||||
| weiter ~0 | **7.24.1 hat es behoben**, Hebel 1 war wirkungslos | Fund E schließen; offen bleibt das Band-Ping-Pong (s. u.) |
|
||||
| Hämmern kommt zurück | Hebel 1 hat doch beigetragen | neue Transaktion, `ft-over-ds=no` erneut — diesmal auf 7.24.1 **isoliert** |
|
||||
|
||||
## Neues Symptom, das die Reauth-Schleife ablöst: Band-Ping-Pong
|
||||
|
||||
Am 01.09. hämmert nichts mehr, aber das iPhone oszilliert zwischen den **beiden Bändern desselben
|
||||
AP** (alte Karte, also ap3 5 GHz ↔ ap3 2,4 GHz):
|
||||
```
|
||||
01:49:14 ap3-2,4G → ap3-5G (−65)
|
||||
01:49:32 ap3-5G → ap3-2,4G (−55) ← 18 s später zurück
|
||||
01:50:28 ap3-2,4G → ap3-5G (−69)
|
||||
07:45 / 07:46 / 07:47 dasselbe im Minutentakt
|
||||
```
|
||||
Verbindungsalter beim Nachsehen: **1:26 min** bei −72 dBm. Das ist kein Auth-Problem mehr, sondern
|
||||
genau das, wofür **Hebel 3 (`2g-probe-delay=yes`)** gedacht war. **Nicht** in diesem Durchgang.
|
||||
|
||||
## ⚠️ Zwei Anomalien aus dem Gesamtlog — eigener Durchgang, nicht nebenbei
|
||||
|
||||
**1. Das Log besteht zu 98,4 % aus Rauschen.** 5457 von 5548 Zeilen sind Firewall-Drops, davon
|
||||
**3810 MNDP-Broadcasts (udp/5678) der eigenen Netzgeräte** (ap1/ap2/ap3/branch, je ~950/Tag).
|
||||
Nutzsignal 1,6 % — in genau dem Log, das unser Diagnosewerkzeug ist.
|
||||
|
||||
**2. 🔴 IGMP aus VLAN30 wird verworfen** (funktional, nicht kosmetisch):
|
||||
```
|
||||
in:vlan30 proto 2, 10.40.30.211->224.0.0.251
|
||||
in:vlan30 proto 2, 10.40.30.215->224.0.0.251
|
||||
```
|
||||
Membership-Reports für die **mDNS-Gruppe** von zwei IoT-Geräten. Der Core betreibt
|
||||
`mdns-repeat-ifaces` — er verwirft also Anmeldungen für genau den Dienst, den er weiterreichen
|
||||
soll. Kandidat für Matter/HomeKit-Discovery-Probleme (TP12.1).
|
||||
|
||||
**3. Nebenbefund zur Hypothese:** `dirtyvader-iot` (mit `ft=no`) hatte am 31.08. **7
|
||||
`reauthenticating`**, und `association rejected, no cached PMK` tritt dort ebenfalls auf. Die
|
||||
ursprüngliche Trennschärfe „93/93 nur auf der `ft=yes`-SSID" galt für die Nacht-Baseline, **nicht
|
||||
für den vollen Tag**. `no cached PMK` ist PMKSA-Caching und nicht FT-spezifisch.
|
||||
|
||||
## Unverändert offen
|
||||
|
||||
1. TP25-Messrunde mit Rundgang (`bash docs/tp25-runde.sh`) — **Terrasse und Arbeitszimmer**;
|
||||
`ap-map` dabei neu einfrieren (s. o., sie wandert bei jedem Provision).
|
||||
2. Passwort-Rotation TP30 (Admin-PW am 08-30 verbrannt).
|
||||
3. ap1-Umzug ans Sideboard (`core ether3`, `5260/Ce`, Frequenz-**Liste**, `tx-power` vorher messen).
|
||||
69
docs/handoff-20260901-n8n-mcp-ssrf.md
Normal file
69
docs/handoff-20260901-n8n-mcp-ssrf.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Handoff 2026-09-01 — n8n-mcp SSRF-Block ✅ GEFIXT + in Portainer-Stack 174 gefaltet
|
||||
|
||||
## Kontext
|
||||
Aus TP10 (Terpenfinder Auto-Refresh, Repo `blaueblueten-n8n`) ausgelagerter bf-infra-Task:
|
||||
der n8n-MCP war einsatzfähig, aber seine Anbindung an die **n8n-API** war blockiert. Diese
|
||||
Session hat den Blocker behoben und die Container-Definition sauber verortet.
|
||||
|
||||
## Befund (Ausgangslage)
|
||||
- **Netz war nie das Problem:** aus dem `n8n-mcp`-Container erreichten **beide** Wege n8n —
|
||||
intern `http://n8n:5678` → HTTP 200, öffentlich `https://n8n.emsenhuber.net/healthz` → HTTP 200.
|
||||
- **Einziger Blocker = App-eigener SSRF-Guard** von n8n-mcp (v2.57.1 → nach Redeploy 2.77.0):
|
||||
`N8N_API_URL=http://n8n:5678` löst auf die private Docker-Bridge-IP `172.19.0.3` auf, und der
|
||||
Guard lehnte private IPs im Default-Modus `strict` ab (`SSRF protection: Private IP addresses
|
||||
not allowed`, `connected:false`). Der API-Client validiert `N8N_API_URL` über genau diesen
|
||||
Guard (`/app/dist/services/n8n-api-client.js:104` → `SSRFProtection.validateWebhookUrl`).
|
||||
- **SSoT-Drift (mit-gefixt):** der laufende Container war ein **Waise** aus
|
||||
`~/dev/homelab-cline/n8n-mcp-deploy/docker-compose.yml` (kein Git-Repo), und dieses File stimmte
|
||||
mit dem laufenden Container nicht überein (File: `https://n8n.emsenhuber.net` + Netz `web`;
|
||||
Container: `http://n8n:5678` + Netz `n8n_default`). `n8n`+`n8n-redis` liefen dagegen im
|
||||
Portainer-Stack **174** (`n8n`, Endpoint 20 = macmini).
|
||||
|
||||
## Fix (durchgeführt 2026-09-01)
|
||||
Entscheidung (User): **intern + permissive**, und **n8n-mcp in Portainer-Stack 174 falten**.
|
||||
|
||||
1. **SSRF entschärft:** `WEBHOOK_SECURITY_MODE=permissive` gesetzt → private/LAN-IP für
|
||||
`N8N_API_URL=http://n8n:5678` erlaubt. Bleibt auf der Docker-Bridge, **kein** CF/Tunnel/Caddy-
|
||||
Umweg, keine 10-s-DNS-Falle, unabhängig von der Edge. Vertretbar, weil dieser Container
|
||||
ausschließlich mit dem trusted LAN-n8n redet.
|
||||
2. **Waise beseitigt:** orphan-Container entfernt (`docker rm -f n8n-mcp`), n8n-mcp als **dritter
|
||||
Service** in Stack 174 aufgenommen (neben `n8n`+`redis`, gemeinsames Default-Netz `n8n_default`,
|
||||
`depends_on: n8n`). Stack via Portainer-API redeployt (`PUT /api/stacks/174?endpointId=20`,
|
||||
`prune:false`).
|
||||
3. **Erhalten geblieben:** Bearer (`AUTH_TOKEN`==`MCP_AUTH_TOKEN`, len 64) **unverändert** →
|
||||
bestehende Clients (opencode `http://10.40.20.167:3001/mcp`) laufen weiter; Host-Port-Bind
|
||||
`10.40.20.167:3001:3000` → Caddy-Route `n8n-mcp.emsenhuber.net` (Caddyfile Z. 75) intakt;
|
||||
Daten-Volume als **`external`** wiederverwendet (`n8n-mcp-deploy_n8n-mcp-data`, `nodes.db`
|
||||
bleibt) — eigener `N8N_API_KEY` von n8n-mcp (≠ n8n) unverändert.
|
||||
|
||||
## Verifikation (nicht behauptet — gemessen)
|
||||
- `SSRFProtection.validateWebhookUrl("http://n8n:5678")` im Container → `valid:true`,
|
||||
`resolved:172.19.0.3`, `mode:permissive`.
|
||||
- MCP-Tool `n8n_health_check` (voller Handshake) → `{"success":true,"status":"ok",
|
||||
"apiUrl":"http://n8n:5678","mcpVersion":"2.77.0","upToDate":true}`.
|
||||
- `n8n`+`n8n-redis` behielten Container-ID **und** `StartedAt` (2026-07-29) → **kein n8n-Downtime**
|
||||
beim Redeploy (nur der neue Service wurde erstellt).
|
||||
|
||||
## SSoT / Ablage
|
||||
- **Master der Stack-Definition = Portainer-Stack 174** (`n8n`, Endpoint 20, macmini).
|
||||
- Gitignored Repo-Mirror + Rollback: `docs/macmini-vlan20/stacks/174-n8n.yml` (neuer Stand) und
|
||||
`…/174-n8n.orig-pre-mcp-fold-20260901.yml` (Vorzustand). Neu gitignored: `docs/macmini-vlan20/stacks`.
|
||||
- INVENTORY-Eintrag `mcp/INVENTORY.md` (n8n-mcp) aktualisiert.
|
||||
|
||||
## Offene Punkte
|
||||
- 🔴 **TP30 Posten #8:** beim Ausgeben des Stack-174-Files ist `N8N_SMTP_PASS` (Gmail-App-PW
|
||||
`johnny.claw.0x00@gmail.com`) ins Transkript geraten (Redaktionsmuster hatte `PASSWORD`, nicht
|
||||
bare `PASS`). **Rotation fällig** — Google App-Passwort widerrufen + Stack-174-Env nachziehen.
|
||||
- ⚠️ **Toter Orphan:** `~/dev/homelab-cline/n8n-mcp-deploy/` (kein Git) kann gelöscht werden — ein
|
||||
erneutes `docker compose up` dort würde sonst einen Namenskonflikt mit dem Stack-174-Container
|
||||
erzeugen. Nicht kritisch (nur bei Handstart).
|
||||
- ⚠️ **Client-401 in THIS Claude-Code-Session:** der n8n-mcp-Server kam in dieser Session mit
|
||||
`AUTH_HEADER_REJECTED` (401) hoch — das ist ein **Client-Config-Thema** (`~/.claude.json`-Bearer
|
||||
leer/falsch, vgl. globale CLAUDE.md „kein Shell → `{env:}` leer"), **nicht** der hier gefixte
|
||||
Server. Der Server antwortet LAN-direkt korrekt; opencode ist unbetroffen.
|
||||
|
||||
## Auswirkung auf TP10
|
||||
Keine für den Feature-Pfad: TP10 läuft über **Cloudflare Worker Cron**, nicht über n8n. Der Fix
|
||||
macht n8n-mcp aber wieder als **Werkzeug** nutzbar (n8n-Workflow-Validierung, künftig optional
|
||||
TP10-als-n8n-Workflow). Rückantwort ans zuweisende Projekt:
|
||||
`~/dev/blaueblueten-n8n/docs/rueckantwort-n8n-mcp-fix-20260901.md`.
|
||||
130
docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md
Normal file
130
docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# 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).
|
||||
54
docs/handoff-20260901-tp25-ap2-verdacht.md
Normal file
54
docs/handoff-20260901-tp25-ap2-verdacht.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Handoff 2026-09-01 — TP25: Fund E geheilt (sauberes Fenster) + neuer Verdacht `ap2`
|
||||
|
||||
**Kontext:** Christoph meldete um **2026-08-31 23:02** eine WLAN-Störung am Schreibtisch (5G, iPhone,
|
||||
kein Telefonat). Diese Session hat den Vorfall am Manager `crs326-core` analysiert (alles read-only)
|
||||
und dabei den Fund-E-Stand korrigiert. Parallel wurde TP39 abgeschlossen (eigener Strang, s. Archiv).
|
||||
|
||||
## Kernbefunde
|
||||
|
||||
### 1. Fund E (`reauthenticating`) ist geheilt — die „GESCHEITERT"-Wertung war kontaminiert
|
||||
- Core-Uptime `10h41m` @ 01:18 ⇒ letzter Reboot **14:36** (TP27-Upgrade). Der `caps`-Log endet um
|
||||
15:57; um 23:02 **kein** caps-Ereignis ⇒ kein Infrastruktur-/Reboot-Burst, echtes Client-Event.
|
||||
- **Tages-Query** `get_log topics=[wireless] prefix=reauthenticating sinceMinutes=1440` → **total 0**.
|
||||
Das erste ungestörte Fenster (14:36 → 01:20, **10,7 h**) zeigt **0× reauthenticating**; Baseline 93×.
|
||||
- Die im Vorgänger-Handoff notierten „124× nach dem Eingriff" fielen in die TP27-Upgrade-Reboots
|
||||
(viele MACs = Infrastruktur, CLAUDE.md-Gotcha). ⇒ **Hebel 1 (`ft-over-ds=no`) hat sein Ziel erreicht.**
|
||||
|
||||
### 2. Neuer Teilbefund: `ap2` unterperformt (das ist der 23:02-Schmerz, NICHT FT)
|
||||
AP-Karte (Manager, stabil seit Rejoin 15:57): `cap-wifi5/6 = ap2`, `cap-wifi3/4 = ap3`,
|
||||
`cap-wifi1/2 = ap1` (funkstill).
|
||||
|
||||
- 23:02: iPhone `F2:62:4C:E1:AF:09` ping-pongt im Sekundentakt `cap-wifi5 ↔ cap-wifi6` =
|
||||
**ap2s 5G (5220) ↔ ap2s 2,4G (ch11/2462)** — Band-Steering-Thrash auf **demselben** AP.
|
||||
`disconnected, not responding` um 22:37:40 (−76) und **23:01:00** (−82). Roam-Feldstärke −75…−88 dBm.
|
||||
- 🔴 **Christophs Fakt:** iPhone ↔ ap2 nur **2 m**, gleicher Raum, ap2 auf 2,3 m. Bei 2 m wären
|
||||
−35…−45 dBm normal. −80 auf 2 m ⇒ **kein Coverage-, kein FT-Problem**.
|
||||
- **0 Clients auf ap2 aktuell**, alle 29 auf ap3 → die Clients meiden ap2.
|
||||
- Verdacht: **ap2s Funk selbst** (RF/Antenne/HW) und/oder **DTU-Störung auf ap2/ch11**
|
||||
(Transaktion `TP17.1-dtu-pin-ap2`, `54:F2:9F:12:51:F0`, −59 dBm auf ap2s 2,4-Radio).
|
||||
|
||||
**In-situ-Diagnose nötig** (nachts nicht messbar, Phone idle auf ap3): Registration-Signal live prüfen,
|
||||
während ein Client auf ap2 hängt. Kandidaten-Eingriffe: DTU-Pin lösen/verlegen; `dirtyvader-main` auf
|
||||
ap2 temporär deaktivieren (ap3 übernimmt Schreibtisch); ap2-Antenne/HW prüfen. **Keine Änderung ohne
|
||||
diese Messung.**
|
||||
|
||||
## Offen / nächster Schritt
|
||||
|
||||
**Hebel 1 committen** (Transaktion `TP25-fund-e-ft-over-ds`, Scope `wifi-security`, Ablauf 2026-09-03).
|
||||
Der Commit ist eine **git-push-Kette** und wartet auf Christophs Go:
|
||||
|
||||
1. `nautobot/mikrotik_routeros.j2` **Z. 220**: `sec-main` `ft-over-ds=yes` → `ft-over-ds=no`.
|
||||
2. Template-Repo nach Nautobot syncen (Golden-Config-Git-Repository).
|
||||
3. `python3 nautobot/gc-configplan.py --refresh-compliance` (Backup → Intended → Compliance).
|
||||
4. `python3 nautobot/gc-transaktion.py commit --change-id TP25-fund-e-ft-over-ds`
|
||||
(verweigert, solange `wifi-security` noch driftet — deshalb Schritt 1–3 zuerst).
|
||||
|
||||
🔴 Schritt 1 ist ein `git push` (Backup-Guard + Christophs Commit-Hinweis-Regel) und Schritt 2–4 sind
|
||||
Live-Nautobot-Jobs — bewusst **nicht autonom** ausgeführt. Geräte-Backup `pre-tp25-funde-ftoverds.backup`
|
||||
liegt auf dem Core. `wifi-security` wird ohnehin **nicht deployt** (Passphrasen `<<REDACTED>>` im
|
||||
Template, Z. 189–196) — der Commit ist reine Soll↔Live-Angleichung, kein Geräte-Write.
|
||||
|
||||
## Werkzeug-Notiz
|
||||
- AP-Zuordnung: `/interface wifi radio print terse proplist=cap,radio-mac,interface` am Manager.
|
||||
- reauth-Zählung: `get_log` mit `prefix=reauthenticating` (nicht `list_wifi_interfaces` — leakt PSKs).
|
||||
- Kanäle: `/interface wifi print detail` je `cap-wifiN` (Frequenz + Band im `channel.`-Block).
|
||||
109
docs/handoff-20260901-tp41-followup.md
Normal file
109
docs/handoff-20260901-tp41-followup.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Handoff 2026-09-01 — TP41 Follow-up: IdP-Feinschliff, App-Launcher, Geli-Zugänge, dw-DNS
|
||||
|
||||
> Kleine Folgesession nach TP41 (T4/T3/T2 durch). Sammelt die Rest-Punkte rund um **Logins für Geli**,
|
||||
> die **App-Launcher-Seite** und den **dw-Split-Horizon** für Terpenfinder. Mehrere Punkte sind
|
||||
> **User-Konsolen-Aufgaben** (Google/Meta), dafür je eine Kurzanleitung.
|
||||
|
||||
## Status je Punkt (Stand dieser Session)
|
||||
| # | Punkt | Stand |
|
||||
|---|---|---|
|
||||
| 1 | GitHub-Login | ✅ funktioniert (User bestätigt) |
|
||||
| 2 | Google „Zugriff blockiert: nur innerhalb der Organisation" | ✅ **gefixt** — User hat Consent-Screen auf *External* gestellt; Google-Login läuft (bestätigt 2026-09-01). Anleitung §A war der Weg. |
|
||||
| 3 | Meta/Facebook einbinden | ❌ **für TP41 abgesagt** (User-Entscheid 2026-09-01) — optional, kein Bedarf. Keine App, kein CF-IdP angelegt. Geli via OTP+Google voll gedeckt. §B nur noch als Anleitung, falls später gewünscht. |
|
||||
| 4 | Geli-Zugänge hinterlegen | ✅ `pillepalle670@gmail.com` in `zt-humans`. **FB-Konto-Mail = `angelikahy@outlook.de`** (schon drin → Facebook automatisch abgedeckt, sobald Meta läuft). Instagram = kein CF-IdP. |
|
||||
| 5 | App-Launcher überarbeiten | ✅ **D1 umgesetzt** — 3 Bookmark-Kacheln (Vaultwarden/Home Assistant/Terpenfinder), Bundle-/Wildcard-/Terpene-self_hosted-Kacheln aus dem Launcher genommen (Policies **unverändert** geprüft), Launcher gestylt (Titel „BF-Zugänge", Begrüßung, Buttons). |
|
||||
| 6 | `420.teilzeitladen.xyz` an dw | ✅ **Entscheidung:** Geli sofort per **WARP**; das dw-Site-DNS-Uplink-Thema → **TP43** (angelegt). |
|
||||
|
||||
---
|
||||
|
||||
## §A — Google-Login-Fix (User, Google Cloud Console)
|
||||
Fehler „cloudflare kann nur innerhalb der Organisation verwendet werden" = der **OAuth-Consent-Screen**
|
||||
des Google-Projekts steht auf **User Type = Internal** (nur Workspace-Org-Konten). Gelis Gmail ist extern
|
||||
→ blockiert. Fix (der CF-Google-IdP `c757…` bleibt unverändert, nur die Consent-Einstellung ändert sich):
|
||||
1. <https://console.cloud.google.com> → richtiges Projekt (das, aus dem die Google-OAuth-Client-ID stammt).
|
||||
2. **APIs & Services → OAuth consent screen** (neu: „Google Auth Platform → Audience").
|
||||
3. **User Type / Audience von *Internal* auf *External*** stellen.
|
||||
4. **Veröffentlichen:** Publishing status → **„In production"** (dann kann jedes Google-Konto rein).
|
||||
Alternativ in „Testing" bleiben und **Gelis Gmail als Test user** eintragen.
|
||||
5. Danach Login-Test mit Gelis Google-Konto. (Bei „External/unverified" kommt ggf. ein
|
||||
„unbestätigte App"-Hinweis — für den kleinen Kreis unkritisch, oder App verifizieren lassen.)
|
||||
|
||||
## §B — Meta/Facebook als Login (User legt App an, dann CF-IdP durch mich)
|
||||
Es gibt **noch keine** Facebook-App (Creds leer). Schritte:
|
||||
1. <https://developers.facebook.com> → **My Apps → Create App** → Use case **„Authenticate and request
|
||||
data from users with Facebook Login"** (Consumer).
|
||||
2. Produkt **Facebook Login** hinzufügen.
|
||||
3. **Facebook Login → Settings → Valid OAuth Redirect URIs** =
|
||||
`https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback`
|
||||
4. **App settings → Basic:** **App ID** + **App Secret** → an mich (in `~/.secrets`, **nicht** in den Chat),
|
||||
ich trage sie in `mcp/cloudflare/.env` (`FACEBOOK_APP_ID/SECRET`) ein und lege den CF-Facebook-IdP an.
|
||||
5. **App Mode → Live** (sonst dürfen nur App-Rollen/Tester rein); Geli ggf. als Tester eintragen.
|
||||
6. ⚠️ CF matcht die Policy über die **E-Mail**, die Facebook zurückgibt — diese E-Mail muss in
|
||||
`zt-humans` stehen (s. §C).
|
||||
|
||||
## §C — Geli: Zugangsmethoden (Matrix)
|
||||
CF Access matcht Personen über die **E-Mail** der Identität (nicht über Usernamen). Stand:
|
||||
| Methode | Gelis Angabe | CF-Status | To-Do |
|
||||
|---|---|---|---|
|
||||
| OTP (E-Mail-Code) | `angelikahy@outlook.de` | ✅ in `zt-humans` | — |
|
||||
| OTP + Google | `pillepalle670@gmail.com` | ✅ **heute ergänzt** | Google-Fix §A nötig, damit Google-Login geht |
|
||||
| Facebook | User `35Lika.Ange` | ⏳ | Facebook-App (§B); dann die **E-Mail** ihres FB-Kontos in `zt-humans` — welche ist das? (vermutlich eine der beiden obigen) |
|
||||
| Instagram | `angelikahy` | ❌ **CF Access hat keinen Instagram-IdP** | Nicht möglich als Direkt-Login → Geli nutzt Facebook/Google/OTP |
|
||||
|
||||
→ Sobald Gelis FB-Konto-E-Mail bekannt ist und sie eine der schon hinterlegten Adressen ist, ist Facebook
|
||||
automatisch abgedeckt. Sonst diese E-Mail zusätzlich in `zt-humans` aufnehmen.
|
||||
|
||||
## §D — App-Launcher `emsenhuber.cloudflareaccess.com` überarbeiten
|
||||
**Ist-Analyse (live):** Der Launcher (App `6df5c431`, `landing_page_design={}` = ungestylt) zeigt Kacheln
|
||||
aus den Access-Apps mit `app_launcher_visible=true`:
|
||||
- `1dbc45ca` **„hass, vw, gitea"** (self_hosted, Domain `vw.emsenhuber.net`) → **eine** Kachel, verlinkt nur vw.
|
||||
- `16aaec78` **`*.emsenhuber.net`** (Wildcard) → Kachel ohne sinnvolles Ziel.
|
||||
- `e6a7991f` **Terpenfinder v3** (`420.teilzeitladen.xyz`) → eigene Kachel ✅.
|
||||
Deshalb „stimmt nicht mehr": vw/hass/gitea teilen sich eine Kachel, die Wildcard-Kachel stört.
|
||||
|
||||
**Ziel:** je ein sauberer Button für **Vaultwarden, Home Assistant, Terpenfinder** + freundlichere Seite.
|
||||
**Zwei Wege (Entscheidung offen):**
|
||||
- **D1 — CF-nativ (empfohlen, „diese Seite"):** je ein **Bookmark-App** (type `bookmark`) für vw/hass/
|
||||
terpenfinder mit Name + Logo (eigene Kachel/Link), die Wildcard-Kachel aus dem Launcher nehmen,
|
||||
`landing_page_design` setzen (Titel z.B. „BF-Zugänge", Begrüßung, Farbe, Logo). Reversibel, in Minuten.
|
||||
Grenze: CF-Styling = Titel/Text/Farbe/Logo + uniforme Kacheln.
|
||||
- **D2 — Custom-Landing-Page:** eigene HTML-Seite (Caddy, hinter Access) mit voller Gestaltung/großen
|
||||
Buttons. Mehr Design, mehr Aufwand (eigener vhost + Access-Regel).
|
||||
|
||||
## §E — dw: `420.teilzeitladen.xyz` lokal auflösen (FritzBox `10.95.10.1`)
|
||||
**Ehrliche FritzBox-Antwort:** Eine FritzBox kann **keinen** freien „Hostname → beliebige IP"-Override im
|
||||
GUI (nur *DNS-Rebind-Schutz-Ausnahmen* = Whitelist gegen Rebind-Blockade, **ohne** IP-Zuweisung). Ein
|
||||
sauberer Split-Horizon für genau diesen Namen braucht daher einen **kleinen lokalen Resolver** am dw
|
||||
(dnsmasq/AdGuard/Pi-hole auf einem Dauerläufer): `address=/420.teilzeitladen.xyz/<BF-Caddy-über-WG>` +
|
||||
Rest weiterleiten; diesen Resolver als DNS der FritzBox bzw. der Clients setzen.
|
||||
⚠️ **Vor Umsetzung verifizieren** (nicht aus dem Kopf): FritzOS-Version am dw + ob ein Dauerläufer da ist.
|
||||
**BF-seitige Prereqs (fehlen noch):**
|
||||
1. **Caddy-vhost** `420.teilzeitladen.xyz` → macmini-Worker (`10.40.20.167:8890`) **mit Cert**
|
||||
(DNS-01, `…4148` hat jetzt teilzeitladen.xyz-DNS).
|
||||
2. **WG-Route** dw → `10.40.20.40` (Caddy) muss stehen.
|
||||
3. **Split-Horizon** für `420.teilzeitladen.xyz` (heute liefern auch `.36/.37` **public** für diesen Namen).
|
||||
Cross-Projekt (teilzeitladen.xyz). Alternative aus Ur-Handoff: Gelis Gerät in **WARP** (Session statt Login,
|
||||
CGNAT unkritisch) + Access-Policy auf die WARP-Identität — spart den ganzen dw-DNS-Umbau.
|
||||
|
||||
## Entscheidungen (2026-09-01, getroffen)
|
||||
1. **App-Launcher:** ✅ **D1** (CF-nativ) — umgesetzt (s. §D / Punkt 5).
|
||||
2. **Gelis Facebook-Mail:** ✅ `angelikahy@outlook.de` — schon in `zt-humans`, Facebook damit abgedeckt.
|
||||
3. **dw-Ansatz:** ✅ Geli per **WARP** (sofort); Site-DNS-Uplink als **TP43** ausgelagert.
|
||||
|
||||
## Verbleibende offene To-Dos (User)
|
||||
- ~~**§A Google-Consent-Screen** auf *External*~~ ✅ **erledigt** — Google-Login läuft (2026-09-01).
|
||||
- ~~**§B Facebook-App anlegen**~~ ❌ **abgesagt für TP41** (User-Entscheid 2026-09-01) — optional; §B
|
||||
bleibt als Anleitung stehen, falls später doch gewünscht.
|
||||
- ~~**d47435-Revoke**~~ ✅ erledigt · ~~**T3-WARP-Client-Verify**~~ ✅ ok (User, 2026-09-01).
|
||||
- **Geli in WARP:** ✅ **CF-seitig nichts zu tun** — Enrollment läuft über App „Warp Login App"
|
||||
(`6c32fe23…`) → `bf-users` → Gruppe `zt-humans`, die Gelis Mails **schon enthält**; sie darf bereits
|
||||
enrollen. Terpenfinder-`geli`-Policy lässt sie per E-Mail durch. **Rest = Handgriff auf Gelis Gerät:**
|
||||
WARP installieren, Team `emsenhuber`, Login OTP `angelikahy@outlook.de` oder Google `pillepalle670@gmail.com`.
|
||||
*Permission-Frage:* CF-seitig keine nötig; `/access/seats` per MCP nicht nutzbar (`10405`, Endpoint will
|
||||
User-Token statt Account-Token — kein Scope-Fix, für Enroll irrelevant).
|
||||
- **T5 (TP41)** ✅ GitHub- **und** Google-Login laufen (bestätigt).
|
||||
- **TP43** (dw-Site-DNS) bei Gelegenheit.
|
||||
|
||||
> **TP41-Auth-Kern damit abgeschlossen (2026-09-01):** T2/T3/T4/T5 ✅, FB abgesagt, d47435-Revoke ✅,
|
||||
> WARP-Verify ✅, Geli CF-seitig fertig. **Nichts mehr auf Claude-/CF-Seite offen** — verbleibt nur
|
||||
> Gelis WARP-Client auf ihrem Gerät.
|
||||
166
docs/handoff-20260901-tp41.md
Normal file
166
docs/handoff-20260901-tp41.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# Handoff 2026-09-01 — TP41 CF-Access-Reparatur + Zero-Trust-Konsolidierung
|
||||
|
||||
> **Branch `tp41-cf-access-repair`.** Alle CF-Änderungen sind **live via API** gemacht (Schreibpfad
|
||||
> `CF_API_TOKEN` + curl, cf-tunnel-mapping.md §11). Working-Tree: `docs/cf-backup/tp41-20260901/`
|
||||
> (Snapshots, secret-frei) + dieser Handoff + `teilprojekte.md`-Eintrag; `mcp/cloudflare/.env`
|
||||
> (gitignored) wurde geändert (Token-Konsolidierung). Helper-Skripte lagen im Scratchpad/`/tmp`
|
||||
> (`cf_session.py`, `cf_harden.py`, `cf_groups.py`, `cf_vwadmin.py`, `cf_carveout.py`, `t4a.py`).
|
||||
|
||||
## Auslöser
|
||||
Zugriff auf CF-geschützte Apps zwang Christoph **und Geli** faktisch **täglich** zum E-Mail-OTP-Login,
|
||||
obwohl 30 Tage gelten sollten; föderierte Logins (GitHub/Google) „funktionieren nicht". Root-Causes:
|
||||
(1) **Team-Domain-Rename `bf4` → `emsenhuber`** ⇒ Provider-OAuth-Apps kennen die neue Callback-URL nicht;
|
||||
(2) App-**Session 24h**; (3) diverse Ordnungs-/Sicherheitslecks. Daraus wurde eine
|
||||
Zero-Trust-Konsolidierungs-Runde.
|
||||
|
||||
## ✅ LIVE erledigt (verifiziert)
|
||||
- **Session 720h** auf Wildcard (`16aaec78`), vw-App (`1dbc45ca`), Warp-Login (`6c32fe23`).
|
||||
- **login_method-Loch geschlossen:** reusable Policy **`bf-users` (`4ccc9b7e`)** = `allow` mit **nur**
|
||||
`email:christoph@emsenhuber.com` + `email:<geli>@outlook.de` (kein `login_method`-Include mehr).
|
||||
Attached an Wildcard / App-Launcher (`6df5c431`) / Warp-Login. Reusable Policy `8e44f5d1`
|
||||
**entkoppelt** → hängt jetzt **nur noch an Terpenfinder** (Fremdprojekt, nicht angefasst).
|
||||
- **Access-Gruppen (Prefix `zt-`):** `zt-humans` (`6eeec7f3`, christoph+geli), `zt-home`
|
||||
(`c0f8ba0d`, IP `90.146.33.177/32`), `zt-automation` (`1b60b608`, svc-token `65f1821a`).
|
||||
Policies `bf-users` / `bf4` (`5165d139`) / `claude-mcp` (`39fe0e9d`) zeigen jetzt **auf die Gruppen**
|
||||
→ Personen-/IP-/Token-Pflege künftig nur noch in der Gruppe.
|
||||
- **vw = voll Bypass** (Passwort-Lebensader: Web-Vault + Bitwarden-App/Extension/Desktop offen, **kein**
|
||||
CF-Login davor). Ein Carve-out-Versuch (nur Client-Pfade bypass, Rest gaten) wurde **verworfen**:
|
||||
CF-**Bypass kurzschließt** spezifischere path-Apps, und `/` (Web-Vault-Root) teilt den Prefix mit
|
||||
`/admin` — nicht trennbar. Die 3 Experiment-Apps wurden wieder gelöscht.
|
||||
- **`vw.emsenhuber.net/admin` öffentlich geblockt** per **WAF-Custom-Rule** (Zone-Ruleset
|
||||
`416af72d0dd54853805875bf5752afd7`, Regel `f26744eb…`, `action=block`,
|
||||
expr `http.host eq "vw.emsenhuber.net" and (path eq "/admin" or starts_with(path,"/admin/"))`).
|
||||
**Verifiziert über CF-Edge** und vom User per **Mobilfunk** („you have been blocked"). Lokal (Heim-LAN,
|
||||
Split-Horizon → Caddy) und später WARP-intern bleibt `/admin` erreichbar.
|
||||
- **API-Token konsolidiert:** `mcp/cloudflare/.env` `CF_API_TOKEN` = **`…4148`** (id `493ed8bd…`),
|
||||
Backup `mcp/cloudflare/.env.bak-tp41-20260901`. Der User hat `…4148` anschließend **vollständig**
|
||||
gemacht (u.a. **Access: Service Tokens Write** + **Zero Trust Write** + WAF + Groups + DNS für
|
||||
emsenhuber.net **und** teilzeitladen.xyz). **Altes Token `…2174` (id `9984078812bc18d4ebb6a64b570144f2`)
|
||||
ist am 2026-09-01 vom User revoked ✅.**
|
||||
|
||||
> ⚠️ **API-Token-Altlast → ARBEITSPAKET für die Folgesession (User 2026-09-01):** der User fand ein
|
||||
> weiteres API-Token **`b00722522c685920f73cfcc62e9555d9`** mit **exakt denselben Permissions wie
|
||||
> `d47435d5c86b764bbf7c5b19ae827033`** — vermutlich eine **blaueblüten/Terpene-Altlast**.
|
||||
> **Auftrag: Projekte nachziehen** — feststellen, welcher Consumer welches der beiden Tokens nutzt,
|
||||
> auf **eines** konsolidieren, das verwaiste dann abbauen. Token-/Credentials-Hygiene (TP30-nah).
|
||||
|
||||
## 🔜 OFFEN (Token reicht jetzt für alles außer T5)
|
||||
- **T4 — kumulatives Service-Token `zt-svc`** (Basis: `t4a.py`, war nur an fehlender Perm gescheitert):
|
||||
1. `claude-mcp` (`65f1821a`) **rename → `zt-svc`** + **rotate** (Secret einmalig).
|
||||
2. `terpene-svc`-Policy (`bf7d2e5e`) **additiv** += group `zt-automation` (akzeptiert dann alt **und** neu).
|
||||
3. Secret ablegen: `mcp/cloudflare/.env` (`CF_ACCESS_CLIENT_ID/SECRET`) **und**
|
||||
`~/.secrets/credentials.env` — dort auch die Terpene-Aliase **`TERPENE_ACCESS_CLIENT_ID/SECRET`**
|
||||
(die die Tools lesen) **und** `TERPENE_VERIFY_CF_CLIENT_ID/SECRET` (beide zeigten auf terpene-verify-v2).
|
||||
4. **Verify Terpene:** `python3 ~/dev/blaueblueten-n8n/tools/test_whoami.py`
|
||||
(→ `420.teilzeitladen.xyz/api/admin/whoami`, muss weiter funktionieren).
|
||||
5. Erst **nach** grünem Verify: `terpene-verify-v2` aus `terpene-svc` entfernen, dann
|
||||
**`terpene-verify` (`a6be7efa`) + `terpene-verify-v2` (`1082bad1`) löschen**.
|
||||
6. `~/.secrets/README.md`-Index nachziehen. opencode/`exports.zsh` optional (gui-env-sync).
|
||||
→ End: **ein** Service-Token `zt-svc` über Gruppe `zt-automation` in allen Apps + Consumern.
|
||||
- **T3 — WARP löst `emsenhuber.net` intern auf** (User-Wahl „Variante 2"): WARP-Device-Profile
|
||||
`fallback_domains` += `emsenhuber.net` → interner Resolver **`10.40.20.1`** (liefert Split-Horizon
|
||||
`*.emsenhuber.net` → Caddy `10.40.20.40`). Route **`10.40.0.0/16` existiert** (tunnel `d1da7c8a`).
|
||||
Danach `/admin` + alle internen Namen über **WARP** via Caddy erreichbar (kein CF/WAF). ⚠️ **account-/
|
||||
profilweit** → als Lifecycle-Change **proaktiv melden**. (Token hat jetzt Zero-Trust-Write.)
|
||||
- **T2 — 404 statt 403 (User-Wunsch):** WAF-**Custom-Response ist Free-Plan-gesperrt** („not entitled to
|
||||
use a custom response"). 403-Block bleibt — außer man macht es **Origin-seitig in Caddy** (`respond 404`
|
||||
wenn Header `CF-Connecting-IP` gesetzt = via CF gekommen; lokal/WARP-intern ohne Header → durchlassen).
|
||||
Das komponiert sauber mit T3 (WARP-intern trifft Caddy ohne CF-Header). Eigener Caddy-Deploy (LXC 130).
|
||||
- **T5 — IdP-Konsolen (USER-Hausaufgabe, DER Daily-OTP-Fix, bestätigt kaputt):** User-Test lieferte
|
||||
GitHub **„The redirect_uri is not associated with this application"**. Fix in den **Provider-Konsolen**:
|
||||
- **GitHub** OAuth-App `Ov23li2h96hAkGRPJXYV` → *Authorization callback URL*
|
||||
- **Google** OAuth-Client → *Authorized redirect URIs*
|
||||
- beide = **`https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback`**.
|
||||
Danach Login-Test je Provider; Gegenprobe CF-Audit `GET /accounts/…/access/logs/access_requests`
|
||||
(`identity_provider=github/google` statt `onetimepin`).
|
||||
- **T6 (optional) — Rate-Limit:** vw `/identity/connect/token` + gitea-Login. **Kein** Managed-Challenge
|
||||
vor vw-API/`/identity`, git-/api-Pfaden, `assetlinks.json` (bricht Bitwarden-Clients / git / MCP).
|
||||
- **T7 — Doku:** ggf. `docs/tp41-cf-access-repair-runbook.md` (Detail-Runbook) ergänzen.
|
||||
|
||||
## 🆕 NEU — dw/Geli an der Auth vorbei (Terpenfinder, CGNAT)
|
||||
Ziel: dw erreicht `420.teilzeitladen.xyz` **ohne** CF-Login. IP-Bypass wie `bf4` scheitert an Gelis
|
||||
**CGNAT**. **Eleganteste Lösung (User-Idee): Split-Horizon am dw-Standort** — dw-FritzBox setzt lokalen
|
||||
DNS-Override `420.teilzeitladen.xyz` → BF-Caddy (`caddy-bf1` / `10.40.20.40`), erreichbar über den
|
||||
bestehenden **WG-Tunnel dw↔core**; Caddy braucht einen Block `420.teilzeitladen.xyz` → macmini-Worker
|
||||
(`10.40.20.167:8890`) **mit Cert** (DNS-01; Token hat jetzt DNS-Write für `teilzeitladen.xyz`).
|
||||
Vorab prüfen: (a) FritzBox-Host-Override möglich; (b) WG-Route dw→10.40.20.40; (c) Worker wirklich auf
|
||||
`macmini:8890` von Caddy erreichbar. **Cross-Projekt** (teilzeitladen.xyz). Alternative: Geli-Gerät in
|
||||
**WARP** (Session statt Login, CGNAT unkritisch) + Access-Policy auf WARP-Identität.
|
||||
|
||||
## ❓ Scope-Klärung für die neue Session
|
||||
Der User nannte „TP3/TP4/TP5 gleich mitnehmen" — **diese sind laut `teilprojekte.md` abgeschlossen**
|
||||
(TP3 WLAN-Rebuild ✅, TP4 ap1-Router/WAN-Edge ✅, TP5 deny-by-default ✅). Vermutlich Zahlendreher.
|
||||
**Offene Kandidaten:** TP6 (CAKE, Projektziel), TP16.1 (WARP-Mesh nativ), TP16.3, TP24 (DC-USV),
|
||||
TP25 (WLAN-Signal/Re-Walk). **Vor Start klären, welche gemeint sind** (je eigene Session empfohlen;
|
||||
Subagenten nur für parallele, abgegrenzte Teilaufgaben innerhalb einer Session).
|
||||
|
||||
## 🧭 Test-Vantage-Lehre (wichtig, hat hier Stunden gekostet)
|
||||
Von der **Heim-IP** löst `*.emsenhuber.net` → `10.40.20.40` (Caddy) und **umgeht CF komplett** — CF-Access/
|
||||
WAF-Gating ist von zuhause **nicht** sichtbar (alles wirkt „offen"). Edge-Verhalten **erzwingen** mit
|
||||
`curl --resolve <host>:443:<CF-anycast-IP>` (CF-IP via `dig @1.1.1.1 +short <host>`). **WebFetch ist für
|
||||
Access/Redirects unzuverlässig** (erreichte Origin trotz Gating) — **nicht** als Beweis verwenden; echter
|
||||
Remote-Test = User-Gerät im Mobilfunk.
|
||||
|
||||
## Referenz-IDs
|
||||
Apps: Wildcard `16aaec78` · vw/hass/gitea-Bundle `1dbc45ca` · App-Launcher `6df5c431` · Warp-Login
|
||||
`6c32fe23` · Terpenfinder v3 `e6a7991f`. Policies: `bf-users` `4ccc9b7e` · `bf4` `5165d139` · `claude-mcp`
|
||||
`39fe0e9d` · `terpene-svc` `bf7d2e5e` · (Terpene-only) `8e44f5d1`. Gruppen: `zt-humans` `6eeec7f3` ·
|
||||
`zt-home` `c0f8ba0d` · `zt-automation` `1b60b608`. Service-Tokens: `claude-mcp`→`zt-svc` `65f1821a` ·
|
||||
`terpene-verify` `a6be7efa` (Waise) · `terpene-verify-v2` `1082bad1`. WAF: Ruleset `416af72d…`, Regel
|
||||
`f26744eb…`. Team-Domain `emsenhuber.cloudflareaccess.com` (Org-`name`-Altlabel `bf4…` nicht anfassen).
|
||||
|
||||
---
|
||||
|
||||
## ✅ Update — Folgesession 2026-09-01 (T4 durch, Token-Altlast geklärt, Drift-Korrekturen)
|
||||
|
||||
### T4 — zt-svc ✅ DURCH (Variante B, inkl. Worker)
|
||||
- `claude-mcp` (`65f1821a`) → **`zt-svc`** umbenannt **und rotiert** (Secret in
|
||||
`mcp/cloudflare/.env` `CF_ACCESS_CLIENT_ID/SECRET` + `~/.secrets/credentials.env`; dort
|
||||
`TERPENE_ACCESS_*` und `TERPENE_VERIFY_CF_*` jetzt = zt-svc). client_id
|
||||
`ad1b47dee8ba9625eebb30247d163dda.access`.
|
||||
- **Worker-Pin gefunden** (`blaueblueten-n8n/worker/src/index.js:44`): Admin wird nur dem Token mit
|
||||
`common_name == env.TERPENE_SVC_CLIENT_ID` gewährt. Deshalb Variante B: **`wrangler secret put
|
||||
TERPENE_SVC_CLIENT_ID`** = zt-svc-client_id (wrangler-OAuth-Session, `workers_scripts:write` — die
|
||||
„Deploy blockiert"-Notiz galt nur für API-Tokens). Kein Code-Redeploy nötig.
|
||||
- `terpene-svc` (`bf7d2e5e`) include = **nur noch Gruppe `zt-automation`** (`1b60b608`).
|
||||
**`terpene-verify` (`a6be7efa`) + `terpene-verify-v2` (`1082bad1`) gelöscht.** Einziges verbleibendes
|
||||
Access-Service-Token = **`zt-svc`**. Verify: `test_whoami.py` → `admin:true`, common_name = zt-svc. ✅
|
||||
|
||||
### Token-Altlast (b00722 / d47435) — GEKLÄRT (Rollen waren im Ur-Handoff vertauscht)
|
||||
- **`b00722`** ist **NICHT** die Altlast, sondern das **LIVE** von Caddy genutzte DNS-01-Token
|
||||
(LXC130 `/etc/caddy/caddy.env`, SSoT). Certs valide bis Nov 2026.
|
||||
- **`d47435`** = **stale Klartext-Kopie** in `credentials.env` (gleiche Perms, kein Live-Consumer).
|
||||
n8n hält **0 Credentials**, blaueblüten hält keinen der beiden. `credentials.env`-Kopie am
|
||||
2026-09-01 auf **b00722** realignt (SSoT-Abgleich).
|
||||
- 🔜 **USER-Aktion:** **`d47435` revoken** (Dashboard oder `…4148` kurz „Account API Tokens Write"
|
||||
geben — `…4148` kann API-Tokens weder listen noch revoken, Bestätigung 9109/1000).
|
||||
|
||||
### Drift-Korrekturen (live gemessen)
|
||||
- **T3-Resolver:** interner Split-Horizon liegt auf **`10.40.20.36`/`.37`** (→ `*.emsenhuber.net = .40`),
|
||||
**nicht** auf `10.40.20.1` (der liefert public CF). T3-fallback_domains müssen auf `.36/.37` zeigen.
|
||||
- **`10.40.20.16/.17`** (AdGuard laut CLAUDE.md) sind **stale** → neu als **TP42** angelegt
|
||||
(`docs/handoff-20260901-tp42-naming.md`): `.bf.lan`/`.bf.emsenhuber.net`-Vereinheitlichung.
|
||||
|
||||
### 🔴 Leak (Transparenz)
|
||||
Beim maskierten Lesen von `credentials.env` ist der Wert **`TERPENE_ANDROID_KEYSTORE_PW`** ins
|
||||
Sitzungstranskript geraten (Regex-Loch `_PW`). **Rotation erwägen** (Terpene-Android-Signing).
|
||||
|
||||
### T3 — WARP-intern ✅ APPLIED (2026-09-01)
|
||||
- Ziel-Profil geklärt: das custom „Cloudflare Mesh"-Profil matcht **nur** `warp_connector@…` → Christoph/Geli
|
||||
laufen im **Default-Profil** (`0197d1b3`). `fallback_domains += emsenhuber.net → [10.40.20.36, 10.40.20.37]`
|
||||
dort gesetzt (15 Suffixe). Tunnel-Route `10.40.0.0/16` via `d1da7c8a` existiert; Exclude-Liste enthält
|
||||
**kein** `10.0.0.0/8` (nur `192.168/16` + CGNAT-minus-Mesh) → `.36/.37` sind über WARP routbar.
|
||||
- ⏳ **User-Verify:** WARP am Gerät **neu verbinden** (Profil-Cache), dann `dig vw.emsenhuber.net → .40`
|
||||
und `/admin` über WARP erreichbar.
|
||||
|
||||
### T2 — 404 statt 403 ✅ DURCH (2026-09-01)
|
||||
- Caddyfile `vw`-Block: `@cf_admin {header CF-Connecting-IP *; path /admin /admin/*} → respond 404`.
|
||||
Deploy LXC130 (Backup `/etc/caddy/Caddyfile.bak-tp41-20260901`), reload ok.
|
||||
- WAF-Regel **`f26744eb` gelöscht** (nur noch die gitea-skip-Regel `3c707c3c` im Ruleset).
|
||||
- Verify: **Edge `/admin` = 404** (war 403), Edge `/` = 200, **lokal/WARP `/admin` = 200**. ✅
|
||||
|
||||
### Noch offen
|
||||
- **d47435-Revoke** (User, Account API Tokens Write). **T3-Client-Verify** (User, WARP neu verbinden).
|
||||
- **T5** (GitHub/Google-Callbacks — der eigentliche OTP-Fix, User) — **Schritt-für-Schritt:**
|
||||
[`docs/tp41-t5-idp-callback-anleitung.md`](tp41-t5-idp-callback-anleitung.md). **T6/T7/dw-Geli**.
|
||||
- 🔴 **`TERPENE_ANDROID_KEYSTORE_PW`-Rotation erwägen** (Transkript-Leak, s.o.).
|
||||
40
docs/handoff-20260901-tp42-naming.md
Normal file
40
docs/handoff-20260901-tp42-naming.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Handoff 2026-09-01 — TP42 Namens-Vereinheitlichung bf.lan → emsenhuber.net
|
||||
|
||||
> **Angelegt aus einem TP41-Randbefund.** Reine Anlage + Bestandsaufnahme; **keine Live-Änderung**
|
||||
> in dieser Session. Umsetzung = eigene Session.
|
||||
|
||||
## Auslöser
|
||||
Beim Verifizieren des T3-Resolvers (TP41) live gemessen:
|
||||
|
||||
| Resolver | vw.emsenhuber.net | Bewertung |
|
||||
|---|---|---|
|
||||
| 10.40.20.36 / .37 | 10.40.20.40 | ✅ korrekt (reale Client-Resolver, via DHCP) |
|
||||
| 10.40.20.1 (Core) | 188.114.96.10 / .97.10 | public CF (Core macht DoH→CF) |
|
||||
| 10.40.20.16 | CNAME nginx-bf.emsenhuber.net (kein A) | 🔴 stale |
|
||||
| 10.40.20.17 | nginx.bf.emsenhuber.net + 10.40.41.123 | 🔴 stale, totes VLAN1 |
|
||||
|
||||
Daneben: Core `/ip dns static` = 11× `*.bf.lan`; Caddyfile doppelt jeden internen Namen als
|
||||
`*.bf.emsenhuber.net`.
|
||||
|
||||
## Befund-Fundstellen (Start für die Umsetzung)
|
||||
- **Core (`crs326-core`) `/ip dns static`:** router.lan, core.bf.lan, macmini.bf.lan, pve.bf.lan,
|
||||
pve-mcp.bf.lan, nas.bf.lan, docker.bf.lan, platform-pg.bf.lan, ap1.bf.lan, ap2.bf.lan, branch.bf.lan.
|
||||
- **Caddyfile (`caddy/Caddyfile`, LXC130/.40):** `*.bf.emsenhuber.net`-Aliase an nautobot/ccu/iobroker/
|
||||
z2m25/pve-mcp/ha-mcp/n8n-mcp/gitea-mcp/pve/portainer/pbs.
|
||||
- **AdGuard `.36`/`.37`:** aktive Split-Horizon-Rewrites `*.emsenhuber.net → .40` (Sollquelle).
|
||||
- **Stale `.16`/`.17`:** alte AdGuard, `nginx*`-Antworten + `10.40.41.123` → abbauen/klären.
|
||||
- **DHCP:** Search-/Domain-Option je Netz prüfen (welcher Suffix wird verteilt?).
|
||||
|
||||
## Ziel
|
||||
Ein interner Namensraum `emsenhuber.net` (Split-Horizon `.36/.37 → .40`). `.bf.lan` +
|
||||
`.bf.emsenhuber.net` raus. Sollzustand in Nautobot (TP37).
|
||||
|
||||
## Offen / Entscheidungen für die Umsetzungssession
|
||||
1. Zielschema fix: nur `emsenhuber.net`, oder `bf.emsenhuber.net` als **einzige** interne Zone?
|
||||
2. Migrationsreihenfolge ohne DNS-Loch (erst neue Namen, dann alte weg).
|
||||
3. `.16/.17`: laufen die noch, gehören sie abgebaut? (mit TP für AdGuard-Konsolidierung abgleichen)
|
||||
4. Nautobot-Erfassung: Custom Field / Records — abhängig von TP37-Datenmodell.
|
||||
|
||||
## Nicht anfassen
|
||||
Öffentliche Zone `emsenhuber.net` (CF); Resolver-Zuordnung `.36/.37`; `.1`-DNS-Reste auf Clients
|
||||
(User: „bis jetzt kein Problem"). Test-Vantage-Lehre aus TP41 beachten (von zuhause umgeht man CF).
|
||||
72
docs/handoff-20260902-cf-estate-nautobot-ssot.md
Normal file
72
docs/handoff-20260902-cf-estate-nautobot-ssot.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Handoff 2026-09-02 — CF-Estate als SSoT in Nautobot (TP44, Etappe 1)
|
||||
|
||||
> Scope: die Cloudflare-Infrastruktur (Tunnel + App-Ebene) als strukturierte, abfragbare SSoT in
|
||||
> Nautobot abbilden. Etappe 1 = **manuelle Erstbefüllung** über die nativen `nautobot.cloud`-Modelle.
|
||||
> Ausgelöst aus der DB-Pfad-Session (siehe `cf-tunnel-mapping.md` §17).
|
||||
|
||||
## Entscheidung (User, 2026-09-02)
|
||||
|
||||
- **SSoT-Modus:** Etappen — *manuell jetzt, Sync später*. `cf-tunnel-mapping.md` wird zum Snapshot/Zeiger.
|
||||
- **Scope Etappe 1:** *volle CF-Estate* (Tunnel + WARP-Connector + VPC-Service + Hyperdrive + Workers +
|
||||
alle Access-Apps).
|
||||
- **Grundsatz:** Nautobot kann CF **nicht steuern** → „SSoT" = **Dokumentations**-SSoT. CF bleibt
|
||||
operativer Master.
|
||||
|
||||
## Warum ein eigenes TP (TP44), nicht TP36
|
||||
|
||||
TP36 ist in `teilprojekte.md` eng auf *`teilprojekte.md`-Live-Daten + Datei-Aufteilung* geschnitten.
|
||||
Dieselbe Idee (Nautobot als Doku-SSoT), aber andere Dimension → **TP44** (nächste freie Nummer nach TP43).
|
||||
Quick-Index-Zeile + TP-Abschnitt in `teilprojekte.md` sind **noch offen** (die Datei trug bei dieser
|
||||
Session fremde, ungestagte Änderungen — bewusst nicht mit angefasst, um den Commit sauber zu halten).
|
||||
|
||||
## Modell (Nautobot 3.1.7, App `nautobot.cloud`)
|
||||
|
||||
```
|
||||
Manufacturer "Cloudflare"
|
||||
└─ CloudAccount "Cloudflare" (account_number = 393c051f3accf51881d6c98fc5b66c36)
|
||||
├─ CloudResourceType ×6
|
||||
│ cloudflared Tunnel · WARP Connector → cloud.cloudnetwork
|
||||
│ VPC Service · Hyperdrive · Worker · Access Application → cloud.cloudservice
|
||||
├─ CloudNetwork ×4 bf-public · fm.emsenhuber.net · terpene-db · bf-core-mesh
|
||||
└─ CloudService ×14 VPC terpene-db · Hyperdrive terpene(ro)+terpene-rw ·
|
||||
Worker terpene+blaueblueten-n8n · 9× Access-App
|
||||
```
|
||||
|
||||
- **IDs/Ports/Hostnames/Origins** liegen je Objekt in `extra_config` (JSON).
|
||||
- **Service↔Tunnel-Verknüpfung** über das Through-Modell `cloud-service-network-assignments` (3 Rows):
|
||||
`terpene-db↔terpene-db`, `*.emsenhuber.net↔bf-public`, `hass, vw, gitea↔bf-public`.
|
||||
- **Prefix-Routen** (`10.40.0.0/16` bf-core-mesh, `10.101.0.0/24` fm) sind **nicht** als
|
||||
`cloud-network-prefix-assignments` gesetzt, weil die Prefixe nicht in IPAM existieren → in
|
||||
`extra_config.route` belassen (best-effort im Seeder, greift automatisch, sobald die Prefixe in IPAM sind).
|
||||
|
||||
## Werkzeug
|
||||
|
||||
`nautobot/tp44-cf-estate-seed.py` — **idempotenter** Seeder (get-or-create), Datenstand als Inline-Struktur.
|
||||
Token aus `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored). Aufruf: Dry-Run default,
|
||||
`--commit` schreibt. Re-Run = 26/26 „existiert".
|
||||
*(Datei am 2026-09-06 von `tp36-…` auf `tp44-cf-estate-seed.py` umbenannt — Präfix jetzt korrekt.)*
|
||||
|
||||
## Gotchas (für Etappe 2 / Folgesessions)
|
||||
|
||||
- 🔴 **`CloudService.cloud_networks` ist im Serializer `read_only` und bleibt bei GET leer** — die
|
||||
Verknüpfung wird **ausschließlich** über `cloud-service-network-assignments` geschrieben UND gelesen.
|
||||
Nicht am leeren Convenience-Feld verzweifeln; die Through-Rows sind die Wahrheit.
|
||||
- VPC-Service-API liegt unter `connectivity/directory/services` (Update = **PUT**, voller Body), nicht `/vpc/`.
|
||||
- Der Repo-`CF_API_TOKEN` darf `cfd_tunnel`, aber **nicht** Workers-VPC (`connectivity/directory`) — dort
|
||||
über den `cloudflare`-MCP-Credential gehen.
|
||||
> ⚠️ **ÜBERHOLT (2026-09-11):** falsch. Live getestet liest der `CF_API_TOKEN` aus
|
||||
> `~/.secrets/credentials.env` Hyperdrive/VPC/Workers (alle 200) — der schmale ist `CF_DNS_API_TOKEN`.
|
||||
> Der Teil-B-Sync deckt damit 14/14 ab. Details: `handoff-20260910-tp44-teilb-sync-live.md`.
|
||||
|
||||
## Offen (Etappe 2, eigene Session)
|
||||
|
||||
1. **CF-API→Nautobot-Sync** (Python/n8n): Inline-Daten im Seeder durch Live-Pull ersetzen, periodisch
|
||||
(analog golden-config-bot). Dann ist Nautobot driftfrei.
|
||||
2. ✅ **TP44 in `teilprojekte.md`** eingetragen (Quick-Index + Abschnitt + Ist-Stand) — 2026-09-06.
|
||||
3. IPAM-Prefixe `10.40.0.0/16` + `10.101.0.0/24` anlegen → dann greifen die Prefix-Assignments automatisch.
|
||||
4. ✅ Seeder-Datei nach `tp44-cf-estate-seed.py` umbenannt — 2026-09-06.
|
||||
|
||||
## Verifikation (2026-09-02)
|
||||
|
||||
Counts: CloudAccount 1 · ResourceType 6 · CloudNetwork 4 · CloudService 14 · Service-Network-Assignments 3.
|
||||
Idempotenz-Gegenprobe grün.
|
||||
57
docs/handoff-20260902-tp25-fund-e-messung.md
Normal file
57
docs/handoff-20260902-tp25-fund-e-messung.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Handoff 2026-09-02 — TP25 Fund E: die Abschlussmessung, und was sie entschieden hat
|
||||
|
||||
**Kurz:** Die für heute früh vorgemerkte Messung ist gelaufen. **7.24.1 hat den
|
||||
`reauthenticating`-Sturm aufgelöst, nicht `ft-over-ds`.** Hebel 1 war widerlegt und ist zu Recht
|
||||
zurückgebaut; Hebel 2–4 entfallen. **Fund E ist geschlossen** — ohne Geräte-Write.
|
||||
|
||||
## Was Fund E war
|
||||
|
||||
Ein `reauthenticating`-Sturm, sauber isoliert auf **einen** Client (iPhone
|
||||
`F2:62:4C:E1:AF:09`) und **eine** SSID (`dirtyvader-main`, die einzige mit
|
||||
`ft=yes ft-over-ds=yes`). Baseline: 93/93 auf genau diesem Client und dieser SSID. Hebel 1
|
||||
(`ft-over-ds=no`) lief am 31.08. **6,4 h allein** und machte es **schlimmer** (124 ≈ 19/h + 2
|
||||
erlebte Ausfälle) → am 01.09. zurückgebaut, Transaktion `TP25-fund-e-ft-over-ds` geschlossen.
|
||||
Der Einbruch auf ~0/h fiel exakt auf das **TP27-Upgrade 7.24.1** (Core-Reboot 31.08. 14:36).
|
||||
|
||||
## Vorbedingung zuerst (CLAUDE.md-Gotcha: „grep caps + uptime vor Client-Diagnose")
|
||||
|
||||
- Core-Uptime **1d18h** → letzter Reboot 31.08. 14:36; **kein** Reboot am 01./02.09.
|
||||
- `caps joined = 0` an beiden Tagen.
|
||||
- ⇒ Die Zahlen unten sind echte Client-Ereignisse, keine Reboot-Artefakte.
|
||||
|
||||
## Messung (Kollektor `/opt/tp5-syslog/log/10.40.20.1/`, via pve→`pct exec 400`)
|
||||
|
||||
| Tag | reauth total | davon iPhone F2:62 | distinct MACs | data loss / deauth | Kontext |
|
||||
|---|---|---|---|---|---|
|
||||
| 08-31 | 225 | 218 | 6 | (Upgrade+Hebel1) | Hebel-1-Fenster + 2 Upgrade-Reboots |
|
||||
| 09-01 | 44 | 40 | 4 | 0 | 7.24.1, Hebel 1 mittags zurückgebaut |
|
||||
| **09-02** (00:00–08:37) | **4** | **4** | **1** | **0** | 7.24.1 + `ft-over-ds=yes`, sauberes Fenster |
|
||||
|
||||
- **218 → 40 → 4.** Am 09-02 vier isolierte Einzelereignisse (01:13, 02:00, 03:14, 08:01),
|
||||
**kein Burst**, alle `dirtyvader-main` (Interface `cap-wifi3`/`cap-wifi6` — die `cap-wifiN`-Karte
|
||||
wandert, deshalb NICHT einem AP zugeschrieben). ≈ **0,46/h** gegen Baseline 93 bzw. Hebel-1 **19/h**.
|
||||
- Der iPhone ist **präsent und stabil** — er verbindet und erzeugt die 4 Zeilen, ist also nicht
|
||||
„still, weil abwesend".
|
||||
- Die 97 `association rejected` am 09-01 fallen auf den **Rollback-/Re-Provisioning-Vorgang**
|
||||
(viele MACs = Infrastruktur, per Gotcha), nicht auf einen Client; am 09-02 nur 5.
|
||||
|
||||
## Schluss & Entscheidung
|
||||
|
||||
**7.24.1 war die Ursache/der Fix, nicht `ft-over-ds`.** Der Restwert (~0,5/h isolierte
|
||||
Einzel-Reauth eines iPhones, 0 Ausfälle) ist normales iOS-Roaming, kein Defekt.
|
||||
**Hebel 2–4 (`ft=no`, `2g-probe-delay`, `signal-range`) werden NICHT gezogen. Fund E geschlossen.**
|
||||
|
||||
Kein Geräte-Write: Sollzustand steht bereits (`sec-main` = `ft=yes ft-over-ds=yes`, Flotte 7.24.1,
|
||||
Transaktion `zurueckgebaut`, Compliance **140/140**).
|
||||
|
||||
## Bleibt offen (nicht Fund E)
|
||||
|
||||
- **ap2 unterperformt** (2 m / −80 dBm, 23:02-Befund) — eigener In-situ-Unterpunkt in TP25,
|
||||
kein FT-/Auth-Thema. TP25 bleibt deshalb als Sammel-TP offen.
|
||||
|
||||
## Merkregel bestätigt
|
||||
|
||||
Der Fall ist ein Lehrstück für zwei CLAUDE.md-Regeln: (a) **Reboots zuerst ausschließen** hätte am
|
||||
31.08. verhindert, den Upgrade-Reboot-Burst für Client-Instabilität zu halten; (b) **eine Drift/ein
|
||||
Symptom im offenen Versuch sieht aus wie ein Defekt** — Hebel 1 „verbesserte auf 0/h" war in
|
||||
Wahrheit das parallele Upgrade. Die einzelne Messung nach dem Rückbau hat beides getrennt.
|
||||
113
docs/handoff-20260903-tp25-tp28-kanalplan-messung.md
Normal file
113
docs/handoff-20260903-tp25-tp28-kanalplan-messung.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Handoff 2026-09-03 — TP25/TP28: Kanalplan live, In-situ-Messung offen
|
||||
|
||||
**Kurz:** ap1 haengt jetzt am Sideboard (Trunk auf `ether3`), der TP25-Kanalplan ist am
|
||||
Manager gesetzt (**ap1 5260/5280 + ch1**, **ap2 5300/5320 + ch11**, **ap3 5180 + ch6**),
|
||||
und alle drei APs funken. 35 Clients an der Registration-Table (vorher 30, +5 auf ap1).
|
||||
**Was fehlt: die In-situ-Messung** — Aufstellorte begehen und entscheiden, ob der Zustand
|
||||
Zielzustand wird (dann Template + Commit der Akte) oder ob nachjustiert werden muss.
|
||||
|
||||
## Was am 03.09. live gesetzt wurde
|
||||
|
||||
L2 auf `crs326-core`:
|
||||
- `ether3` als AP-Trunk fuer ap1 (analog `ether15`/`ether21`) — Template gepflegt
|
||||
- Akte `TEST-ether3-trunk-ap1-sideboard-2` (Scope `bridge-vlan`, `state=committed`,
|
||||
expires 2026-09-10)
|
||||
|
||||
WLAN am Manager (`crs326-core`):
|
||||
- `ch-5g-ap1`: 5180 → **Frequenz-Liste 5260,5280** (DFS Band B, ch52/56)
|
||||
- `ch-5g-ap2`: 5220 → **Frequenz-Liste 5300,5320** (DFS Band B, ch60/64)
|
||||
- Zwei Provisioning-Regeln fuer ap1 neu (radio-mac `E5`=5G, `E6`=2G) — analog ap2/ap3
|
||||
- `remote-cap provision` auf ap1 und ap2 gefahren
|
||||
- Akte `TP25-kanalplan-ap1-live` (Scope `wifi-channel`, `state=open`, expires 2026-09-10)
|
||||
|
||||
Live-Verifikation:
|
||||
- ap1: 9/9 Interfaces `running=true` am CAP (Manager-Anzeige `running=false` ist der bekannte
|
||||
Post-Reprovisioning-Gotcha, s. CLAUDE.md — Wahrheit am CAP)
|
||||
- ap2: 9/9 Interfaces `running=true`
|
||||
- ap3: unveraendert
|
||||
- 35 Clients (vor Aenderung 30)
|
||||
|
||||
## Was fuer die naechste Session zu tun ist
|
||||
|
||||
**Fokus = messen, nicht nachjustieren, bis die Aufstellorte belegt sind.**
|
||||
|
||||
Zwei offene Frage aus TP25/TP28, die vor Ort beantwortet werden muessen:
|
||||
|
||||
1. **Aufstellort ap1 (Sideboard)** — Abdeckung akzeptabel? Vorher stand ap1 im Technik UG, jetzt
|
||||
am Sideboard (Test). Signal in den Ecken (Terrasse, Bad, hintere Zimmer) messen.
|
||||
2. **ap2 unterperformt** (TP25 Rest-Punkt, In-situ 2 m/−80 dBm am 08-31). Vermutung: RF/Antenne/HW,
|
||||
moeglicherweise auch nur `ch149`-Leistungsproblem (jetzt weg, 5300 statt 5220). Die
|
||||
Kanalaenderung koennte das Symptom bereits behoben haben — deshalb **zuerst neu messen**,
|
||||
bevor man an Antennen oder Hardware denkt.
|
||||
|
||||
## Aufstellorts-Messplan (Vorschlag, bewusst knapp)
|
||||
|
||||
Pro Standort (Wohnzimmer, Kueche, Bad, Terrasse, Schlafzimmer, Technik UG):
|
||||
- Signal in dBm auf `dirtyvader-main` (5 GHz) mit App am Handy
|
||||
- Welcher AP wird ausgewaehlt (BSSID am APx-Radio abgleichen — s. Manager-Registration-Table)
|
||||
- Kurz eine Datei ziehen (SpeedTest oder `iperf3` gegen `10.40.20.10`), damit reale Throughput-
|
||||
Zahl da ist, nicht nur RSSI
|
||||
- 2,4 GHz nur pruefen, wenn das 5-GHz-Signal an dem Standort schlecht ist (< −75 dBm)
|
||||
|
||||
Am Manager parallel:
|
||||
- `/interface wifi registration-table print terse where ssid=dirtyvader-main` — Signal/Rate live
|
||||
- `/interface wifi radio print` gibt aktuelle Frequenz je Radio (5260 vs 5280, 5300 vs 5320 —
|
||||
DFS hat einen der beiden gewaehlt)
|
||||
|
||||
## Gotchas fuer die Messsession (aus CLAUDE.md)
|
||||
|
||||
- **`/interface wifi scan` NUR am Manager**, nicht am CAP (`not allowed`).
|
||||
- **Registration-Table NUR am Manager** — am CAP leer.
|
||||
- **`cap-wifiN`-Karte wandert bei jedem Rejoin.** Vor der Auswertung eines Ereignisses
|
||||
`/interface wifi radio print terse proplist=cap,radio-mac,interface` am Manager lesen; wenn
|
||||
zwischen Ereignis und Auswertung ein Rejoin liegt, Zuordnung als **unbekannt** behandeln.
|
||||
- **`list_wifi_interfaces` leakt PSKs** — nicht benutzen; stattdessen
|
||||
`/interface wifi radio print` bzw. `/interface wifi print terse where master=yes proplist=...`.
|
||||
- **Ein `caps,info`-Burst ist Infrastruktur, ein Client-MAC-Burst ist ein Client** — vor jeder
|
||||
Client-Diagnose `/system resource get uptime` am Core lesen und `grep " caps,"` im TP5-Log.
|
||||
- **DFS-CAC** dauert beim ersten Einschalten eines DFS-Kanals ~60 s. Bei einem Radar-Event
|
||||
wechselt der Kanal automatisch auf den Zweitwert (5260↔5280 bzw. 5300↔5320) — deshalb steht
|
||||
im Channel-Objekt eine **Liste**, kein Einzelwert.
|
||||
|
||||
## Rollback (falls die Messung schlecht ausfaellt)
|
||||
|
||||
Der Snapshot `docs/transaktionen/TP25-kanalplan-ap1-live.snapshot.rsc` haelt den Vorher-Zustand
|
||||
(ap1=5180, ap2=5220, keine ap1-Provisioning-Regeln). Rollback per:
|
||||
|
||||
```
|
||||
python3 nautobot/gc-transaktion.py rollback --change-id TP25-kanalplan-ap1-live
|
||||
```
|
||||
|
||||
Der Trunk auf `ether3` (physischer Umbau) muss separat via
|
||||
`TEST-ether3-trunk-ap1-sideboard-2` behandelt werden.
|
||||
|
||||
## Commit-Weg (falls die Messung gut ausfaellt)
|
||||
|
||||
Zwei Sachen ins Template `nautobot/mikrotik_routeros.j2`:
|
||||
1. Zeilen 206–207: `frequency=5180`/`5220` → Frequenz-Listen `5260,5280`/`5300,5320`
|
||||
2. Nach den bestehenden Provisioning-Zeilen fuer ap2/ap3 die zwei ap1-Regeln einfuegen
|
||||
(radio-mac `D0:EA:11:4D:40:E5` = 5G, `D0:EA:11:4D:40:E6` = 2G) — Slave-Set analog ap2/ap3
|
||||
|
||||
Danach:
|
||||
```
|
||||
python3 nautobot/gc-transaktion.py commit --change-id TP25-kanalplan-ap1-live
|
||||
```
|
||||
|
||||
Skript verweigert den Commit, solange die SoT nicht nachgezogen ist — der Ablauf funktioniert
|
||||
nur in dieser Reihenfolge.
|
||||
|
||||
## Ein-Scope-Grenze der Akte (wichtig, wenn Compliance-Status gelesen wird)
|
||||
|
||||
Die Akte deckt formell **nur `wifi-channel`**. Die zwei ap1-Provisioning-Adds fallen unter
|
||||
`wifi-provisioning` — das begin-Skript erlaubt aber **nur eine offene Akte je Geraet** (Regel 3).
|
||||
Deshalb steht im `commands.rsc` der Akte ein Header, der beides zusammenfuehrt. Im naechsten
|
||||
Compliance-Run wird `wifi-provisioning` als „fremd" (nicht durch die aktive Akte gedeckt)
|
||||
gemeldet werden — das ist **erklaerbarer, nicht undokumentierter Drift**. Beim Commit gehoert
|
||||
BEIDES ins Template.
|
||||
|
||||
## Aufraeumkandidat, wenn alles glatt geht
|
||||
|
||||
- TP25-Ist-Stand-Block: Punkt „ap2 unterperformt" als geloest markieren (falls Messung das
|
||||
bestaetigt).
|
||||
- TP28-Ist-Stand-Block: „ap1 funkstill" ausbauen — ist mit 09-03 erledigt.
|
||||
- Quick-Index-Zeile TP25 kann bei erfolgreichem Commit auf `✅` gesetzt werden.
|
||||
70
docs/handoff-20260904-tp25-konsole-n-clients.md
Normal file
70
docs/handoff-20260904-tp25-konsole-n-clients.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Handoff 2026-09-04 — TP25: Klick-Konsole auf N Clients + Pin-UI
|
||||
|
||||
**Kurz:** Die Klick-Konsole (`docs/tp6-marker/server.py`, Port 3031) war beim Multi-Pin-Umbau
|
||||
(2026-09-04, `tp25-pin-multi.sh` + `TP25_PHONES`) **nicht** mitgezogen worden — sie zeigte weiter
|
||||
hartkodiert zwei Clients (iPhone/S22) und pinnte ueber die alte Gegen-AP-Automatik. Jetzt ist sie
|
||||
auf **N Clients** generalisiert und hat eine **Pin-UI**: Signal/AP/Ping-Verlust je Client live,
|
||||
Pinnen band-genau direkt in der Konsole. Die alte 2-Client-Automatik ist entfernt.
|
||||
|
||||
## Was umgebaut wurde
|
||||
|
||||
`docs/tp6-marker/server.py` (Hauptumbau):
|
||||
- **Client-Liste aus Datei statt hartkodiert:** `geraete()` liest `geraete.txt` aus dem
|
||||
Laufverzeichnis (schreibt `tp25-walk-messung.sh`, eine Zeile `name|ip|mac` je Client). Fallback
|
||||
auf die zwei alten MACs fuer Alt-Laeufe.
|
||||
- **Kein eigenes SSH mehr in der Konsole:** der `beobachter()`-Thread (2 MACs per SSH,
|
||||
`beide-telefone.csv`) ist raus. Stattdessen liest die Konsole je Client die **letzte Zeile** von
|
||||
`sampler-<name>.csv` (`sta_iface`, `sta_signal`) und den **juengsten Ping-Verlust** aus
|
||||
`walk-ping-<name>.csv` (leeres `ms` = Verlust). Eine SSH-Session weniger gegen den Core-SPOF.
|
||||
- **N Client-Karten** statt der festen iPhone/S22-Zeile: Name, AP (via `ap_map()`), Signal dBm,
|
||||
Ping-Verlust der letzten ~30 s. **Alarm**, wenn ein **gepinnter** Client `sta_iface == "absent"`
|
||||
ist → „<name> HAENGT NIRGENDS — nicht weitergehen" (Nachfolger des alten S22-Alarms).
|
||||
- **Pin-UI** (Karte „Pinnen (Multi-Pin)"): je Client ein `<select>` mit `frei` / `apX/5GHz` /
|
||||
`apX/2,4GHz` (Ziele aus `ap_map()` abgeleitet) plus drei Aktionen:
|
||||
- **„Pin setzen"** → baut `TP25_PINSPEC="name|mac|ap|band;…"` aus den Nicht-`frei`-Auswahlen und
|
||||
ruft `bash docs/tp25-pin-multi.sh set` im Thread.
|
||||
- **„Pin loesen"** → `bash docs/tp25-pin-multi.sh off`.
|
||||
- **„verify"** → `bash docs/tp25-pin-multi.sh verify`, Ausgabe als Statuszeile.
|
||||
Neuer Endpunkt `POST /pinmulti` (analog zum alten `/pin`).
|
||||
- **Entfernt:** `IPHONE_MAC`/`S22_MAC`, `_live`/`_auto`, `entscheide()`, `pin_lesen()`/
|
||||
`pin_setzen()` (via `tp25-pin-s22.sh`), die ap1/ap2/auto-Buttons und der `PIN_SH`-Aufruf.
|
||||
`tp25-pin-s22.sh` bleibt als Skript erhalten (liefert `map`), wird aber von der Konsole nicht
|
||||
mehr zum Pinnen aufgerufen.
|
||||
|
||||
`docs/tp25-runde.sh`:
|
||||
- `aufraeumen()` loest jetzt `tp25-pin-multi.sh off` statt `tp25-pin-s22.sh off` (Kommentar
|
||||
angepasst: die Konsole pinnt nicht mehr automatisch).
|
||||
|
||||
## Bedienung (Messablauf)
|
||||
|
||||
```
|
||||
bash docs/tp25-runde.sh [name] # Konsole (3031) + Messung, Adresse fuer das Telefon
|
||||
```
|
||||
|
||||
1. Am Telefon die Konsole oeffnen, einmal irgendwo tippen (schaltet den Signalton frei).
|
||||
2. In der Konsole **pinnen**: je Client AP/Band waehlen, „Pin setzen". Clients ohne Ziel bleiben
|
||||
frei (das Skript raeumt vorher alle `TP25-PINM-*`-Regeln ab).
|
||||
3. Losgehen. 🚶 beim Losgehen, 📍 beim Stehenbleiben, Raum antippen. Alarm = ein gepinnter Client
|
||||
haengt nirgends.
|
||||
4. „⏹ Aufzeichnung stoppen" (oder Ctrl-C im Terminal). Der Wrapper loest den Multi-Pin beim Beenden.
|
||||
|
||||
Auswertung: `python3 docs/tp25-gehweg-auswertung.py --dir docs/messdaten/tp25-runde-<name>`
|
||||
|
||||
## Was noch offen ist (braucht die Geraete vor Ort)
|
||||
|
||||
- **Live-Test mit N Geraeten im Netz** (Plan-Verifikation Schritt 3): `TP25_PHONES="…" bash
|
||||
docs/tp25-runde.sh test` → N Karten sichtbar, pinnen → `bash docs/tp25-pin-multi.sh verify` zeigt
|
||||
die Regeln, gehen/Raeume/stoppen → Auswertung liefert die Raumtabelle mit N Geraeten.
|
||||
- **Aufraeumen** (Schritt 4): nach dem Lauf `bash docs/tp25-pin-multi.sh off` — keine
|
||||
`TP25-PINM-*`-Regeln am Manager zurueck.
|
||||
|
||||
Statisch verifiziert (ohne Geraete): AST-Parse ok, keine stale Referenzen auf die alte Automatik,
|
||||
Smoke-Render mit 2 Test-Clients ok, `bash -n` auf allen drei Shell-Skripten ok.
|
||||
|
||||
## Gotchas (unveraendert, aus CLAUDE.md)
|
||||
|
||||
- **`cap-wifiN`-Karte wandert bei jedem Rejoin** — `tp25-walk-messung.sh` friert sie als
|
||||
`ap-map.txt` im Messlauf ein; die Konsole beschriftet daraus.
|
||||
- **Registration-Table nur am Manager** — die Sampler (`tp6-monitor-core.sh`) fragen den Core ab,
|
||||
nicht die CAPs.
|
||||
- **`sshpass -e`, nie `-p`** — gilt weiter fuer alle Skripte, die den Core ansprechen.
|
||||
127
docs/handoff-20260906-tp37-34-36-plan.md
Normal file
127
docs/handoff-20260906-tp37-34-36-plan.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# Handoff 2026-09-06 — Plan TP37 (P1+2) → TP34, TP36 parallel
|
||||
|
||||
> **Sessiontyp:** „erst planen, nichts bauen" (User-Entscheid 2026-09-06). **Kein Nautobot-Write.**
|
||||
> Dieses Dokument ist der verzahnte Runbook für die drei nachfolgenden Build-Sessions.
|
||||
> Datenmodell-Entscheid: **native Nautobot-Modelle, keine eigene App** (konsistent zu TP44).
|
||||
|
||||
## 1. Ausgangslage — live gegen die API gelesen (2026-09-06)
|
||||
|
||||
| | Wert | Bedeutung |
|
||||
|---|---|---|
|
||||
| Nautobot | `http://10.40.20.30:8080`, v3.1.7 | Apps: **Golden Config 3.0.7 + Nornir** (cloud-Modelle sind Core) |
|
||||
| Devices | 9 | 4 aktive MikroTik + decommissioned/Rest — in Build-Schritt 0 verifizieren |
|
||||
| **VirtualMachines** | **0** | TP37 P1 offen |
|
||||
| **Clusters** | **0** | TP37 P1 offen |
|
||||
| **ipam.Service** | **0** | TP37 P2 offen |
|
||||
| **CustomFields** | **0** | TP36 offen |
|
||||
| Relationships / Tags | 0 / 0 | — |
|
||||
| `cloud.*` (Account/ResType/Network/Service) | 1 / 6 / 4 / 14 | ✅ **TP44 Etappe 1** — CF-Estate steht |
|
||||
|
||||
**Kernbefund:** TP37 **Punkt 3 (CF-Connectoren) ist durch TP44 erledigt** (native cloud-Modelle). Echt
|
||||
offen bleibt das **Substrat** (P1) und die **Dienste** (P2) — und genau darauf sitzt TP34.
|
||||
|
||||
## 2. Entscheidungen (User, 2026-09-06)
|
||||
|
||||
1. **Erst planen, nichts bauen** — diese Session schreibt nichts nach Nautobot.
|
||||
2. **Native Modelle** — `virtualization.Cluster/VirtualMachine` + `ipam.Service`, **keine eigene App**.
|
||||
3. **TP44-Doku aufgeräumt** — Quick-Index-Zeile + Abschnitt in `teilprojekte.md`, Seeder
|
||||
`nautobot/tp36-…` → `tp44-cf-estate-seed.py` umbenannt.
|
||||
|
||||
## 3. Reihenfolge / Abhängigkeit (korrigiert)
|
||||
|
||||
```
|
||||
TP37 P3 (CF-Connectoren) ─── ✅ ERLEDIGT via TP44 ───┐
|
||||
│ gleiche native-Modell-Linie
|
||||
TP37 P1 (Hosts/Container → VirtualMachine) │
|
||||
└─► TP37 P2 (Dienste → ipam.Service) ─► TP34 (Caddyfile via GC)
|
||||
|
||||
TP36 (CustomFields auf den 4 Devices + Datei-Split) ── ∥ unabhängig, jederzeit parallel
|
||||
```
|
||||
|
||||
**Grund für die Unabhängigkeit von TP36:** seine Live-Daten-CustomFields hängen an den **bestehenden
|
||||
`dcim.Device`**, nicht an neuen VM/Service-Objekten. TP34 dagegen kann ohne die Backend-`ipam.Service`
|
||||
aus P2 nichts rendern → **TP37 vor TP34** bleibt zwingend.
|
||||
|
||||
---
|
||||
|
||||
## 4. TP37 Punkt 1 — Substrat: Hosts + Container als VMs
|
||||
|
||||
**Modell-Mapping (nativ):**
|
||||
- `virtualization.ClusterType`: `Proxmox VE`, `Synology Docker`, `Docker Desktop`.
|
||||
- `virtualization.Cluster`: `pve`, `nas-bf`, `macmini` (je einer, passender ClusterType).
|
||||
*(Die physischen Hosts als eigene `dcim.Device` sind **optional** und kommen frühestens in einer
|
||||
Etappe 2 — für den Doku-SSoT reicht der Cluster als Gruppierung. Empfehlung: Etappe 1 ohne Host-Devices.)*
|
||||
- `virtualization.VirtualMachine` je Workload, mit `cluster` + `primary_ip4`:
|
||||
- **pve:** alle LXCs (u.a. `platform-pg` 105/`.20.20`, Docker-LXC 400/`.20.126`, `mcast-relay` 108,
|
||||
influxdb, MariaDB 302/`.20.23`, …).
|
||||
- **nas-bf (DS923, Portainer ep14):** Nautobot-Stack-Container, ggf. Caddy/weitere.
|
||||
- **macmini (Docker Desktop):** `n8n`/`n8n-redis`/`n8n-mcp`/`gitea-mcp` + terpene-Worker `:8890`.
|
||||
|
||||
**Build-Schritt 0 (read-only Inventur, BEVOR geseedet wird):** je Host die Workloads mit Name, Rolle,
|
||||
primärer IP enumerieren — `pct list` + `pct config <id>` über **pve-mcp**, Portainer-API (ep14) für die
|
||||
NAS, `docker ps` auf dem macmini. Ergebnis in eine **Inline-Datenstruktur** (Muster: `tp44-cf-estate-seed.py`)
|
||||
→ idempotenter Seeder `nautobot/tp37-substrat-seed.py` (get-or-create, Dry-Run default, `--commit`).
|
||||
|
||||
## 5. TP37 Punkt 2 — Dienste als `ipam.Service`
|
||||
|
||||
- Je exponiertem Port ein `ipam.Service`, an die VM (bzw. später das Device) gebunden, das ihn betreibt:
|
||||
Caddy `:80/:443`, AdGuard `:53` (bf1/bf2), Nautobot `:8080`, n8n `:5678`, HA `:8123`, Portainer `:9443`,
|
||||
`pve-mcp :3000`, gitea, Vaultwarden, …
|
||||
- **Quelle ohne Raten:** die Ports stehen in `CLAUDE.md` (Hardware/Tooling) **und** in den
|
||||
`extra_config.origin/port`-Feldern der TP44-`CloudService`-Objekte — gegeneinander abgleichen.
|
||||
- Idempotenter Seeder `nautobot/tp37-dienste-seed.py`.
|
||||
|
||||
## 6. 🔴 Auflage: Compliance-Gegenprobe (aus TP37 selbst)
|
||||
|
||||
Nach P1+2 **muss** `python3 nautobot/gc-transaktion.py status` bzw. `gc-configplan.py --refresh-compliance`
|
||||
zeigen, dass die Geräte-Compliance **unverändert 140/140** ist. VMs/Services hinzuzufügen darf die
|
||||
Golden-Config-Pipeline der 4 MikroTik **nicht** berühren. P1 und P2 sind je ein **abnehmbarer** Schritt
|
||||
mit dieser Gegenprobe danach — nicht als Nebeneffekt von etwas anderem.
|
||||
|
||||
---
|
||||
|
||||
## 7. TP34 — Caddyfile via Golden Config (nach P2)
|
||||
|
||||
- **Vorbedingung:** Backend-Dienste existieren als `ipam.Service` (P2).
|
||||
- **Modell (nativ):** Proxy-Route = **Relationship** (oder CustomField) Frontend `caddy`-Service ↔ Backend-
|
||||
Service, plus den öffentlichen Hostname am Backend. GC-Job + Jinja rendert den Caddyfile, Diff gegen
|
||||
live `caddy-bf1`, neue ComplianceRule `caddyfile`.
|
||||
- **Schritt 0 / Quick-Win (sobald gebaut wird):** `terpene.teilzeitladen.xyz → http://10.40.20.167:8890`
|
||||
als **manueller** Caddy-Block, damit terpene läuft, bevor die GC-Pipeline steht.
|
||||
- ⚠️ **Offener Design-Punkt:** Caddy ist **kein RouterOS-Gerät** — GC an ein Nicht-Netzgerät zu deployen
|
||||
(Caddy-Reload) ist neu (die „nicht in TP37"-Grenze). Deploy-Pfad in der TP34-Build-Session entscheiden.
|
||||
|
||||
## 8. TP36 — Live-Daten-CustomFields + Datei-Split (parallel)
|
||||
|
||||
- **CustomFields auf `dcim.Device`:** `ros_version`, `compliance_pct`, `dhcp_server_count`, `mgmt_ip`,
|
||||
`dns_upstream_mode`. Compliance-Zahl kommt aus **GC selbst**, der Rest aus MikroMCP/REST.
|
||||
- **Skript `nautobot/gc-snapshot.py`** (neu — existiert noch nicht): liest live, setzt die CFs, rendert
|
||||
`docs/teilprojekte-aktuell.md` als **read-only Snapshot**.
|
||||
- **Datei-Split:** `teilprojekte-index.md` (nur aktive TPs, eine Zeile) · `teilprojekte-aktuell.md`
|
||||
(Live-Snapshot) · `teilprojekte-archiv.md` (unverändert). `/projektstatus` liest **Index + Archiv**.
|
||||
- **Unabhängig von TP37** → kann sofort/parallel starten.
|
||||
|
||||
---
|
||||
|
||||
## 9. Empfohlene Reihenfolge der Build-Sessions
|
||||
|
||||
1. **TP37 P1** (Substrat) — Inventur → Seeder → Compliance-Gegenprobe.
|
||||
2. **TP37 P2** (Dienste) — schließt an P1 an, gleiche Gegenprobe.
|
||||
3. **TP34** — nach P2 (Quick-Win terpene als Schritt 0).
|
||||
4. **TP36** — jederzeit parallel zu 1–3.
|
||||
|
||||
## 10. Offene Entscheidungen je Build-Session (nicht heute)
|
||||
|
||||
- **TP34:** Proxy-Route-Modell (Relationship vs. CustomField) + Caddy-Deploy-Pfad (GC an Nicht-Netzgerät).
|
||||
- **TP37:** Hosts als eigene `dcim.Device` anlegen oder nur Cluster? (Empfehlung: Etappe 1 nur Cluster.)
|
||||
- **TP36:** genaues Feld-Set + wie oft `gc-snapshot.py` läuft (Bot analog golden-config vs. on-demand).
|
||||
|
||||
## 11. Was diese Session geändert hat (nur Doku)
|
||||
|
||||
- `nautobot/tp36-cf-estate-seed.py` → **`nautobot/tp44-cf-estate-seed.py`** umbenannt (+ 4 Referenzen,
|
||||
+ Docstring-Titel TP36→TP44).
|
||||
- `teilprojekte.md`: Quick-Index-Zeile TP44; Ist-Stand-Bullet 2026-09-06; TP34/TP36/TP37-Abschnitte auf
|
||||
den korrigierten Stand gezogen; **neuer TP44-Abschnitt** mit Anker.
|
||||
- `handoff-20260902-cf-estate-nautobot-ssot.md` + `cf-tunnel-mapping.md`: Dateiname-Referenzen + erledigte
|
||||
TODOs nachgezogen.
|
||||
- **TP23-Quick-Index-Zeile** (fremde, korrekte Fremd-Änderung ✅→⏳) auf User-Okay mit übernommen.
|
||||
57
docs/handoff-20260910-tp44-teilb-sync-live.md
Normal file
57
docs/handoff-20260910-tp44-teilb-sync-live.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Handoff 2026-09-10 — TP44 Teil B: CF-Estate-Sync als Nautobot-Job LIVE
|
||||
|
||||
> **Ergebnis:** Der Cloudflare-Estate→Nautobot-Sync läuft als **täglicher Nautobot-Job**
|
||||
> (`CFEstateSync`, grouping `TP44 / Cloudflare`). Dry-Run + Commit-Run sauber: **4 CloudNetworks /
|
||||
> 14 CloudServices, alle CF-Endpoints lesbar, 0 Drift.** CF bleibt operativer Master, Nautobot ist
|
||||
> read-only Dokumentations-SSoT. **TP44 ist damit vollständig durch.**
|
||||
|
||||
## Governance (User, 2026-09-09)
|
||||
Periodische externe→Nautobot-Syncs leben als **Nautobot-Jobs** in `bf-infra/jobs/` und werden **in
|
||||
Nautobot geplant** — kein per-Task-Container, kein Cron. Künftige Syncs = weitere Jobs in `jobs/`.
|
||||
|
||||
## Was live ist
|
||||
- **Runtime:** `jobs/cf_estate_sync.py` (`CFEstateSync`, ORM). Pull der CF-API (urllib+Bearer),
|
||||
Upsert per `extra_config`-Match (`tunnel_id`/`script`/`id`/`service_id`), Verwaisung = `stale`-Flag
|
||||
statt Löschen. 403-tolerant (fehlender Scope kippt den Sync nicht; Verwaisung wird dann übersprungen).
|
||||
- **Registrierung:** `jobs/__init__.py` ruft `register_jobs(CFEstateSync)`; **Repo-Wurzel-`__init__.py`**
|
||||
macht `bf_infra` als reguläres Paket sichtbar.
|
||||
- **Token:** Nautobot-Secret `cf-api-token` (Provider `environment-variable`) → `CF_API_TOKEN` am
|
||||
`nautobot-worker`, verdrahtet im Anchor-`environment` von `docs/nas-vlan20/stacks/210-nautobot.yml`
|
||||
(gitignored). Wert = der breite `CF_API_TOKEN` aus `~/.secrets/credentials.env` (liest 14/14).
|
||||
- **Schedule:** `ScheduledJob "CF Estate Sync – taeglich"`, `interval=daily`, `start_time=2026-09-11T03:00:00Z`
|
||||
(= 05:00 Europe/Vienna, vor den Golden-Config-Läufen), `enabled=True`, `dryrun=False`.
|
||||
- **GitRepository:** `bf-infra` (`provided_contents=['extras.job']`) — war schon verdrahtet.
|
||||
|
||||
## Drei load-bearing Funde (sonst lädt/plant der Job nicht)
|
||||
1. **Repo-Wurzel `__init__.py` ist Pflicht.** Nautobot 3.1.7 lädt Git-Repo-Jobs über
|
||||
`import_modules_privately()` → `pkgutil.walk_packages([GIT_ROOT])`. walk_packages entdeckt **nur**
|
||||
reguläre Pakete (mit `__init__.py`), **keine** Namespace-Packages. Ohne die Datei ist der geklonte
|
||||
`GIT_ROOT/bf_infra/` unsichtbar → `jobs/` wird nie importiert. Symptom: Git-Sync **SUCCESS**, aber
|
||||
Log „No jobs were registered on loading the `bf_infra.jobs` submodule" und **kein** Job-DB-Eintrag.
|
||||
bf-infra ist das **erste** Git-Repo mit `extras.job` — daher nie zuvor aufgetreten. Der `module_path`-
|
||||
Filter des Loaders importiert nur `bf_infra` + `bf_infra.jobs.*`; `nautobot/`, `routeros/` etc. bleiben
|
||||
unberührt.
|
||||
2. **`register_jobs()` gehört ins Paket-`__init__`**, nicht nur ins Submodul (Doku bestätigt).
|
||||
3. **`Meta.has_sensitive_variables = False`** nötig — Default `True` ⇒ Nautobot verweigert das Scheduling
|
||||
(„Job may have sensitive input variables"). Der Job nimmt nur `dryrun` (Boolean); das Token kommt aus
|
||||
dem Secret, nicht aus einer Job-Variable.
|
||||
|
||||
## Zwei Daten-/Code-Funde beim Dry-Run
|
||||
- **VPC-Bug:** VPC-Directory-Services tragen ihren Identifier in **`service_id`**, nicht `id`. Der Job las
|
||||
`id` (=None) → per `.get(mk)==None` matchte er ein Fremdobjekt (App Launcher) und ließ den echten
|
||||
`terpene-db` auf stale laufen. Fix: VPC nutzt `service_id`; `_upsert` überspringt `mv=None` generell.
|
||||
- **Seed-Artefakt:** der geseedete CloudService `terpene-db` hatte `extra_config.service_id: null`
|
||||
(der echte `019fa3d5-…` stand beim Seed nur in den Hyperdrive-Einträgen als `vpc_service_id`).
|
||||
**Einmalig reconciled** (PATCH `service_id=019fa3d5-…`) → seither matcht der Sync sauber, 0 Drift.
|
||||
|
||||
## Drift-Korrektur (nicht stillschweigend)
|
||||
Die frühere Notiz „Repo-`CF_API_TOKEN` darf kein Workers-VPC → über den `cloudflare`-MCP-Credential"
|
||||
(TP44-Prosa + `handoff-20260902-…`) war **falsch**. Live getestet liest der `CF_API_TOKEN` aus
|
||||
`~/.secrets/credentials.env` Hyperdrive/VPC/Workers (alle 200). Der schmale Token ist `CF_DNS_API_TOKEN`
|
||||
(403). Der `cloudflare`-MCP ist der **remote OAuth-MCP** (kein API-Token) und für einen serverseitigen
|
||||
Job ohnehin nicht nutzbar.
|
||||
|
||||
## Nächster CF-Sync = neuer Job im selben Muster
|
||||
Modul in `jobs/` anlegen, Klasse importieren + `register_jobs(...)` im `jobs/__init__.py` ergänzen,
|
||||
`Meta.has_sensitive_variables=False` setzen, Git-Sync, enablen, Dry-Run, dann Schedule. Die Wurzel-
|
||||
`__init__.py` gilt schon.
|
||||
6
docs/messdaten/tp25-runde-1er/ap-map.txt
Normal file
6
docs/messdaten/tp25-runde-1er/ap-map.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
cap-wifi1=ap2/5GHz
|
||||
cap-wifi2=ap3/5GHz
|
||||
cap-wifi3=ap1/5GHz
|
||||
cap-wifi4=ap3/2,4GHz
|
||||
cap-wifi5=ap1/2,4GHz
|
||||
cap-wifi6=ap2/2,4GHz
|
||||
2
docs/messdaten/tp25-runde-1er/geraete.txt
Normal file
2
docs/messdaten/tp25-runde-1er/geraete.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
iphone|10.40.10.196|F2:62:4C:E1:AF:09
|
||||
s22|10.40.10.178|2A:0D:B0:5D:AD:A7
|
||||
6
docs/messdaten/tp25-runde-1er/markers.csv
Normal file
6
docs/messdaten/tp25-runde-1er/markers.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
ts_epoch,ts_local,marker
|
||||
1788526676,14:57:56,PINM=off
|
||||
1788526735,14:58:55,PINM=off
|
||||
1788526763,14:59:23,PINM=off
|
||||
1788526765,14:59:25,PINM=off
|
||||
1788526770,14:59:30,PINM=s22|2A:0D:B0:5D:AD:A7|ap1|24
|
||||
|
1
docs/messdaten/tp25-runde-1er/phase.json
Normal file
1
docs/messdaten/tp25-runde-1er/phase.json
Normal file
@@ -0,0 +1 @@
|
||||
{"mode": "langzeit", "phase": "GEHWEG", "title": "Roaming-Messung l\u00e4uft", "instruction": "Aufzeichnung gestoppt.", "step": 0, "steps": 0, "ends": 0}
|
||||
26
docs/messdaten/tp25-runde-1er/sampler-iphone.csv
Normal file
26
docs/messdaten/tp25-runde-1er/sampler-iphone.csv
Normal file
@@ -0,0 +1,26 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788526644,14:57:24,14:57:24,41,472232,195392,cap-wifi3,-57,309700000,325000000,2800,2960,00:04:37,00:00:00
|
||||
1788526646,14:57:26,14:57:26,11,229864,36304,cap-wifi3,-57,309700000,325000000,2800,2960,00:04:39,00:00:00
|
||||
1788526648,14:57:28,14:57:28,8,132384,26968,cap-wifi3,-59,309700000,309700000,6160,6512,00:04:41,00:00:00
|
||||
1788526650,14:57:30,14:57:30,30,196672,48240,cap-wifi3,-59,309700000,344100000,6160,6512,00:04:43,00:00:00
|
||||
1788526652,14:57:32,14:57:32,12,131304,37448,cap-wifi3,-59,309700000,344100000,6160,6512,00:04:45,00:00:00
|
||||
1788526654,14:57:34,14:57:34,11,92000,18872,cap-wifi3,-59,309700000,412900000,5600,5920,00:04:47,00:00:00
|
||||
1788526656,14:57:36,14:57:36,12,130144,24840,cap-wifi3,-60,309700000,390000000,6048,6512,00:04:49,00:00:00
|
||||
1788526658,14:57:38,14:57:38,9,105160,20800,cap-wifi3,-60,309700000,390000000,6048,6512,00:04:51,00:00:00
|
||||
1788526660,14:57:40,14:57:40,14,177144,59112,cap-wifi3,-57,309700000,344100000,6048,6288,00:04:53,00:00:00
|
||||
1788526662,14:57:42,14:57:42,11,136152,39360,cap-wifi3,-59,309700000,325000000,5600,5920,00:04:55,00:00:00
|
||||
1788526664,14:57:44,14:57:44,7,132416,46304,cap-wifi3,-59,309700000,325000000,5600,5920,00:04:57,00:00:00
|
||||
1788526666,14:57:46,14:57:46,8,462016,41704,cap-wifi3,-60,309700000,390000000,5600,6296,00:04:59,00:00:00
|
||||
1788526668,14:57:48,14:57:48,11,129736,41416,cap-wifi3,-59,309700000,390000000,5600,5920,00:05:01,00:00:00
|
||||
1788526670,14:57:50,14:57:51,14,401784,54464,cap-wifi3,-59,309700000,390000000,5600,5920,00:05:03,00:00:00
|
||||
1788526672,14:57:52,14:57:53,8,146064,92728,cap-wifi3,-56,309700000,433300000,6640,7008,00:05:05,00:00:00
|
||||
1788526674,14:57:54,14:57:55,14,111952,31488,cap-wifi3,-59,309700000,433300000,6160,6512,00:05:07,00:00:00
|
||||
1788526677,14:57:57,14:57:57,9,123096,20552,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:09,00:00:00
|
||||
1788526679,14:57:59,14:57:59,15,113008,17656,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:11,00:00:00
|
||||
1788526681,14:58:01,14:58:01,16,172400,59040,cap-wifi3,-58,309700000,433300000,6160,6512,00:05:14,00:00:00
|
||||
1788526683,14:58:03,14:58:03,10,190968,57448,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:16,00:00:00
|
||||
1788526685,14:58:05,14:58:05,8,183848,56872,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:18,00:00:00
|
||||
1788526687,14:58:07,14:58:07,9,305320,47576,cap-wifi3,-59,309700000,487500000,5600,5920,00:05:20,00:00:00
|
||||
1788526689,14:58:09,14:58:09,20,331408,59856,cap-wifi3,-58,309700000,455800000,5600,5920,00:05:22,00:00:00
|
||||
1788526691,14:58:11,14:58:11,10,322448,65576,cap-wifi3,-58,309700000,455800000,5600,5920,00:05:24,00:00:00
|
||||
1788526692,14:58:12,RECONNECT
|
||||
|
1
docs/messdaten/tp25-runde-1er/sampler-iphone.out
Normal file
1
docs/messdaten/tp25-runde-1er/sampler-iphone.out
Normal file
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-1er/sampler-iphone.csv (Takt 2s, Client F2:62:4C:E1:AF:09)
|
||||
1
docs/messdaten/tp25-runde-1er/sampler-iphone.stderr.log
Normal file
1
docs/messdaten/tp25-runde-1er/sampler-iphone.stderr.log
Normal file
@@ -0,0 +1 @@
|
||||
14:58:12 Verbindung weg -- neuer Versuch in 2 s
|
||||
26
docs/messdaten/tp25-runde-1er/sampler-s22.csv
Normal file
26
docs/messdaten/tp25-runde-1er/sampler-s22.csv
Normal file
@@ -0,0 +1,26 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788526644,14:57:24,14:57:24,41,472232,195392,cap-wifi5,-61,137600000,229400000,2800,2960,01:04:55,00:00:00
|
||||
1788526646,14:57:26,14:57:26,11,229864,36304,cap-wifi5,-59,172100000,229400000,2800,2960,01:04:57,00:00:00
|
||||
1788526648,14:57:28,14:57:28,8,143088,22488,cap-wifi5,-60,172100000,229400000,2800,2368,01:04:59,00:00:00
|
||||
1788526650,14:57:30,14:57:30,30,192288,49440,cap-wifi5,-60,172100000,229400000,2800,2368,01:05:01,00:00:00
|
||||
1788526652,14:57:32,14:57:32,12,131304,37448,cap-wifi5,-60,172100000,229400000,3360,3552,01:05:03,00:00:00
|
||||
1788526654,14:57:34,14:57:34,11,92000,18872,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:05,00:00:00
|
||||
1788526656,14:57:36,14:57:36,12,130144,24840,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:07,00:00:00
|
||||
1788526658,14:57:38,14:57:38,9,105160,20800,cap-wifi5,-59,129000000,258100000,3856,2960,01:05:09,00:00:00
|
||||
1788526660,14:57:40,14:57:40,14,177144,59112,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:11,00:00:00
|
||||
1788526662,14:57:42,14:57:42,11,136152,39360,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:13,00:00:00
|
||||
1788526664,14:57:44,14:57:45,7,132416,46304,cap-wifi5,-57,114700000,206500000,3360,2960,01:05:15,00:00:00
|
||||
1788526666,14:57:46,14:57:47,8,462016,41704,cap-wifi5,-57,114700000,206500000,2800,2960,01:05:17,00:00:00
|
||||
1788526669,14:57:49,14:57:49,11,129736,41416,cap-wifi5,-57,154900000,172100000,3360,3552,01:05:19,00:00:00
|
||||
1788526671,14:57:51,14:57:51,14,401784,54464,cap-wifi5,-57,154900000,172100000,3360,3552,01:05:21,00:00:00
|
||||
1788526673,14:57:53,14:57:53,8,146064,92728,cap-wifi5,-58,154900000,206500000,2800,2960,01:05:23,00:00:00
|
||||
1788526675,14:57:55,14:57:55,14,111952,31488,cap-wifi5,-58,154900000,229400000,2800,2960,01:05:26,00:00:00
|
||||
1788526677,14:57:57,14:57:57,9,123096,20552,cap-wifi5,-58,154900000,229400000,2800,2960,01:05:28,00:00:00
|
||||
1788526679,14:57:59,14:57:59,17,113008,17656,cap-wifi5,-58,103200000,229400000,2800,2960,01:05:30,00:00:00
|
||||
1788526681,14:58:01,14:58:01,9,172400,59040,cap-wifi5,-58,103200000,206500000,3248,3328,01:05:32,00:00:00
|
||||
1788526683,14:58:03,14:58:03,10,190968,57448,cap-wifi5,-58,103200000,206500000,3248,3328,01:05:34,00:00:00
|
||||
1788526685,14:58:05,14:58:05,10,183848,56872,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:36,00:00:00
|
||||
1788526687,14:58:07,14:58:07,9,305320,47576,cap-wifi5,-59,103200000,229400000,2800,2960,01:05:38,00:00:00
|
||||
1788526689,14:58:09,14:58:09,20,331408,59856,cap-wifi5,-59,103200000,229400000,2800,2960,01:05:40,00:00:00
|
||||
1788526691,14:58:11,14:58:11,10,322448,65576,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:42,00:00:00
|
||||
1788526692,14:58:12,RECONNECT
|
||||
|
1
docs/messdaten/tp25-runde-1er/sampler-s22.out
Normal file
1
docs/messdaten/tp25-runde-1er/sampler-s22.out
Normal file
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-1er/sampler-s22.csv (Takt 2s, Client 2A:0D:B0:5D:AD:A7)
|
||||
1
docs/messdaten/tp25-runde-1er/sampler-s22.stderr.log
Normal file
1
docs/messdaten/tp25-runde-1er/sampler-s22.stderr.log
Normal file
@@ -0,0 +1 @@
|
||||
14:58:12 Verbindung weg -- neuer Versuch in 2 s
|
||||
242
docs/messdaten/tp25-runde-1er/walk-ping-iphone.csv
Normal file
242
docs/messdaten/tp25-runde-1er/walk-ping-iphone.csv
Normal file
@@ -0,0 +1,242 @@
|
||||
ts_local,seq,ms
|
||||
14:57:24,0,3ms102us
|
||||
14:57:24,1,2ms682us
|
||||
14:57:25,2,2ms739us
|
||||
14:57:25,3,2ms889us
|
||||
14:57:25,4,2ms955us
|
||||
14:57:25,5,4ms434us
|
||||
14:57:25,6,4ms59us
|
||||
14:57:26,7,3ms540us
|
||||
14:57:26,8,98ms220us
|
||||
14:57:26,9,2ms841us
|
||||
14:57:26,10,95ms173us
|
||||
14:57:26,11,2ms688us
|
||||
14:57:27,12,113ms888us
|
||||
14:57:27,13,4ms866us
|
||||
14:57:27,14,2ms909us
|
||||
14:57:27,15,2ms776us
|
||||
14:57:27,16,2ms572us
|
||||
14:57:28,17,2ms931us
|
||||
14:57:28,18,2ms663us
|
||||
14:57:28,19,2ms796us
|
||||
14:57:28,20,2ms736us
|
||||
14:57:28,21,2ms826us
|
||||
14:57:29,22,2ms778us
|
||||
14:57:29,23,2ms741us
|
||||
14:57:29,24,2ms904us
|
||||
14:57:29,25,2ms744us
|
||||
14:57:29,26,2ms845us
|
||||
14:57:30,27,2ms850us
|
||||
14:57:30,28,2ms746us
|
||||
14:57:30,29,2ms973us
|
||||
14:57:30,30,2ms907us
|
||||
14:57:30,31,2ms771us
|
||||
14:57:31,32,2ms778us
|
||||
14:57:31,33,2ms793us
|
||||
14:57:31,34,2ms823us
|
||||
14:57:31,35,2ms717us
|
||||
14:57:31,36,5ms311us
|
||||
14:57:32,37,2ms752us
|
||||
14:57:32,38,2ms799us
|
||||
14:57:32,39,2ms964us
|
||||
14:57:32,40,2ms760us
|
||||
14:57:32,41,3ms53us
|
||||
14:57:33,42,2ms775us
|
||||
14:57:33,43,2ms793us
|
||||
14:57:33,44,4ms125us
|
||||
14:57:33,45,2ms696us
|
||||
14:57:33,46,2ms686us
|
||||
14:57:34,47,2ms738us
|
||||
14:57:34,48,2ms824us
|
||||
14:57:34,49,2ms607us
|
||||
14:57:34,50,2ms944us
|
||||
14:57:34,51,2ms854us
|
||||
14:57:35,52,2ms724us
|
||||
14:57:35,53,3ms453us
|
||||
14:57:35,54,3ms417us
|
||||
14:57:35,55,3ms535us
|
||||
14:57:35,56,2ms719us
|
||||
14:57:36,57,4ms498us
|
||||
14:57:36,58,2ms706us
|
||||
14:57:36,59,4ms279us
|
||||
14:57:36,60,2ms836us
|
||||
14:57:36,61,2ms646us
|
||||
14:57:37,62,2ms873us
|
||||
14:57:37,63,2ms782us
|
||||
14:57:37,64,2ms624us
|
||||
14:57:37,65,2ms881us
|
||||
14:57:37,66,2ms716us
|
||||
14:57:38,67,2ms763us
|
||||
14:57:38,68,2ms833us
|
||||
14:57:38,69,2ms879us
|
||||
14:57:38,70,2ms851us
|
||||
14:57:38,71,2ms777us
|
||||
14:57:39,72,2ms937us
|
||||
14:57:39,73,2ms821us
|
||||
14:57:39,74,2ms729us
|
||||
14:57:39,75,2ms892us
|
||||
14:57:39,76,2ms729us
|
||||
14:57:40,77,2ms755us
|
||||
14:57:40,78,2ms932us
|
||||
14:57:40,79,2ms701us
|
||||
14:57:40,80,2ms662us
|
||||
14:57:40,81,2ms651us
|
||||
14:57:41,82,5ms991us
|
||||
14:57:41,83,2ms728us
|
||||
14:57:41,84,2ms756us
|
||||
14:57:41,85,2ms716us
|
||||
14:57:41,86,2ms707us
|
||||
14:57:42,87,2ms785us
|
||||
14:57:42,88,2ms594us
|
||||
14:57:42,89,2ms747us
|
||||
14:57:42,90,2ms712us
|
||||
14:57:42,91,3ms258us
|
||||
14:57:43,92,2ms727us
|
||||
14:57:43,93,2ms623us
|
||||
14:57:43,94,2ms723us
|
||||
14:57:43,95,2ms749us
|
||||
14:57:43,96,2ms700us
|
||||
14:57:44,97,2ms723us
|
||||
14:57:44,98,2ms735us
|
||||
14:57:44,99,3ms646us
|
||||
14:57:44,100,2ms718us
|
||||
14:57:44,101,2ms740us
|
||||
14:57:45,102,2ms768us
|
||||
14:57:45,103,2ms663us
|
||||
14:57:45,104,2ms639us
|
||||
14:57:45,105,2ms731us
|
||||
14:57:45,106,3ms290us
|
||||
14:57:46,107,2ms822us
|
||||
14:57:46,108,2ms844us
|
||||
14:57:46,109,2ms617us
|
||||
14:57:46,110,2ms734us
|
||||
14:57:46,111,3ms447us
|
||||
14:57:47,112,3ms169us
|
||||
14:57:47,113,3ms247us
|
||||
14:57:47,114,2ms564us
|
||||
14:57:47,115,4ms516us
|
||||
14:57:47,116,2ms623us
|
||||
14:57:48,117,2ms675us
|
||||
14:57:48,118,2ms877us
|
||||
14:57:48,119,3ms310us
|
||||
14:57:48,120,2ms851us
|
||||
14:57:48,121,2ms803us
|
||||
14:57:49,122,7ms998us
|
||||
14:57:49,123,2ms887us
|
||||
14:57:49,124,2ms852us
|
||||
14:57:49,125,2ms846us
|
||||
14:57:49,126,2ms899us
|
||||
14:57:50,127,2ms913us
|
||||
14:57:50,128,2ms680us
|
||||
14:57:50,129,2ms715us
|
||||
14:57:50,130,3ms374us
|
||||
14:57:50,131,2ms670us
|
||||
14:57:51,132,3ms148us
|
||||
14:57:51,133,2ms932us
|
||||
14:57:51,134,2ms831us
|
||||
14:57:51,135,4ms780us
|
||||
14:57:51,136,2ms911us
|
||||
14:57:52,137,3ms85us
|
||||
14:57:52,138,3ms589us
|
||||
14:57:52,139,2ms697us
|
||||
14:57:52,140,4ms876us
|
||||
14:57:52,141,2ms867us
|
||||
14:57:53,142,3ms283us
|
||||
14:57:53,143,2ms710us
|
||||
14:57:53,144,2ms801us
|
||||
14:57:53,145,2ms928us
|
||||
14:57:53,146,2ms640us
|
||||
14:57:54,147,2ms678us
|
||||
14:57:54,148,4ms976us
|
||||
14:57:54,149,3ms408us
|
||||
14:57:54,150,2ms706us
|
||||
14:57:54,151,2ms827us
|
||||
14:57:55,152,2ms884us
|
||||
14:57:55,153,2ms855us
|
||||
14:57:55,154,2ms787us
|
||||
14:57:55,155,2ms695us
|
||||
14:57:55,156,2ms902us
|
||||
14:57:56,157,2ms749us
|
||||
14:57:56,158,2ms838us
|
||||
14:57:56,159,3ms937us
|
||||
14:57:57,160,3ms43us
|
||||
14:57:57,161,2ms870us
|
||||
14:57:57,162,3ms357us
|
||||
14:57:57,163,2ms756us
|
||||
14:57:57,164,2ms679us
|
||||
14:57:57,165,2ms863us
|
||||
14:57:57,166,2ms768us
|
||||
14:57:58,167,2ms858us
|
||||
14:57:58,168,3ms30us
|
||||
14:57:58,169,2ms677us
|
||||
14:57:58,170,2ms725us
|
||||
14:57:58,171,2ms919us
|
||||
14:57:59,172,2ms688us
|
||||
14:57:59,173,2ms821us
|
||||
14:57:59,174,2ms805us
|
||||
14:57:59,175,2ms709us
|
||||
14:57:59,176,2ms989us
|
||||
14:58:00,177,2ms589us
|
||||
14:58:00,178,3ms835us
|
||||
14:58:00,179,3ms194us
|
||||
14:58:00,180,2ms662us
|
||||
14:58:00,181,2ms686us
|
||||
14:58:01,182,2ms704us
|
||||
14:58:01,183,2ms752us
|
||||
14:58:01,184,2ms656us
|
||||
14:58:01,185,2ms904us
|
||||
14:58:01,186,2ms823us
|
||||
14:58:02,187,2ms656us
|
||||
14:58:02,188,2ms813us
|
||||
14:58:02,189,2ms644us
|
||||
14:58:02,190,2ms782us
|
||||
14:58:02,191,2ms722us
|
||||
14:58:03,192,2ms674us
|
||||
14:58:03,193,5ms657us
|
||||
14:58:03,194,4ms701us
|
||||
14:58:03,195,2ms772us
|
||||
14:58:03,196,2ms661us
|
||||
14:58:04,197,2ms660us
|
||||
14:58:04,198,2ms859us
|
||||
14:58:04,199,2ms800us
|
||||
14:58:04,200,2ms706us
|
||||
14:58:04,201,2ms847us
|
||||
14:58:05,202,2ms625us
|
||||
14:58:05,203,2ms816us
|
||||
14:58:05,204,2ms703us
|
||||
14:58:05,205,2ms818us
|
||||
14:58:05,206,3ms162us
|
||||
14:58:06,207,2ms673us
|
||||
14:58:06,208,2ms781us
|
||||
14:58:06,209,2ms607us
|
||||
14:58:06,210,2ms990us
|
||||
14:58:06,211,2ms602us
|
||||
14:58:07,212,2ms711us
|
||||
14:58:07,213,2ms819us
|
||||
14:58:07,214,2ms757us
|
||||
14:58:07,215,2ms605us
|
||||
14:58:07,216,2ms770us
|
||||
14:58:08,217,2ms682us
|
||||
14:58:08,218,4ms824us
|
||||
14:58:08,219,2ms623us
|
||||
14:58:08,220,2ms566us
|
||||
14:58:08,221,2ms724us
|
||||
14:58:09,222,3ms737us
|
||||
14:58:09,223,3ms273us
|
||||
14:58:09,224,2ms809us
|
||||
14:58:09,225,2ms619us
|
||||
14:58:09,226,2ms709us
|
||||
14:58:10,227,2ms909us
|
||||
14:58:10,228,2ms707us
|
||||
14:58:10,229,2ms909us
|
||||
14:58:10,230,2ms610us
|
||||
14:58:10,231,3ms251us
|
||||
14:58:11,232,2ms689us
|
||||
14:58:11,233,2ms714us
|
||||
14:58:11,234,2ms680us
|
||||
14:58:11,235,2ms644us
|
||||
14:58:11,236,2ms665us
|
||||
14:58:12,237,3ms326us
|
||||
14:58:12,238,2ms749us
|
||||
14:58:12,239,2ms713us
|
||||
14:58:12,,RECONNECT
|
||||
|
238
docs/messdaten/tp25-runde-1er/walk-ping-s22.csv
Normal file
238
docs/messdaten/tp25-runde-1er/walk-ping-s22.csv
Normal file
@@ -0,0 +1,238 @@
|
||||
ts_local,seq,ms
|
||||
14:57:24,0,
|
||||
14:57:25,1,
|
||||
14:57:25,2,
|
||||
14:57:25,3,
|
||||
14:57:25,4,
|
||||
14:57:25,5,
|
||||
14:57:26,6,
|
||||
14:57:26,7,
|
||||
14:57:26,8,
|
||||
14:57:26,9,
|
||||
14:57:26,10,
|
||||
14:57:27,11,
|
||||
14:57:27,12,
|
||||
14:57:27,13,
|
||||
14:57:27,14,
|
||||
14:57:27,15,unre...
|
||||
14:57:28,16,
|
||||
14:57:28,17,
|
||||
14:57:28,18,
|
||||
14:57:28,19,
|
||||
14:57:28,20,
|
||||
14:57:29,21,
|
||||
14:57:29,22,
|
||||
14:57:29,23,
|
||||
14:57:29,24,
|
||||
14:57:29,25,
|
||||
14:57:30,26,
|
||||
14:57:30,27,
|
||||
14:57:30,28,
|
||||
14:57:30,29,
|
||||
14:57:30,30,
|
||||
14:57:31,31,unre...
|
||||
14:57:31,32,
|
||||
14:57:31,33,
|
||||
14:57:31,34,
|
||||
14:57:31,35,
|
||||
14:57:32,36,
|
||||
14:57:32,37,
|
||||
14:57:32,38,
|
||||
14:57:32,39,
|
||||
14:57:32,40,
|
||||
14:57:33,41,
|
||||
14:57:33,42,
|
||||
14:57:33,43,
|
||||
14:57:33,44,
|
||||
14:57:33,45,
|
||||
14:57:34,46,
|
||||
14:57:34,47,unre...
|
||||
14:57:34,48,
|
||||
14:57:34,49,
|
||||
14:57:34,50,
|
||||
14:57:35,51,
|
||||
14:57:35,52,
|
||||
14:57:35,53,
|
||||
14:57:35,54,
|
||||
14:57:35,55,
|
||||
14:57:36,56,
|
||||
14:57:36,57,
|
||||
14:57:36,58,
|
||||
14:57:36,59,
|
||||
14:57:37,60,
|
||||
14:57:37,61,
|
||||
14:57:37,62,
|
||||
14:57:37,63,unre...
|
||||
14:57:38,64,
|
||||
14:57:38,65,
|
||||
14:57:38,66,
|
||||
14:57:38,67,
|
||||
14:57:38,68,
|
||||
14:57:38,69,
|
||||
14:57:39,70,
|
||||
14:57:39,71,
|
||||
14:57:39,72,
|
||||
14:57:39,73,
|
||||
14:57:39,74,
|
||||
14:57:40,75,
|
||||
14:57:40,76,
|
||||
14:57:40,77,
|
||||
14:57:40,78,
|
||||
14:57:40,79,unre...
|
||||
14:57:41,80,
|
||||
14:57:41,81,
|
||||
14:57:41,82,
|
||||
14:57:41,83,
|
||||
14:57:41,84,
|
||||
14:57:42,85,
|
||||
14:57:42,86,
|
||||
14:57:42,87,
|
||||
14:57:42,88,
|
||||
14:57:42,89,
|
||||
14:57:43,90,
|
||||
14:57:43,91,
|
||||
14:57:43,92,
|
||||
14:57:43,93,
|
||||
14:57:43,94,
|
||||
14:57:43,95,unre...
|
||||
14:57:44,96,
|
||||
14:57:44,97,
|
||||
14:57:44,98,
|
||||
14:57:44,99,
|
||||
14:57:45,100,
|
||||
14:57:45,101,
|
||||
14:57:45,102,
|
||||
14:57:45,103,
|
||||
14:57:45,104,
|
||||
14:57:46,105,
|
||||
14:57:46,106,
|
||||
14:57:46,107,
|
||||
14:57:46,108,
|
||||
14:57:46,109,
|
||||
14:57:47,110,
|
||||
14:57:47,111,unre...
|
||||
14:57:47,112,
|
||||
14:57:47,113,
|
||||
14:57:47,114,
|
||||
14:57:48,115,
|
||||
14:57:48,116,
|
||||
14:57:48,117,
|
||||
14:57:48,118,
|
||||
14:57:49,119,
|
||||
14:57:49,120,
|
||||
14:57:49,121,
|
||||
14:57:49,122,
|
||||
14:57:49,123,
|
||||
14:57:50,124,
|
||||
14:57:50,125,
|
||||
14:57:50,126,
|
||||
14:57:50,127,unre...
|
||||
14:57:50,128,
|
||||
14:57:51,129,
|
||||
14:57:51,130,
|
||||
14:57:51,131,
|
||||
14:57:51,132,
|
||||
14:57:51,133,
|
||||
14:57:52,134,
|
||||
14:57:52,135,
|
||||
14:57:52,136,
|
||||
14:57:52,137,
|
||||
14:57:52,138,
|
||||
14:57:53,139,
|
||||
14:57:53,140,
|
||||
14:57:53,141,
|
||||
14:57:53,142,
|
||||
14:57:53,143,unre...
|
||||
14:57:54,144,
|
||||
14:57:54,145,
|
||||
14:57:54,146,
|
||||
14:57:54,147,
|
||||
14:57:54,148,
|
||||
14:57:55,149,
|
||||
14:57:55,150,
|
||||
14:57:55,151,
|
||||
14:57:55,152,
|
||||
14:57:55,153,
|
||||
14:57:56,154,
|
||||
14:57:56,155,
|
||||
14:57:56,156,
|
||||
14:57:57,157,
|
||||
14:57:57,158,
|
||||
14:57:57,159,unre...
|
||||
14:57:57,160,
|
||||
14:57:57,161,
|
||||
14:57:57,162,
|
||||
14:57:57,163,
|
||||
14:57:58,164,
|
||||
14:57:58,165,
|
||||
14:57:58,166,
|
||||
14:57:58,167,
|
||||
14:57:58,168,
|
||||
14:57:59,169,
|
||||
14:57:59,170,
|
||||
14:57:59,171,
|
||||
14:57:59,172,
|
||||
14:57:59,173,
|
||||
14:58:00,174,
|
||||
14:58:00,175,unre...
|
||||
14:58:00,176,
|
||||
14:58:00,177,
|
||||
14:58:00,178,
|
||||
14:58:01,179,
|
||||
14:58:01,180,
|
||||
14:58:01,181,
|
||||
14:58:01,182,
|
||||
14:58:01,183,
|
||||
14:58:02,184,
|
||||
14:58:02,185,
|
||||
14:58:02,186,
|
||||
14:58:02,187,
|
||||
14:58:02,188,
|
||||
14:58:03,189,
|
||||
14:58:03,190,
|
||||
14:58:03,191,unre...
|
||||
14:58:03,192,
|
||||
14:58:03,193,
|
||||
14:58:04,194,
|
||||
14:58:04,195,
|
||||
14:58:04,196,
|
||||
14:58:04,197,
|
||||
14:58:04,198,
|
||||
14:58:05,199,
|
||||
14:58:05,200,
|
||||
14:58:05,201,
|
||||
14:58:05,202,
|
||||
14:58:05,203,
|
||||
14:58:06,204,
|
||||
14:58:06,205,
|
||||
14:58:06,206,
|
||||
14:58:06,207,unre...
|
||||
14:58:07,208,
|
||||
14:58:07,209,
|
||||
14:58:07,210,
|
||||
14:58:07,211,
|
||||
14:58:07,212,
|
||||
14:58:08,213,
|
||||
14:58:08,214,
|
||||
14:58:08,215,
|
||||
14:58:08,216,
|
||||
14:58:08,217,
|
||||
14:58:09,218,
|
||||
14:58:09,219,
|
||||
14:58:09,220,
|
||||
14:58:09,221,
|
||||
14:58:09,222,
|
||||
14:58:09,223,unre...
|
||||
14:58:10,224,
|
||||
14:58:10,225,
|
||||
14:58:10,226,
|
||||
14:58:10,227,
|
||||
14:58:11,228,
|
||||
14:58:11,229,
|
||||
14:58:11,230,
|
||||
14:58:11,231,
|
||||
14:58:11,232,
|
||||
14:58:12,233,
|
||||
14:58:12,234,
|
||||
14:58:12,235,
|
||||
14:58:12,,RECONNECT
|
||||
|
6
docs/messdaten/tp25-runde-dauerping/ap-map.txt
Normal file
6
docs/messdaten/tp25-runde-dauerping/ap-map.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
cap-wifi1=ap2/5GHz
|
||||
cap-wifi2=ap3/5GHz
|
||||
cap-wifi3=ap1/5GHz
|
||||
cap-wifi4=ap3/2,4GHz
|
||||
cap-wifi5=ap1/2,4GHz
|
||||
cap-wifi6=ap2/2,4GHz
|
||||
@@ -0,0 +1 @@
|
||||
ts_epoch,ts_local,marker
|
||||
|
@@ -0,0 +1,43 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788526610,14:56:50,14:56:50,50,160216,1109704,cap-wifi2,-69,137600000,275300000,45848,2240,01:04:23,00:00:00
|
||||
1788526612,14:56:52,14:56:52,6,151312,62480,cap-wifi2,-69,137600000,275300000,45848,2240,01:04:25,00:00:00
|
||||
1788526614,14:56:54,14:56:54,15,127416,44832,cap-wifi2,-69,137600000,309700000,36152,6320,01:04:27,00:00:00
|
||||
1788526616,14:56:56,14:56:56,4,127712,21960,cap-wifi2,-69,103200000,325000000,42008,9736,01:04:29,00:00:00
|
||||
1788526618,14:56:58,14:56:58,9,157888,29816,cap-wifi2,-69,103200000,325000000,42008,9736,01:04:31,00:00:00
|
||||
1788526620,14:57:00,14:57:00,16,322208,124400,cap-wifi2,-69,103200000,344100000,123600,58608,01:04:33,00:00:00
|
||||
1788526622,14:57:02,14:57:03,10,451416,4332552,cap-wifi2,-69,137600000,275300000,193568,29704,01:04:35,00:00:00
|
||||
1788526624,14:57:04,14:57:05,9,398720,136640,cap-wifi2,-69,137600000,292500000,40792,7440,01:04:37,00:00:00
|
||||
1788526627,14:57:07,14:57:07,15,947800,446984,cap-wifi2,-69,137600000,292500000,40792,7440,01:04:40,00:00:00
|
||||
1788526629,14:57:09,14:57:09,12,7610296,3321592,cap-wifi2,-69,154900000,292500000,89400,14304,01:04:42,00:00:00
|
||||
1788526631,14:57:11,14:57:11,18,2720136,2091232,cap-wifi2,-69,103200000,275300000,69264,10760,01:04:44,00:00:00
|
||||
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi2,-69,103200000,275300000,69264,10760,01:04:46,00:00:00
|
||||
1788526635,14:57:15,14:57:15,7,108584,42016,cap-wifi2,-69,103200000,309700000,78112,11920,01:04:48,00:00:00
|
||||
1788526637,14:57:17,14:57:17,4,309312,51096,cap-wifi2,-68,103200000,309700000,117392,10152,01:04:50,00:00:00
|
||||
1788526639,14:57:19,14:57:19,14,309864,66576,cap-wifi2,-68,103200000,309700000,117392,10152,01:04:52,00:00:00
|
||||
1788526641,14:57:21,14:57:21,6,150056,22800,cap-wifi2,-68,103200000,309700000,53888,10272,01:04:54,00:00:00
|
||||
1788526643,14:57:23,14:57:23,14,510016,213944,cap-wifi2,-68,103200000,309700000,61328,9088,01:04:56,00:00:00
|
||||
1788526645,14:57:25,14:57:25,19,507656,169768,cap-wifi2,-68,103200000,309700000,61328,9088,01:04:58,00:00:00
|
||||
1788526647,14:57:27,14:57:27,9,136752,33856,cap-wifi2,-69,103200000,309700000,41640,8560,01:05:00,00:00:00
|
||||
1788526649,14:57:29,14:57:29,18,143088,22488,cap-wifi2,-69,103200000,292500000,61120,8192,01:05:02,00:00:00
|
||||
1788526651,14:57:31,14:57:31,15,192288,49440,cap-wifi2,-69,103200000,292500000,61120,8192,01:05:04,00:00:00
|
||||
1788526653,14:57:33,14:57:33,9,131304,37448,cap-wifi2,-69,137600000,309700000,57760,8136,01:05:06,00:00:00
|
||||
1788526655,14:57:35,14:57:35,11,92000,18872,cap-wifi2,-69,137600000,344100000,56408,8592,01:05:08,00:00:00
|
||||
1788526657,14:57:37,14:57:37,9,130144,24840,cap-wifi2,-69,137600000,344100000,56408,8592,01:05:10,00:00:00
|
||||
1788526659,14:57:39,14:57:39,20,105160,20800,cap-wifi2,-69,137600000,325000000,19344,5200,01:05:12,00:00:00
|
||||
1788526661,14:57:41,14:57:41,11,177144,59112,cap-wifi2,-71,154900000,275300000,111184,14496,01:05:14,00:00:00
|
||||
1788526663,14:57:43,14:57:43,16,136152,39360,cap-wifi2,-71,154900000,275300000,111184,14496,01:05:16,00:00:00
|
||||
1788526665,14:57:45,14:57:45,16,132416,46304,cap-wifi2,-70,154900000,309700000,44928,8560,01:05:18,00:00:00
|
||||
1788526667,14:57:47,14:57:47,11,462016,41704,cap-wifi2,-70,154900000,309700000,397536,18704,01:05:20,00:00:00
|
||||
1788526669,14:57:49,14:57:49,24,129736,41416,cap-wifi2,-70,154900000,309700000,397536,18704,01:05:22,00:00:00
|
||||
1788526671,14:57:51,14:57:51,7,401784,54464,cap-wifi2,-76,103200000,206500000,44784,8560,01:05:24,00:00:00
|
||||
1788526673,14:57:53,14:57:53,14,101992,21720,cap-wifi2,-69,103200000,292500000,55400,9120,01:05:26,00:00:00
|
||||
1788526675,14:57:55,14:57:55,14,152504,61272,cap-wifi2,-69,103200000,292500000,55400,9120,01:05:28,00:00:00
|
||||
1788526677,14:57:57,14:57:57,22,130520,26552,cap-wifi2,-70,103200000,260000000,55304,10816,01:05:30,00:00:00
|
||||
1788526679,14:57:59,14:57:59,17,155408,24688,cap-wifi2,-69,103200000,275300000,58480,8720,01:05:32,00:00:00
|
||||
1788526681,14:58:01,14:58:01,9,244456,41424,cap-wifi2,-69,103200000,275300000,58480,8720,01:05:34,00:00:00
|
||||
1788526683,14:58:03,14:58:03,10,115640,26032,cap-wifi2,-69,103200000,260000000,38208,22096,01:05:36,00:00:00
|
||||
1788526685,14:58:05,14:58:05,10,154824,24456,cap-wifi2,-70,137600000,260000000,65000,8000,01:05:38,00:00:00
|
||||
1788526687,14:58:07,14:58:07,9,135144,25000,cap-wifi2,-70,137600000,260000000,65000,8000,01:05:40,00:00:00
|
||||
1788526689,14:58:09,14:58:10,20,122800,29936,cap-wifi2,-68,137600000,275300000,18856,4048,01:05:42,00:00:00
|
||||
1788526691,14:58:11,14:58:12,10,152160,65768,cap-wifi2,-68,137600000,206500000,40064,12024,01:05:44,00:00:00
|
||||
1788526692,14:58:12,RECONNECT
|
||||
|
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-ipad.csv (Takt 2s, Client CA:B8:D4:3F:8A:81)
|
||||
@@ -0,0 +1,43 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788526610,14:56:50,14:56:50,50,160216,1109704,cap-wifi3,-58,309700000,412900000,0,0,00:04:03,00:00:03.010
|
||||
1788526612,14:56:52,14:56:52,6,151312,62480,cap-wifi3,-57,309700000,412900000,0,0,00:04:05,00:00:00
|
||||
1788526614,14:56:54,14:56:54,15,127416,44832,cap-wifi3,-57,309700000,412900000,2800,2960,00:04:07,00:00:00
|
||||
1788526616,14:56:56,14:56:56,4,127712,21960,cap-wifi3,-57,309700000,412900000,2800,2960,00:04:09,00:00:00
|
||||
1788526618,14:56:58,14:56:58,9,157888,29816,cap-wifi3,-57,309700000,412900000,3248,3552,00:04:11,00:00:00
|
||||
1788526620,14:57:00,14:57:00,16,322208,124400,cap-wifi3,-57,344100000,325000000,3360,3552,00:04:13,00:00:00
|
||||
1788526622,14:57:02,14:57:03,10,451416,4332552,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:15,00:00:00
|
||||
1788526624,14:57:04,14:57:05,9,398720,136640,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:17,00:00:00
|
||||
1788526627,14:57:07,14:57:07,15,947800,446984,cap-wifi3,-59,344100000,325000000,3360,3552,00:04:20,00:00:00
|
||||
1788526629,14:57:09,14:57:09,12,7610296,3321592,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:22,00:00:00
|
||||
1788526631,14:57:11,14:57:11,18,2720136,2091232,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:24,00:00:00
|
||||
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi3,-57,344100000,325000000,3360,3552,00:04:26,00:00:00
|
||||
1788526635,14:57:15,14:57:15,7,108584,42016,cap-wifi3,-57,344100000,344100000,2800,2960,00:04:28,00:00:00
|
||||
1788526637,14:57:17,14:57:17,4,309312,51096,cap-wifi3,-57,344100000,344100000,2800,2960,00:04:30,00:00:00
|
||||
1788526639,14:57:19,14:57:19,14,309864,66576,cap-wifi3,-58,344100000,325000000,2800,2960,00:04:32,00:00:00
|
||||
1788526641,14:57:21,14:57:21,6,150056,22800,cap-wifi3,-57,309700000,344100000,3808,4000,00:04:34,00:00:00
|
||||
1788526643,14:57:23,14:57:23,14,510016,213944,cap-wifi3,-57,309700000,344100000,3808,4000,00:04:36,00:00:00
|
||||
1788526645,14:57:25,14:57:25,19,507656,169768,cap-wifi3,-57,309700000,325000000,2800,2960,00:04:38,00:00:00
|
||||
1788526647,14:57:27,14:57:27,9,136752,33856,cap-wifi3,-59,309700000,309700000,6160,6512,00:04:40,00:00:00
|
||||
1788526649,14:57:29,14:57:29,18,143088,22488,cap-wifi3,-59,309700000,309700000,6160,6512,00:04:42,00:00:00
|
||||
1788526651,14:57:31,14:57:31,15,192288,49440,cap-wifi3,-59,309700000,344100000,6160,6512,00:04:44,00:00:00
|
||||
1788526653,14:57:33,14:57:33,9,131304,37448,cap-wifi3,-59,309700000,412900000,5600,5920,00:04:46,00:00:00
|
||||
1788526655,14:57:35,14:57:35,11,92000,18872,cap-wifi3,-59,309700000,412900000,5600,5920,00:04:48,00:00:00
|
||||
1788526657,14:57:37,14:57:37,9,130144,24840,cap-wifi3,-60,309700000,390000000,6048,6512,00:04:50,00:00:00
|
||||
1788526659,14:57:39,14:57:39,20,105160,20800,cap-wifi3,-57,309700000,344100000,6048,6288,00:04:52,00:00:00
|
||||
1788526661,14:57:41,14:57:41,11,177144,59112,cap-wifi3,-57,309700000,344100000,6048,6288,00:04:54,00:00:00
|
||||
1788526663,14:57:43,14:57:43,16,136152,39360,cap-wifi3,-59,309700000,325000000,5600,5920,00:04:56,00:00:00
|
||||
1788526665,14:57:45,14:57:45,16,132416,46304,cap-wifi3,-60,309700000,390000000,5600,6296,00:04:58,00:00:00
|
||||
1788526667,14:57:47,14:57:47,11,462016,41704,cap-wifi3,-60,309700000,390000000,5600,6296,00:05:00,00:00:00
|
||||
1788526669,14:57:49,14:57:49,24,129736,41416,cap-wifi3,-59,309700000,390000000,5600,5920,00:05:02,00:00:00
|
||||
1788526671,14:57:51,14:57:51,7,234376,122480,cap-wifi3,-56,309700000,433300000,6640,7008,00:05:04,00:00:00
|
||||
1788526673,14:57:53,14:57:53,14,101992,21720,cap-wifi3,-56,309700000,433300000,6640,7008,00:05:06,00:00:00
|
||||
1788526675,14:57:55,14:57:55,14,152504,61272,cap-wifi3,-59,309700000,433300000,6160,6512,00:05:08,00:00:00
|
||||
1788526677,14:57:57,14:57:57,22,130520,26552,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:10,00:00:00
|
||||
1788526679,14:57:59,14:57:59,17,155408,24688,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:12,00:00:00
|
||||
1788526681,14:58:01,14:58:01,9,244456,41424,cap-wifi3,-58,309700000,433300000,6160,6512,00:05:14,00:00:00
|
||||
1788526683,14:58:03,14:58:03,10,115640,26032,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:16,00:00:00
|
||||
1788526685,14:58:05,14:58:05,10,154824,24456,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:18,00:00:00
|
||||
1788526687,14:58:07,14:58:08,9,135144,25000,cap-wifi3,-59,309700000,487500000,5600,5920,00:05:20,00:00:00
|
||||
1788526689,14:58:09,14:58:10,20,122800,29936,cap-wifi3,-58,309700000,455800000,5600,5920,00:05:22,00:00:00
|
||||
1788526691,14:58:11,14:58:12,10,152160,65768,cap-wifi3,-58,309700000,455800000,6160,6512,00:05:24,00:00:00
|
||||
1788526692,14:58:12,RECONNECT
|
||||
|
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-iphone.csv (Takt 2s, Client F2:62:4C:E1:AF:09)
|
||||
@@ -0,0 +1,42 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788526611,14:56:51,14:56:51,38,120880,24032,cap-wifi6,-85,68800000,17200000,166280,4310536,01:04:25,00:00:00
|
||||
1788526613,14:56:53,14:56:53,9,151312,62480,cap-wifi6,-85,103200000,17200000,550344,592824,01:04:27,00:00:00
|
||||
1788526615,14:56:55,14:56:55,10,127416,44832,cap-wifi6,-86,68800000,25800000,413184,340240,01:04:29,00:00:00
|
||||
1788526617,14:56:57,14:56:57,6,127712,21960,cap-wifi6,-86,68800000,25800000,413184,340240,01:04:31,00:00:00
|
||||
1788526619,14:56:59,14:56:59,13,157888,29816,cap-wifi6,-85,103200000,34400000,1524128,1126592,01:04:33,00:00:00
|
||||
1788526621,14:57:01,14:57:01,7,322208,124400,cap-wifi6,-86,68800000,34400000,1886112,547568,01:04:35,00:00:00
|
||||
1788526623,14:57:03,14:57:03,13,451416,4332552,cap-wifi6,-86,68800000,34400000,1886112,547568,01:04:37,00:00:00
|
||||
1788526625,14:57:05,14:57:05,10,398720,136640,cap-wifi6,-85,68800000,17200000,1079440,2625392,01:04:39,00:00:00
|
||||
1788526627,14:57:07,14:57:07,12,947800,446984,cap-wifi6,-86,68800000,17200000,1108088,760040,01:04:42,00:00:00
|
||||
1788526629,14:57:09,14:57:09,20,7610296,3321592,cap-wifi6,-86,68800000,17200000,1108088,760040,01:04:44,00:00:00
|
||||
1788526631,14:57:11,14:57:11,8,2720136,2091232,cap-wifi6,-82,68800000,51600000,1684720,1013032,01:04:46,00:00:00
|
||||
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi6,-87,103200000,25800000,324776,3447064,01:04:48,00:00:00
|
||||
1788526636,14:57:16,14:57:15,7,108584,42016,cap-wifi6,-87,103200000,25800000,324776,3447064,01:04:50,00:00:00
|
||||
1788526637,14:57:17,14:57:17,4,1478952,581848,cap-wifi6,-85,103200000,17200000,598680,602896,01:04:52,00:00:00
|
||||
1788526639,14:57:19,14:57:19,14,229272,54576,cap-wifi6,-84,103200000,34400000,1017664,775360,01:04:54,00:00:00
|
||||
1788526641,14:57:21,14:57:21,6,100688,29040,cap-wifi6,-84,103200000,34400000,1017664,775360,01:04:56,00:00:00
|
||||
1788526644,14:57:24,14:57:23,14,472232,195392,cap-wifi6,-86,68800000,17200000,14752,6688,01:04:58,00:00:00
|
||||
1788526645,14:57:25,14:57:25,19,229864,36304,cap-wifi6,-86,68800000,17200000,1094984,789880,01:05:00,00:00:00
|
||||
1788526647,14:57:27,14:57:28,9,132384,26968,cap-wifi6,-86,68800000,17200000,1094984,789880,01:05:02,00:00:00
|
||||
1788526649,14:57:29,14:57:30,18,196672,48240,cap-wifi6,-84,68800000,51600000,912296,563704,01:05:04,00:00:00
|
||||
1788526652,14:57:32,14:57:32,15,237176,31328,cap-wifi6,-87,68800000,11000000,2448600,1495240,01:05:06,00:00:00
|
||||
1788526654,14:57:34,14:57:34,9,147328,27456,cap-wifi6,-87,68800000,17200000,1326824,729536,01:05:08,00:00:00
|
||||
1788526656,14:57:36,14:57:36,11,122784,22816,cap-wifi6,-87,68800000,17200000,1326824,729536,01:05:10,00:00:00
|
||||
1788526658,14:57:38,14:57:38,9,122248,26192,cap-wifi6,-83,68800000,51600000,1292552,729408,01:05:12,00:00:00
|
||||
1788526660,14:57:40,14:57:40,14,167632,49032,cap-wifi6,-87,103200000,17200000,2131488,1138888,01:05:14,00:00:00
|
||||
1788526662,14:57:42,14:57:42,11,89248,17856,cap-wifi6,-87,103200000,17200000,2131488,1138888,01:05:16,00:00:00
|
||||
1788526664,14:57:44,14:57:44,7,125232,33536,cap-wifi6,-86,103200000,17200000,1495112,774112,01:05:18,00:00:00
|
||||
1788526666,14:57:46,14:57:46,8,1056872,260048,cap-wifi6,-86,103200000,17200000,773656,584032,01:05:20,00:00:00
|
||||
1788526668,14:57:48,14:57:48,11,172776,252208,cap-wifi6,-86,103200000,17200000,773656,584032,01:05:22,00:00:00
|
||||
1788526670,14:57:50,14:57:50,14,116656,22744,cap-wifi6,-87,51600000,17200000,256424,250360,01:05:24,00:00:00
|
||||
1788526672,14:57:52,14:57:52,8,234376,122480,cap-wifi6,-83,51600000,51600000,771864,575120,01:05:26,00:00:00
|
||||
1788526674,14:57:54,14:57:54,14,101992,21720,cap-wifi6,-83,51600000,51600000,771864,575120,01:05:28,00:00:00
|
||||
1788526676,14:57:56,14:57:56,9,152504,61272,cap-wifi6,-84,68800000,17200000,944720,547864,01:05:31,00:00:00
|
||||
1788526678,14:57:58,14:57:58,15,130520,26552,cap-wifi6,-88,51600000,17200000,1086104,614336,01:05:33,00:00:00
|
||||
1788526680,14:58:00,14:58:00,16,155408,24688,cap-wifi6,-88,51600000,17200000,1086104,614336,01:05:35,00:00:00
|
||||
1788526682,14:58:02,14:58:02,10,244456,41424,cap-wifi6,-85,68800000,17200000,1515776,563200,01:05:37,00:00:00
|
||||
1788526684,14:58:04,14:58:04,8,183848,56872,cap-wifi6,-84,103200000,25800000,888888,696272,01:05:39,00:00:00
|
||||
1788526686,14:58:06,14:58:06,9,305320,47576,cap-wifi6,-84,103200000,25800000,888888,696272,01:05:41,00:00:00
|
||||
1788526688,14:58:08,14:58:08,14,331408,59856,cap-wifi6,-84,68800000,34400000,860480,583048,01:05:43,00:00:00
|
||||
1788526690,14:58:10,14:58:10,17,322448,65576,cap-wifi6,-87,51600000,25800000,1068352,553088,01:05:45,00:00:00
|
||||
1788526692,14:58:12,RECONNECT
|
||||
|
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-macbook.csv (Takt 2s, Client 56:71:6C:22:E6:A9)
|
||||
@@ -0,0 +1,42 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788526611,14:56:51,14:56:51,38,120880,24032,cap-wifi5,-51,137600000,229400000,0,0,01:04:22,00:00:09
|
||||
1788526613,14:56:53,14:56:53,9,151312,62480,cap-wifi5,-51,137600000,258100000,1680,1776,01:04:24,00:00:00
|
||||
1788526615,14:56:55,14:56:55,10,127416,44832,cap-wifi5,-53,137600000,229400000,2800,2960,01:04:26,00:00:00
|
||||
1788526617,14:56:57,14:56:57,6,127712,21960,cap-wifi5,-53,137600000,229400000,2800,2960,01:04:28,00:00:00
|
||||
1788526619,14:56:59,14:56:59,13,157888,29816,cap-wifi5,-50,137600000,229400000,2800,2960,01:04:30,00:00:00
|
||||
1788526621,14:57:01,14:57:01,7,322208,124400,cap-wifi5,-51,137600000,229400000,3248,3328,01:04:32,00:00:00
|
||||
1788526623,14:57:03,14:57:03,13,451416,4332552,cap-wifi5,-51,137600000,229400000,3248,3328,01:04:34,00:00:00
|
||||
1788526625,14:57:05,14:57:05,10,398720,136640,cap-wifi5,-51,137600000,229400000,2800,2960,01:04:36,00:00:00
|
||||
1788526627,14:57:07,14:57:07,12,947800,446984,cap-wifi5,-51,137600000,229400000,2800,2960,01:04:38,00:00:00
|
||||
1788526629,14:57:09,14:57:09,20,7610296,3321592,cap-wifi5,-51,137600000,229400000,2800,2960,01:04:40,00:00:00
|
||||
1788526631,14:57:11,14:57:11,8,2720136,2091232,cap-wifi5,-52,137600000,229400000,3360,3552,01:04:42,00:00:00
|
||||
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi5,-52,137600000,229400000,3360,3552,01:04:44,00:00:00
|
||||
1788526636,14:57:16,14:57:15,7,108584,42016,cap-wifi5,-52,137600000,229400000,3360,3552,01:04:46,00:00:00
|
||||
1788526637,14:57:17,14:57:17,4,1478952,581848,cap-wifi5,-53,137600000,258100000,2800,2960,01:04:48,00:00:00
|
||||
1788526639,14:57:19,14:57:19,14,229272,54576,cap-wifi5,-53,137600000,229400000,4184,4968,01:04:50,00:00:00
|
||||
1788526641,14:57:21,14:57:21,6,100688,29040,cap-wifi5,-53,137600000,229400000,4184,4968,01:04:52,00:00:00
|
||||
1788526644,14:57:24,14:57:23,14,472232,195392,cap-wifi5,-61,137600000,229400000,2800,2960,01:04:54,00:00:00
|
||||
1788526645,14:57:25,14:57:25,19,229864,36304,cap-wifi5,-59,172100000,229400000,2800,2960,01:04:56,00:00:00
|
||||
1788526647,14:57:27,14:57:28,9,132384,26968,cap-wifi5,-59,172100000,229400000,2800,2960,01:04:58,00:00:00
|
||||
1788526649,14:57:29,14:57:30,18,196672,48240,cap-wifi5,-60,172100000,229400000,2800,2368,01:05:00,00:00:00
|
||||
1788526652,14:57:32,14:57:32,15,237176,31328,cap-wifi5,-60,172100000,229400000,3360,3552,01:05:02,00:00:00
|
||||
1788526654,14:57:34,14:57:34,9,147328,27456,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:04,00:00:00
|
||||
1788526656,14:57:36,14:57:36,11,122784,22816,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:07,00:00:00
|
||||
1788526658,14:57:38,14:57:38,9,122248,26192,cap-wifi5,-59,129000000,258100000,3856,2960,01:05:09,00:00:00
|
||||
1788526660,14:57:40,14:57:40,14,167632,49032,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:11,00:00:00
|
||||
1788526662,14:57:42,14:57:42,11,89248,17856,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:13,00:00:00
|
||||
1788526664,14:57:44,14:57:44,7,125232,33536,cap-wifi5,-57,114700000,206500000,3360,2960,01:05:15,00:00:00
|
||||
1788526666,14:57:46,14:57:46,8,1056872,260048,cap-wifi5,-57,114700000,206500000,2800,2960,01:05:17,00:00:00
|
||||
1788526668,14:57:48,14:57:48,11,172776,252208,cap-wifi5,-57,114700000,206500000,2800,2960,01:05:19,00:00:00
|
||||
1788526670,14:57:50,14:57:50,14,116656,22744,cap-wifi5,-57,154900000,172100000,3360,3552,01:05:21,00:00:00
|
||||
1788526672,14:57:52,14:57:52,8,234376,122480,cap-wifi5,-58,154900000,206500000,2800,2960,01:05:23,00:00:00
|
||||
1788526674,14:57:54,14:57:54,14,101992,21720,cap-wifi5,-58,154900000,206500000,2800,2960,01:05:25,00:00:00
|
||||
1788526676,14:57:56,14:57:56,9,152504,61272,cap-wifi5,-58,154900000,229400000,2800,2960,01:05:27,00:00:00
|
||||
1788526678,14:57:58,14:57:58,15,130520,26552,cap-wifi5,-58,103200000,229400000,2800,2960,01:05:29,00:00:00
|
||||
1788526680,14:58:00,14:58:00,16,155408,24688,cap-wifi5,-58,103200000,229400000,2800,2960,01:05:31,00:00:00
|
||||
1788526682,14:58:02,14:58:02,10,244456,41424,cap-wifi5,-58,103200000,206500000,3248,3328,01:05:33,00:00:00
|
||||
1788526684,14:58:04,14:58:04,8,183848,56872,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:35,00:00:00
|
||||
1788526686,14:58:06,14:58:06,9,305320,47576,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:37,00:00:00
|
||||
1788526688,14:58:08,14:58:08,14,331408,59856,cap-wifi5,-59,103200000,229400000,2800,2960,01:05:39,00:00:00
|
||||
1788526690,14:58:10,14:58:10,17,322448,65576,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:41,00:00:00
|
||||
1788526692,14:58:12,RECONNECT
|
||||
|
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-s22.csv (Takt 2s, Client 2A:0D:B0:5D:AD:A7)
|
||||
2397
docs/messdaten/tp25-runde-dauerping/archiv-150553/walk-ping-ipad.csv
Normal file
2397
docs/messdaten/tp25-runde-dauerping/archiv-150553/walk-ping-ipad.csv
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2398
docs/messdaten/tp25-runde-dauerping/archiv-150553/walk-ping-s22.csv
Normal file
2398
docs/messdaten/tp25-runde-dauerping/archiv-150553/walk-ping-s22.csv
Normal file
File diff suppressed because it is too large
Load Diff
4
docs/messdaten/tp25-runde-dauerping/geraete.txt
Normal file
4
docs/messdaten/tp25-runde-dauerping/geraete.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
iphone|10.40.10.196|F2:62:4C:E1:AF:09
|
||||
s22|10.40.10.179|2A:0D:B0:5D:AD:A7
|
||||
ipad|10.40.10.180|CA:B8:D4:3F:8A:81
|
||||
macbook|10.40.10.82|56:71:6C:22:E6:A9
|
||||
0
docs/messdaten/tp25-runde-dauerping/konsole.log
Normal file
0
docs/messdaten/tp25-runde-dauerping/konsole.log
Normal file
6
docs/messdaten/tp25-runde-dauerping/markers.csv
Normal file
6
docs/messdaten/tp25-runde-dauerping/markers.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
ts_epoch,ts_local,marker
|
||||
1788527256,15:07:36,PINM=off
|
||||
1788527283,15:08:03,PINM=off
|
||||
1788527311,15:08:31,PINM=off
|
||||
1788527320,15:08:40,PINM=off
|
||||
1788527414,15:10:14,STOP
|
||||
|
1
docs/messdaten/tp25-runde-dauerping/phase.json
Normal file
1
docs/messdaten/tp25-runde-dauerping/phase.json
Normal file
@@ -0,0 +1 @@
|
||||
{"mode": "langzeit", "phase": "GEHWEG", "title": "Roaming-Messung l\u00e4uft", "instruction": "Aufzeichnung gestoppt.", "step": 0, "steps": 0, "ends": 0}
|
||||
131
docs/messdaten/tp25-runde-dauerping/sampler-ipad.csv
Normal file
131
docs/messdaten/tp25-runde-dauerping/sampler-ipad.csv
Normal file
@@ -0,0 +1,131 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788527155,15:05:55,15:05:55,26,110192,66624,cap-wifi3,-58,6000000,216700000,0,0,00:07:03,00:00:00
|
||||
1788527157,15:05:57,15:05:57,10,248200,181784,cap-wifi3,-58,6000000,216700000,0,0,00:07:05,00:00:00
|
||||
1788527159,15:05:59,15:05:59,27,895392,176224,cap-wifi3,-54,309700000,455800000,100936,106200,00:07:07,00:00:00
|
||||
1788527161,15:06:01,15:06:01,5,271768,3546664,cap-wifi3,-55,309700000,309700000,4800,18208,00:07:09,00:00:00
|
||||
1788527163,15:06:03,15:06:03,7,212384,57592,cap-wifi3,-55,309700000,309700000,4800,18208,00:07:11,00:00:00
|
||||
1788527165,15:06:05,15:06:05,6,119880,34152,cap-wifi3,-52,309700000,455800000,62952,10824,00:07:13,00:00:00
|
||||
1788527167,15:06:07,15:06:07,6,285512,62760,cap-wifi3,-48,309700000,412900000,2800,2960,00:07:15,00:00:00
|
||||
1788527169,15:06:09,15:06:09,18,135200,33432,cap-wifi3,-48,309700000,412900000,2800,2960,00:07:17,00:00:00
|
||||
1788527171,15:06:11,15:06:11,2,80168,35552,cap-wifi3,-50,309700000,433300000,2800,3360,00:07:19,00:00:00
|
||||
1788527173,15:06:13,15:06:13,6,263824,45616,cap-wifi3,-49,309700000,455800000,2800,2960,00:07:21,00:00:00
|
||||
1788527175,15:06:15,15:06:15,4,139448,79056,cap-wifi3,-49,309700000,455800000,2800,2960,00:07:23,00:00:00
|
||||
1788527177,15:06:17,15:06:17,7,125944,34792,cap-wifi3,-51,309700000,487500000,2800,2960,00:07:25,00:00:00
|
||||
1788527179,15:06:19,15:06:19,21,228896,34848,cap-wifi3,-51,309700000,516200000,3360,3552,00:07:27,00:00:00
|
||||
1788527181,15:06:21,15:06:21,6,91344,100616,cap-wifi3,-51,309700000,516200000,3360,3552,00:07:29,00:00:00
|
||||
1788527183,15:06:23,15:06:23,8,1161368,460544,cap-wifi3,-52,309700000,541700000,2800,3520,00:07:31,00:00:00
|
||||
1788527185,15:06:25,15:06:25,9,669424,189984,cap-wifi3,-51,309700000,433300000,2800,2960,00:07:33,00:00:00
|
||||
1788527187,15:06:27,15:06:27,8,220472,72928,cap-wifi3,-51,309700000,433300000,2800,2960,00:07:35,00:00:00
|
||||
1788527189,15:06:29,15:06:29,19,85696,19672,cap-wifi3,-50,309700000,455800000,11872,3328,00:07:37,00:00:00
|
||||
1788527191,15:06:31,15:06:31,7,88056,17368,cap-wifi3,-52,309700000,516200000,3360,3552,00:07:39,00:00:00
|
||||
1788527193,15:06:33,15:06:33,7,78232,15688,cap-wifi3,-52,309700000,516200000,3360,3552,00:07:41,00:00:00
|
||||
1788527195,15:06:35,15:06:35,7,77824,19488,cap-wifi3,-50,309700000,433300000,2800,2960,00:07:43,00:00:00
|
||||
1788527197,15:06:37,15:06:37,11,91648,29960,cap-wifi3,-56,309700000,455800000,2800,2960,00:07:45,00:00:00
|
||||
1788527199,15:06:39,15:06:39,19,479584,403096,cap-wifi3,-54,309700000,325000000,2800,2960,00:07:47,00:00:00
|
||||
1788527201,15:06:41,15:06:41,6,83504,18032,cap-wifi3,-54,309700000,325000000,2800,2960,00:07:49,00:00:00
|
||||
1788527203,15:06:43,15:06:43,8,94312,27480,cap-wifi3,-53,309700000,344100000,3248,2960,00:07:51,00:00:00
|
||||
1788527205,15:06:45,15:06:45,7,139816,113728,cap-wifi3,-52,309700000,390000000,2800,2960,00:07:53,00:00:00
|
||||
1788527207,15:06:47,15:06:47,8,77512,23304,cap-wifi3,-52,309700000,390000000,2800,2960,00:07:55,00:00:00
|
||||
1788527209,15:06:49,15:06:49,22,135424,86176,cap-wifi3,-53,309700000,412900000,2800,3360,00:07:57,00:00:00
|
||||
1788527211,15:06:51,15:06:52,6,80072,20128,cap-wifi3,-52,309700000,433300000,2800,2960,00:07:59,00:00:00
|
||||
1788527213,15:06:53,15:06:54,7,81544,23592,cap-wifi3,-52,309700000,433300000,2800,2960,00:08:01,00:00:00
|
||||
1788527216,15:06:56,15:06:56,8,118248,77704,cap-wifi3,-52,309700000,455800000,3808,3552,00:08:03,00:00:00
|
||||
1788527218,15:06:58,15:06:58,6,115296,40584,cap-wifi3,-54,309700000,487500000,2800,2960,00:08:05,00:00:00
|
||||
1788527220,15:07:00,15:07:00,36,72144,17920,cap-wifi3,-54,309700000,487500000,2800,2960,00:08:07,00:00:00
|
||||
1788527222,15:07:02,15:07:02,6,87272,19464,cap-wifi3,-53,309700000,516200000,3808,3920,00:08:09,00:00:00
|
||||
1788527224,15:07:04,15:07:04,7,341584,177744,cap-wifi3,-54,309700000,487500000,3488,2960,00:08:11,00:00:00
|
||||
1788527226,15:07:06,15:07:06,5,96008,29072,cap-wifi3,-54,309700000,487500000,3488,2960,00:08:14,00:00:00
|
||||
1788527228,15:07:08,15:07:08,9,88184,20760,cap-wifi3,-54,309700000,516200000,2800,2960,00:08:16,00:00:00
|
||||
1788527230,15:07:10,15:07:10,19,245616,37632,cap-wifi3,-54,309700000,541700000,3424,2960,00:08:18,00:00:00
|
||||
1788527232,15:07:12,15:07:12,7,136904,41680,cap-wifi3,-54,309700000,541700000,3424,2960,00:08:20,00:00:00
|
||||
1788527234,15:07:14,15:07:14,5,176432,193240,cap-wifi3,-54,309700000,573500000,3360,2960,00:08:22,00:00:00
|
||||
1788527236,15:07:16,15:07:16,5,668616,412672,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:24,00:00:00
|
||||
1788527238,15:07:18,15:07:18,12,10040200,401976,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:26,00:00:00
|
||||
1788527240,15:07:20,15:07:20,21,6694840,181608,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:28,00:00:00
|
||||
1788527242,15:07:22,15:07:22,8,269904,95904,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:30,00:00:00
|
||||
1788527244,15:07:24,15:07:24,10,97040,38768,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:32,00:00:00
|
||||
1788527246,15:07:26,15:07:26,8,265536,57040,cap-wifi3,-51,309700000,573500000,2800,2960,00:08:34,00:00:00
|
||||
1788527248,15:07:28,15:07:28,8,79496,17712,cap-wifi3,-52,309700000,573500000,3360,8208,00:08:36,00:00:00
|
||||
1788527250,15:07:30,15:07:30,5,82824,26656,cap-wifi3,-52,309700000,573500000,3360,8208,00:08:38,00:00:00
|
||||
1788527252,15:07:32,15:07:32,8,79440,24984,cap-wifi3,-52,309700000,573500000,3360,7808,00:08:40,00:00:00
|
||||
1788527254,15:07:34,15:07:34,7,84240,17432,cap-wifi3,-52,309700000,573500000,5248,2960,00:08:42,00:00:00
|
||||
1788527256,15:07:36,15:07:36,15,74928,18888,cap-wifi3,-52,309700000,573500000,5248,2960,00:08:44,00:00:00
|
||||
1788527258,15:07:38,15:07:38,6,79856,17376,cap-wifi3,-51,309700000,573500000,3328,3520,00:08:46,00:00:00
|
||||
1788527260,15:07:40,15:07:40,5,91680,31720,cap-wifi3,-52,275300000,573500000,2800,2960,00:08:48,00:00:00
|
||||
1788527262,15:07:42,15:07:42,6,82760,21192,cap-wifi3,-52,275300000,573500000,2800,2960,00:08:50,00:00:00
|
||||
1788527264,15:07:44,15:07:44,7,91960,31680,cap-wifi3,-51,275300000,573500000,2800,2960,00:08:52,00:00:00
|
||||
1788527266,15:07:46,15:07:46,6,986832,256184,cap-wifi3,-51,275300000,573500000,3920,4144,00:08:54,00:00:00
|
||||
1788527268,15:07:48,15:07:48,7,204344,305984,cap-wifi3,-51,275300000,573500000,3920,4144,00:08:56,00:00:00
|
||||
1788527270,15:07:50,15:07:50,9,90376,25984,cap-wifi3,-52,258100000,573500000,2240,2368,00:08:58,00:00:00
|
||||
1788527272,15:07:52,15:07:52,5,106024,28632,cap-wifi3,-52,258100000,286800000,2800,2960,00:09:00,00:00:00
|
||||
1788527274,15:07:54,15:07:54,8,90816,27368,cap-wifi3,-52,258100000,286800000,2800,2960,00:09:02,00:00:00
|
||||
1788527276,15:07:56,15:07:56,9,80656,22520,cap-wifi3,-52,258100000,573500000,2800,2960,00:09:04,00:00:00
|
||||
1788527278,15:07:58,15:07:58,8,74792,15952,cap-wifi3,-54,258100000,412900000,2800,2960,00:09:06,00:00:00
|
||||
1788527280,15:08:00,15:08:00,9,97280,32008,cap-wifi3,-54,258100000,412900000,2800,2960,00:09:08,00:00:00
|
||||
1788527282,15:08:02,15:08:02,22,405584,131400,cap-wifi3,-55,258100000,412900000,2800,2960,00:09:10,00:00:00
|
||||
1788527284,15:08:04,15:08:04,15,99616,29344,cap-wifi3,-53,258100000,433300000,2800,2960,00:09:12,00:00:00
|
||||
1788527286,15:08:06,15:08:06,3,116040,34784,cap-wifi3,-53,258100000,433300000,2800,2960,00:09:14,00:00:00
|
||||
1788527288,15:08:08,15:08:08,6,263752,46256,cap-wifi3,-54,258100000,455800000,2800,3360,00:09:16,00:00:00
|
||||
1788527290,15:08:10,15:08:10,5,154688,74104,cap-wifi3,-54,258100000,487500000,2800,2960,00:09:18,00:00:00
|
||||
1788527292,15:08:12,15:08:13,4,437800,144600,cap-wifi3,-54,258100000,487500000,2800,2960,00:09:20,00:00:00
|
||||
1788527294,15:08:14,15:08:15,5,273784,69248,cap-wifi3,-56,258100000,390000000,3808,3552,00:09:22,00:00:00
|
||||
1788527297,15:08:17,15:08:17,4,110840,33232,cap-wifi3,-56,258100000,433300000,2800,2960,00:09:24,00:00:00
|
||||
1788527299,15:08:19,15:08:19,5,80584,34112,cap-wifi3,-55,258100000,455800000,3360,3552,00:09:26,00:00:00
|
||||
1788527301,15:08:21,15:08:21,5,89992,25208,cap-wifi3,-55,258100000,455800000,3360,3552,00:09:28,00:00:00
|
||||
1788527303,15:08:23,15:08:23,5,258520,122376,cap-wifi3,-56,258100000,433300000,2800,2960,00:09:30,00:00:00
|
||||
1788527305,15:08:25,15:08:25,8,484544,159104,cap-wifi3,-55,258100000,455800000,2800,2960,00:09:33,00:00:00
|
||||
1788527307,15:08:27,15:08:27,5,85832,21400,cap-wifi3,-55,258100000,455800000,2800,2960,00:09:35,00:00:00
|
||||
1788527309,15:08:29,15:08:29,7,86968,23984,cap-wifi3,-56,258100000,433300000,2800,2960,00:09:37,00:00:00
|
||||
1788527311,15:08:31,15:08:31,4,92848,27216,cap-wifi3,-57,258100000,455800000,2800,2960,00:09:39,00:00:00
|
||||
1788527313,15:08:33,15:08:33,13,88112,30272,cap-wifi3,-57,258100000,455800000,2800,2960,00:09:41,00:00:00
|
||||
1788527315,15:08:35,15:08:35,6,97568,38688,cap-wifi3,-57,258100000,433300000,2800,2960,00:09:43,00:00:00
|
||||
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-58,258100000,455800000,3360,3552,00:09:45,00:00:00
|
||||
1788527319,15:08:39,15:08:39,22,95672,27872,cap-wifi3,-58,258100000,455800000,3360,3552,00:09:47,00:00:00
|
||||
1788527321,15:08:41,15:08:41,20,81008,14064,cap-wifi3,-58,258100000,433300000,2800,2960,00:09:49,00:00:00
|
||||
1788527323,15:08:43,15:08:43,9,79480,19824,cap-wifi3,-59,258100000,325000000,3328,2960,00:09:51,00:00:00
|
||||
1788527325,15:08:45,15:08:45,11,83080,28888,cap-wifi3,-59,258100000,325000000,3328,2960,00:09:53,00:00:00
|
||||
1788527327,15:08:47,15:08:47,7,77224,19568,cap-wifi3,-59,258100000,390000000,3360,3952,00:09:55,00:00:00
|
||||
1788527329,15:08:49,15:08:49,20,87976,23544,cap-wifi3,-58,258100000,412900000,2800,2960,00:09:57,00:00:00
|
||||
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-58,258100000,412900000,2800,2960,00:09:59,00:00:00
|
||||
1788527333,15:08:53,15:08:53,4,78784,16504,cap-wifi3,-58,258100000,390000000,3808,3552,00:10:01,00:00:00
|
||||
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-52,6000000,412900000,3360,3552,00:10:03,00:00:00
|
||||
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-52,6000000,412900000,3360,3552,00:10:05,00:00:00
|
||||
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-52,258100000,433300000,2800,3360,00:10:07,00:00:00
|
||||
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-53,258100000,455800000,2800,2960,00:10:09,00:00:00
|
||||
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-53,258100000,455800000,2800,2960,00:10:11,00:00:00
|
||||
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-56,258100000,433300000,2800,2960,00:10:13,00:00:00
|
||||
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-55,258100000,390000000,2800,2960,00:10:15,00:00:00
|
||||
1788527349,15:09:09,15:09:09,19,213416,92736,cap-wifi3,-55,258100000,390000000,2800,2960,00:10:17,00:00:00
|
||||
1788527351,15:09:11,15:09:11,6,319104,63216,cap-wifi3,-52,6000000,309700000,2800,2960,00:10:19,00:00:00
|
||||
1788527353,15:09:13,15:09:13,8,153896,48144,cap-wifi3,-54,258100000,344100000,3360,3552,00:10:21,00:00:00
|
||||
1788527355,15:09:15,15:09:15,5,190952,58360,cap-wifi3,-54,258100000,344100000,3360,3552,00:10:23,00:00:00
|
||||
1788527357,15:09:17,15:09:17,7,232928,149512,cap-wifi3,-55,258100000,390000000,4080,6912,00:10:25,00:00:00
|
||||
1788527359,15:09:19,15:09:20,19,108000,26560,cap-wifi3,-56,258100000,412900000,3360,3552,00:10:27,00:00:00
|
||||
1788527361,15:09:21,15:09:22,10,2754208,213840,cap-wifi3,-56,258100000,412900000,3360,3552,00:10:29,00:00:00
|
||||
1788527364,15:09:24,15:09:24,7,314040,73608,cap-wifi3,-55,258100000,216700000,15040,7600,00:10:31,00:00:00
|
||||
1788527366,15:09:26,15:09:26,5,485488,100744,cap-wifi3,-54,258100000,229400000,3304,6992,00:10:33,00:00:00
|
||||
1788527368,15:09:28,15:09:28,6,123816,28072,cap-wifi3,-54,258100000,229400000,3304,6992,00:10:35,00:00:00
|
||||
1788527370,15:09:30,15:09:30,19,124944,35616,cap-wifi3,-56,258100000,433300000,2800,2960,00:10:37,00:00:00
|
||||
1788527372,15:09:32,15:09:32,5,171352,44496,cap-wifi3,-54,258100000,433300000,4928,0,00:10:39,00:00:00
|
||||
1788527374,15:09:34,15:09:34,6,166240,43784,cap-wifi3,-54,6000000,433300000,2800,0,00:10:42,00:00:00
|
||||
1788527376,15:09:36,15:09:36,6,150760,49464,cap-wifi3,-54,6000000,433300000,2800,0,00:10:44,00:00:00
|
||||
1788527378,15:09:38,15:09:38,10,185768,47120,cap-wifi3,-55,258100000,433300000,2800,6496,00:10:46,00:00:00
|
||||
1788527380,15:09:40,15:09:40,18,190032,49512,cap-wifi3,-54,258100000,433300000,2240,0,00:10:48,00:00:00
|
||||
1788527382,15:09:42,15:09:42,8,97808,22304,cap-wifi3,-54,258100000,433300000,2240,0,00:10:50,00:00:00
|
||||
1788527384,15:09:44,15:09:44,8,148400,53672,cap-wifi3,-54,6000000,433300000,13464,368,00:10:52,00:00:00
|
||||
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-54,258100000,455800000,2800,2960,00:10:54,00:00:00
|
||||
1788527388,15:09:48,15:09:48,4,76456,19280,cap-wifi3,-54,258100000,455800000,2800,2960,00:10:56,00:00:00
|
||||
1788527390,15:09:50,15:09:50,9,74488,14496,cap-wifi3,-54,258100000,390000000,2928,0,00:10:58,00:00:00
|
||||
1788527392,15:09:52,15:09:52,9,81688,114120,cap-wifi3,-54,258100000,390000000,2240,0,00:11:00,00:00:00
|
||||
1788527394,15:09:54,15:09:54,11,139472,94312,cap-wifi3,-54,258100000,390000000,2240,0,00:11:02,00:00:00
|
||||
1788527396,15:09:56,15:09:56,8,99376,34800,cap-wifi3,-54,258100000,390000000,2240,0,00:11:04,00:00:00
|
||||
1788527398,15:09:58,15:09:58,7,95624,20936,cap-wifi3,-54,258100000,390000000,2800,0,00:11:06,00:00:00
|
||||
1788527400,15:10:00,15:10:00,11,75688,17080,cap-wifi3,-54,258100000,390000000,2800,0,00:11:08,00:00:00
|
||||
1788527402,15:10:02,15:10:02,8,194448,59984,cap-wifi3,-54,258100000,390000000,2240,0,00:11:10,00:00:00
|
||||
1788527404,15:10:04,15:10:04,5,87848,23392,cap-wifi3,-54,258100000,390000000,5040,0,00:11:12,00:00:00
|
||||
1788527406,15:10:06,15:10:06,4,102440,31824,cap-wifi3,-54,258100000,390000000,5040,0,00:11:14,00:00:00
|
||||
1788527408,15:10:08,15:10:08,7,140352,49312,cap-wifi3,-54,258100000,390000000,2800,0,00:11:16,00:00:00
|
||||
1788527410,15:10:10,15:10:10,20,81216,18128,cap-wifi3,-53,258100000,390000000,2688,0,00:11:18,00:00:00
|
||||
1788527412,15:10:12,15:10:12,8,223088,23248,cap-wifi3,-53,258100000,390000000,2688,0,00:11:20,00:00:00
|
||||
1788527414,15:10:14,15:10:14,7,139784,51840,cap-wifi3,-54,258100000,390000000,2240,0,00:11:22,00:00:00
|
||||
1788527415,15:10:15,RECONNECT
|
||||
|
1
docs/messdaten/tp25-runde-dauerping/sampler-ipad.out
Normal file
1
docs/messdaten/tp25-runde-dauerping/sampler-ipad.out
Normal file
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-ipad.csv (Takt 2s, Client CA:B8:D4:3F:8A:81)
|
||||
@@ -0,0 +1,2 @@
|
||||
14:58:12 Verbindung weg -- neuer Versuch in 2 s
|
||||
15:10:15 Verbindung weg -- neuer Versuch in 2 s
|
||||
130
docs/messdaten/tp25-runde-dauerping/sampler-iphone.csv
Normal file
130
docs/messdaten/tp25-runde-dauerping/sampler-iphone.csv
Normal file
@@ -0,0 +1,130 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788527155,15:05:55,RECONNECT
|
||||
1788527159,15:05:59,15:05:59,26,895392,176224,cap-wifi3,-63,154900000,309700000,15624,7104,00:13:12,00:00:00
|
||||
1788527161,15:06:01,15:06:01,12,271768,3546664,cap-wifi3,-61,154900000,325000000,4576,3552,00:13:14,00:00:00
|
||||
1788527163,15:06:03,15:06:03,11,212384,57592,cap-wifi3,-61,154900000,325000000,4576,3552,00:13:16,00:00:00
|
||||
1788527165,15:06:05,15:06:05,6,119880,34152,cap-wifi3,-59,154900000,325000000,2240,0,00:13:18,00:00:00
|
||||
1788527167,15:06:07,15:06:07,6,285512,62760,cap-wifi3,-58,154900000,325000000,3360,0,00:13:20,00:00:00
|
||||
1788527169,15:06:09,15:06:09,18,135200,33432,cap-wifi3,-58,154900000,325000000,3360,0,00:13:22,00:00:00
|
||||
1788527171,15:06:11,15:06:11,2,80168,35552,cap-wifi3,-58,154900000,325000000,2240,0,00:13:24,00:00:00
|
||||
1788527173,15:06:13,15:06:13,6,263824,45616,cap-wifi3,-57,154900000,325000000,3360,0,00:13:26,00:00:00
|
||||
1788527175,15:06:15,15:06:15,4,139448,79056,cap-wifi3,-57,154900000,325000000,3360,0,00:13:28,00:00:00
|
||||
1788527177,15:06:17,15:06:17,7,125944,34792,cap-wifi3,-58,154900000,325000000,1680,0,00:13:30,00:00:00
|
||||
1788527179,15:06:19,15:06:19,21,228896,34848,cap-wifi3,-60,154900000,325000000,0,0,00:13:32,00:00:00
|
||||
1788527181,15:06:21,15:06:21,6,91344,100616,cap-wifi3,-60,154900000,325000000,0,0,00:13:34,00:00:00
|
||||
1788527183,15:06:23,15:06:23,8,1161368,460544,cap-wifi3,-62,154900000,325000000,4368,4592,00:13:36,00:00:00
|
||||
1788527185,15:06:25,15:06:25,9,669424,189984,cap-wifi3,-56,154900000,344100000,2800,3712,00:13:38,00:00:00
|
||||
1788527187,15:06:27,15:06:27,8,220472,72928,cap-wifi3,-56,154900000,344100000,2800,3712,00:13:40,00:00:00
|
||||
1788527189,15:06:29,15:06:29,19,85696,19672,cap-wifi3,-60,154900000,325000000,4880,10808,00:13:42,00:00:00
|
||||
1788527191,15:06:31,15:06:31,7,80008,30360,cap-wifi3,-48,154900000,309700000,4080,4992,00:13:44,00:00:00
|
||||
1788527193,15:06:33,15:06:33,7,85392,35808,cap-wifi3,-48,154900000,309700000,4080,4992,00:13:46,00:00:00
|
||||
1788527195,15:06:35,15:06:35,7,81000,33304,cap-wifi3,-52,154900000,325000000,2800,2960,00:13:48,00:00:00
|
||||
1788527197,15:06:37,15:06:37,11,80840,16392,cap-wifi3,-60,154900000,344100000,2800,2960,00:13:50,00:00:00
|
||||
1788527199,15:06:39,15:06:39,19,479584,403096,cap-wifi3,-60,154900000,344100000,2800,2960,00:13:52,00:00:00
|
||||
1788527201,15:06:41,15:06:41,6,83504,18032,cap-wifi3,-54,154900000,390000000,2800,2960,00:13:54,00:00:00
|
||||
1788527203,15:06:43,15:06:43,8,94312,27480,cap-wifi3,-52,154900000,412900000,3776,3552,00:13:56,00:00:00
|
||||
1788527205,15:06:45,15:06:45,7,139816,113728,cap-wifi3,-54,154900000,455800000,3360,3552,00:13:58,00:00:00
|
||||
1788527207,15:06:47,15:06:47,8,77512,23304,cap-wifi3,-54,154900000,455800000,3360,3552,00:14:00,00:00:00
|
||||
1788527209,15:06:49,15:06:49,22,135424,86176,cap-wifi3,-53,206500000,455800000,2800,2960,00:14:02,00:00:00
|
||||
1788527211,15:06:51,15:06:51,6,80072,20128,cap-wifi3,-53,12000000,516200000,2800,2960,00:14:04,00:00:00
|
||||
1788527213,15:06:53,15:06:53,7,81544,23592,cap-wifi3,-53,12000000,516200000,2800,2960,00:14:06,00:00:00
|
||||
1788527215,15:06:55,15:06:55,8,118248,77704,cap-wifi3,-54,206500000,573500000,3248,3552,00:14:08,00:00:00
|
||||
1788527217,15:06:57,15:06:58,6,115296,40584,cap-wifi3,-53,206500000,573500000,3360,3552,00:14:10,00:00:00
|
||||
1788527219,15:06:59,15:07:00,36,72144,17920,cap-wifi3,-53,206500000,573500000,3360,3552,00:14:12,00:00:00
|
||||
1788527221,15:07:01,15:07:02,6,87272,19464,cap-wifi3,-55,206500000,412900000,2800,2960,00:14:14,00:00:00
|
||||
1788527224,15:07:04,15:07:04,7,341584,177744,cap-wifi3,-55,206500000,455800000,2800,2960,00:14:16,00:00:00
|
||||
1788527226,15:07:06,15:07:06,5,96008,29072,cap-wifi3,-55,206500000,455800000,2800,2960,00:14:18,00:00:00
|
||||
1788527228,15:07:08,15:07:08,9,88184,20760,cap-wifi3,-54,206500000,455800000,2800,2960,00:14:21,00:00:00
|
||||
1788527230,15:07:10,15:07:10,19,245616,37632,cap-wifi3,-55,206500000,433300000,2800,2960,00:14:23,00:00:00
|
||||
1788527232,15:07:12,15:07:12,7,136904,41680,cap-wifi3,-55,206500000,433300000,2800,2960,00:14:25,00:00:00
|
||||
1788527234,15:07:14,15:07:14,5,176432,193240,cap-wifi3,-54,206500000,455800000,2800,2960,00:14:27,00:00:00
|
||||
1788527236,15:07:16,15:07:16,5,668616,412672,cap-wifi3,-53,206500000,487500000,3360,3552,00:14:29,00:00:00
|
||||
1788527238,15:07:18,15:07:18,12,10040200,401976,cap-wifi3,-53,206500000,487500000,3360,3552,00:14:31,00:00:00
|
||||
1788527240,15:07:20,15:07:20,21,6694840,181608,cap-wifi3,-53,6000000,516200000,2800,3336,00:14:33,00:00:00
|
||||
1788527242,15:07:22,15:07:22,7,269904,95904,cap-wifi3,-53,206500000,487500000,2800,2960,00:14:35,00:00:00
|
||||
1788527244,15:07:24,15:07:24,6,97040,38768,cap-wifi3,-53,206500000,487500000,2800,2960,00:14:37,00:00:00
|
||||
1788527246,15:07:26,15:07:26,6,265536,57040,cap-wifi3,-53,206500000,516200000,3360,3552,00:14:39,00:00:00
|
||||
1788527248,15:07:28,15:07:28,8,79496,17712,cap-wifi3,-52,206500000,487500000,2800,2960,00:14:41,00:00:00
|
||||
1788527250,15:07:30,15:07:30,20,82824,26656,cap-wifi3,-52,206500000,487500000,2800,2960,00:14:43,00:00:00
|
||||
1788527252,15:07:32,15:07:32,8,79440,24984,cap-wifi3,-53,206500000,516200000,2800,2960,00:14:45,00:00:00
|
||||
1788527254,15:07:34,15:07:34,7,84240,17432,cap-wifi3,-51,206500000,541700000,4560,3552,00:14:47,00:00:00
|
||||
1788527256,15:07:36,15:07:36,15,74928,18888,cap-wifi3,-51,206500000,541700000,4560,3552,00:14:49,00:00:00
|
||||
1788527258,15:07:38,15:07:38,6,79856,17376,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:51,00:00:00
|
||||
1788527260,15:07:40,15:07:40,5,91680,31720,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:53,00:00:00
|
||||
1788527262,15:07:42,15:07:42,6,82760,21192,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:55,00:00:00
|
||||
1788527264,15:07:44,15:07:44,7,91960,31680,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:57,00:00:00
|
||||
1788527266,15:07:46,15:07:46,6,986832,256184,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:59,00:00:00
|
||||
1788527268,15:07:48,15:07:48,7,204344,305984,cap-wifi3,-51,206500000,573500000,2800,2960,00:15:01,00:00:00
|
||||
1788527270,15:07:50,15:07:50,9,90376,25984,cap-wifi3,-51,206500000,516200000,3248,3328,00:15:03,00:00:00
|
||||
1788527272,15:07:52,15:07:52,5,106024,28632,cap-wifi3,-50,12000000,516200000,3808,3920,00:15:05,00:00:00
|
||||
1788527274,15:07:54,15:07:54,8,86752,24568,cap-wifi3,-50,12000000,516200000,3808,3920,00:15:07,00:00:00
|
||||
1788527276,15:07:56,15:07:56,9,68568,17040,cap-wifi3,-51,206500000,541700000,2800,2960,00:15:09,00:00:00
|
||||
1788527278,15:07:58,15:07:58,8,104792,53200,cap-wifi3,-51,206500000,390000000,3360,3552,00:15:11,00:00:00
|
||||
1788527280,15:08:00,15:08:00,9,304368,102592,cap-wifi3,-51,206500000,390000000,3360,3552,00:15:13,00:00:00
|
||||
1788527282,15:08:02,15:08:02,22,74432,14824,cap-wifi3,-50,24000000,412900000,2800,2960,00:15:15,00:00:00
|
||||
1788527284,15:08:04,15:08:04,15,99616,29344,cap-wifi3,-51,154900000,433300000,3360,3552,00:15:17,00:00:00
|
||||
1788527286,15:08:06,15:08:06,3,116040,34784,cap-wifi3,-51,154900000,433300000,3360,3552,00:15:19,00:00:00
|
||||
1788527288,15:08:08,15:08:08,6,263752,46256,cap-wifi3,-50,24000000,455800000,2800,2960,00:15:21,00:00:00
|
||||
1788527290,15:08:10,15:08:10,5,154688,74104,cap-wifi3,-51,154900000,487500000,2800,2960,00:15:23,00:00:00
|
||||
1788527292,15:08:12,15:08:12,4,437800,144600,cap-wifi3,-51,154900000,487500000,2800,2960,00:15:25,00:00:00
|
||||
1788527294,15:08:14,15:08:14,5,273784,69248,cap-wifi3,-50,154900000,516200000,3248,3552,00:15:27,00:00:00
|
||||
1788527296,15:08:16,15:08:16,4,110840,33232,cap-wifi3,-50,154900000,541700000,2800,2960,00:15:29,00:00:00
|
||||
1788527298,15:08:18,15:08:18,5,80584,34112,cap-wifi3,-50,154900000,541700000,2800,2960,00:15:31,00:00:00
|
||||
1788527300,15:08:20,15:08:20,5,89992,25208,cap-wifi3,-51,206500000,573500000,3360,3928,00:15:33,00:00:00
|
||||
1788527302,15:08:22,15:08:23,5,258520,122376,cap-wifi3,-50,206500000,573500000,2800,2960,00:15:35,00:00:00
|
||||
1788527304,15:08:24,15:08:25,8,484544,159104,cap-wifi3,-50,206500000,573500000,2800,2960,00:15:37,00:00:00
|
||||
1788527306,15:08:26,15:08:27,5,85832,21400,cap-wifi3,-52,206500000,573500000,6336,6536,00:15:39,00:00:00
|
||||
1788527309,15:08:29,15:08:29,7,86968,23984,cap-wifi3,-51,206500000,573500000,4384,5704,00:15:41,00:00:00
|
||||
1788527311,15:08:31,15:08:31,4,92848,27216,cap-wifi3,-50,24000000,573500000,3360,2960,00:15:44,00:00:00
|
||||
1788527313,15:08:33,15:08:33,13,88112,30272,cap-wifi3,-50,24000000,573500000,3360,2960,00:15:46,00:00:00
|
||||
1788527315,15:08:35,15:08:35,6,97568,38688,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:48,00:00:00
|
||||
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:50,00:00:00
|
||||
1788527319,15:08:39,15:08:39,7,95672,27872,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:52,00:00:00
|
||||
1788527321,15:08:41,15:08:41,8,81008,14064,cap-wifi3,-52,172100000,573500000,5648,5744,00:15:54,00:00:00
|
||||
1788527323,15:08:43,15:08:43,8,79480,19824,cap-wifi3,-51,172100000,573500000,3360,3552,00:15:56,00:00:00
|
||||
1788527325,15:08:45,15:08:45,6,83080,28888,cap-wifi3,-51,172100000,573500000,3360,3552,00:15:58,00:00:00
|
||||
1788527327,15:08:47,15:08:47,9,77224,19568,cap-wifi3,-52,172100000,573500000,2800,2960,00:16:00,00:00:00
|
||||
1788527329,15:08:49,15:08:49,7,87976,23544,cap-wifi3,-53,172100000,573500000,2800,2960,00:16:02,00:00:00
|
||||
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-53,172100000,573500000,2800,2960,00:16:04,00:00:00
|
||||
1788527333,15:08:53,15:08:53,4,78784,16504,cap-wifi3,-56,172100000,455800000,4416,4840,00:16:06,00:00:00
|
||||
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-56,154900000,344100000,3408,3656,00:16:08,00:00:00
|
||||
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-56,154900000,344100000,3408,3656,00:16:10,00:00:00
|
||||
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-53,154900000,344100000,3936,4496,00:16:12,00:00:00
|
||||
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-53,154900000,325000000,3408,3656,00:16:14,00:00:00
|
||||
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-53,154900000,325000000,3408,3656,00:16:16,00:00:00
|
||||
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-51,154900000,344100000,3408,2960,00:16:18,00:00:00
|
||||
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-58,154900000,325000000,4896,5048,00:16:20,00:00:00
|
||||
1788527349,15:09:09,15:09:09,19,213416,92736,cap-wifi3,-58,154900000,325000000,4896,5048,00:16:22,00:00:00
|
||||
1788527351,15:09:11,15:09:11,6,319104,63216,cap-wifi3,-50,206500000,344100000,3408,3656,00:16:24,00:00:00
|
||||
1788527353,15:09:13,15:09:13,8,153896,48144,cap-wifi3,-46,206500000,412900000,3968,4248,00:16:26,00:00:00
|
||||
1788527355,15:09:15,15:09:15,5,190952,58360,cap-wifi3,-46,206500000,412900000,3968,4248,00:16:28,00:00:00
|
||||
1788527357,15:09:17,15:09:17,7,232928,149512,cap-wifi3,-59,206500000,433300000,3408,3656,00:16:30,00:00:00
|
||||
1788527359,15:09:19,15:09:19,19,108000,26560,cap-wifi3,-60,206500000,344100000,3856,4032,00:16:32,00:00:00
|
||||
1788527361,15:09:21,15:09:21,10,2754208,213840,cap-wifi3,-60,206500000,344100000,3856,4032,00:16:34,00:00:00
|
||||
1788527363,15:09:23,15:09:24,7,314040,73608,cap-wifi3,-60,206500000,325000000,5488,11504,00:16:36,00:00:00
|
||||
1788527365,15:09:25,15:09:26,5,485488,100744,cap-wifi3,-60,206500000,344100000,4736,5096,00:16:38,00:00:00
|
||||
1788527367,15:09:28,15:09:28,6,123816,28072,cap-wifi3,-60,206500000,344100000,4736,5096,00:16:40,00:00:00
|
||||
1788527370,15:09:30,15:09:30,19,124944,35616,cap-wifi3,-61,154900000,292500000,2800,0,00:16:42,00:00:00
|
||||
1788527372,15:09:32,15:09:32,5,171352,44496,cap-wifi3,-60,137600000,325000000,3136,368,00:16:44,00:00:00
|
||||
1788527374,15:09:34,15:09:34,6,166240,43784,cap-wifi3,-60,137600000,325000000,3136,368,00:16:47,00:00:00
|
||||
1788527376,15:09:36,15:09:36,6,150760,49464,cap-wifi3,-55,172100000,309700000,15056,42256,00:16:49,00:00:00
|
||||
1788527378,15:09:38,15:09:38,10,185768,47120,cap-wifi3,-62,172100000,325000000,3408,3656,00:16:51,00:00:00
|
||||
1788527380,15:09:40,15:09:40,18,190032,49512,cap-wifi3,-62,172100000,344100000,3408,3656,00:16:53,00:00:00
|
||||
1788527382,15:09:42,15:09:42,8,97808,22304,cap-wifi3,-62,172100000,344100000,3408,3656,00:16:55,00:00:00
|
||||
1788527384,15:09:44,15:09:44,8,148400,53672,cap-wifi3,-63,12000000,412900000,3856,10808,00:16:57,00:00:00
|
||||
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-62,172100000,412900000,2800,2960,00:16:59,00:00:00
|
||||
1788527388,15:09:48,15:09:48,4,76456,19280,cap-wifi3,-62,172100000,412900000,2800,2960,00:17:01,00:00:00
|
||||
1788527390,15:09:50,15:09:50,17,74488,14496,cap-wifi3,-64,172100000,325000000,7688,7440,00:17:03,00:00:00
|
||||
1788527392,15:09:52,15:09:52,4,81688,114120,cap-wifi3,-62,172100000,344100000,3888,4768,00:17:05,00:00:00
|
||||
1788527394,15:09:54,15:09:54,8,139472,94312,cap-wifi3,-62,172100000,344100000,3888,4768,00:17:07,00:00:00
|
||||
1788527396,15:09:56,15:09:56,4,99376,34800,cap-wifi3,-63,172100000,412900000,3328,3424,00:17:09,00:00:00
|
||||
1788527398,15:09:58,15:09:58,5,95624,20936,cap-wifi3,-62,172100000,412900000,3360,3552,00:17:11,00:00:00
|
||||
1788527400,15:10:00,15:10:00,11,75688,17080,cap-wifi3,-62,172100000,412900000,3360,3552,00:17:13,00:00:00
|
||||
1788527402,15:10:02,15:10:02,8,194448,59984,cap-wifi3,-61,172100000,390000000,2800,0,00:17:15,00:00:00
|
||||
1788527404,15:10:04,15:10:04,5,87848,23392,cap-wifi3,-60,172100000,390000000,2128,368,00:17:17,00:00:00
|
||||
1788527406,15:10:06,15:10:06,4,102440,31824,cap-wifi3,-60,172100000,390000000,2128,368,00:17:19,00:00:00
|
||||
1788527408,15:10:08,15:10:08,7,140352,49312,cap-wifi3,-61,172100000,390000000,2240,0,00:17:21,00:00:00
|
||||
1788527410,15:10:10,15:10:10,20,88352,30376,cap-wifi3,-61,137600000,390000000,3248,0,00:17:23,00:00:00
|
||||
1788527412,15:10:12,15:10:12,8,124328,46808,cap-wifi3,-61,137600000,390000000,3248,0,00:17:25,00:00:00
|
||||
1788527414,15:10:14,15:10:14,7,84784,23040,cap-wifi3,-61,137600000,390000000,2800,0,00:17:27,00:00:00
|
||||
1788527415,15:10:15,RECONNECT
|
||||
|
1
docs/messdaten/tp25-runde-dauerping/sampler-iphone.out
Normal file
1
docs/messdaten/tp25-runde-dauerping/sampler-iphone.out
Normal file
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-iphone.csv (Takt 2s, Client F2:62:4C:E1:AF:09)
|
||||
@@ -0,0 +1,9 @@
|
||||
14:58:12 Verbindung weg -- neuer Versuch in 2 s
|
||||
ssh_askpass: exec(/usr/X11R6/bin/ssh-askpass): No such file or directory
|
||||
Permission denied, please try again.
|
||||
ssh_askpass: exec(/usr/X11R6/bin/ssh-askpass): No such file or directory
|
||||
Permission denied, please try again.
|
||||
ssh_askpass: exec(/usr/X11R6/bin/ssh-askpass): No such file or directory
|
||||
admin@10.40.99.1: Permission denied (publickey,password).
|
||||
15:05:55 Verbindung weg -- neuer Versuch in 2 s
|
||||
15:10:15 Verbindung weg -- neuer Versuch in 2 s
|
||||
130
docs/messdaten/tp25-runde-dauerping/sampler-macbook.csv
Normal file
130
docs/messdaten/tp25-runde-dauerping/sampler-macbook.csv
Normal file
@@ -0,0 +1,130 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788527155,15:05:55,15:05:55,26,215104,164208,cap-wifi3,-59,344100000,455800000,1108432,1179376,00:06:21,00:00:00
|
||||
1788527157,15:05:57,15:05:57,10,230144,103104,cap-wifi3,-58,412900000,455800000,376304,298808,00:06:23,00:00:00
|
||||
1788527159,15:05:59,15:05:59,27,997352,175928,cap-wifi3,-58,412900000,455800000,376304,298808,00:06:25,00:00:00
|
||||
1788527161,15:06:01,15:06:01,5,496624,179032,cap-wifi3,-60,455800000,455800000,2283840,1594024,00:06:27,00:00:00
|
||||
1788527163,15:06:03,15:06:03,7,112272,25664,cap-wifi3,-61,455800000,344100000,71224,20160,00:06:30,00:00:00
|
||||
1788527165,15:06:05,15:06:06,6,353280,101384,cap-wifi3,-61,455800000,344100000,71224,20160,00:06:32,00:00:00
|
||||
1788527167,15:06:08,15:06:08,6,137256,37360,cap-wifi3,-63,344100000,344100000,1205496,674488,00:06:34,00:00:00
|
||||
1788527170,15:06:10,15:06:10,18,373144,1851168,cap-wifi3,-62,344100000,455800000,625632,2151904,00:06:36,00:00:00
|
||||
1788527172,15:06:12,15:06:12,2,79504,15688,cap-wifi3,-62,344100000,455800000,625632,2151904,00:06:38,00:00:00
|
||||
1788527174,15:06:14,15:06:14,6,215576,3512448,cap-wifi3,-61,412900000,412900000,720568,420128,00:06:40,00:00:00
|
||||
1788527176,15:06:16,15:06:16,4,170440,37144,cap-wifi3,-63,344100000,309700000,1040816,801272,00:06:42,00:00:00
|
||||
1788527178,15:06:18,15:06:18,7,187488,1860720,cap-wifi3,-63,344100000,309700000,1040816,801272,00:06:44,00:00:00
|
||||
1788527180,15:06:20,15:06:20,21,418584,3563696,cap-wifi3,-63,412900000,275300000,496424,2170904,00:06:46,00:00:00
|
||||
1788527182,15:06:22,15:06:22,6,91920,32648,cap-wifi3,-64,412900000,275300000,539264,491728,00:06:48,00:00:00
|
||||
1788527184,15:06:24,15:06:24,8,229720,340576,cap-wifi3,-64,412900000,275300000,539264,491728,00:06:50,00:00:00
|
||||
1788527186,15:06:26,15:06:26,11,324680,63616,cap-wifi3,-63,412900000,344100000,768576,455936,00:06:52,00:00:00
|
||||
1788527188,15:06:28,15:06:28,7,323944,57120,cap-wifi3,-67,344100000,309700000,515712,335688,00:06:54,00:00:00
|
||||
1788527190,15:06:30,15:06:30,7,89536,26840,cap-wifi3,-67,344100000,309700000,515712,335688,00:06:56,00:00:00
|
||||
1788527192,15:06:32,15:06:32,6,88056,17368,cap-wifi3,-62,344100000,344100000,546008,422232,00:06:58,00:00:00
|
||||
1788527194,15:06:34,15:06:34,6,78232,15688,cap-wifi3,-62,412900000,344100000,403184,296104,00:07:00,00:00:00
|
||||
1788527196,15:06:36,15:06:36,6,77824,19488,cap-wifi3,-62,412900000,344100000,403184,296104,00:07:02,00:00:00
|
||||
1788527198,15:06:38,15:06:38,8,91648,29960,cap-wifi3,-62,412900000,344100000,665616,416832,00:07:04,00:00:00
|
||||
1788527200,15:06:40,15:06:40,6,479584,403096,cap-wifi3,-63,344100000,275300000,1141120,678936,00:07:06,00:00:00
|
||||
1788527202,15:06:42,15:06:42,5,83504,18032,cap-wifi3,-63,344100000,275300000,1141120,678936,00:07:08,00:00:00
|
||||
1788527204,15:06:44,15:06:44,12,94312,27480,cap-wifi3,-64,344100000,344100000,511368,235632,00:07:10,00:00:00
|
||||
1788527206,15:06:46,15:06:46,11,104592,25288,cap-wifi3,-65,412900000,309700000,882160,555064,00:07:12,00:00:00
|
||||
1788527208,15:06:48,15:06:48,9,77672,15824,cap-wifi3,-65,344100000,275300000,71864,300800,00:07:14,00:00:00
|
||||
1788527210,15:06:50,15:06:50,8,130536,65520,cap-wifi3,-65,344100000,275300000,71864,300800,00:07:16,00:00:00
|
||||
1788527212,15:06:52,15:06:52,6,179704,71320,cap-wifi3,-65,309700000,344100000,612752,430056,00:07:19,00:00:00
|
||||
1788527214,15:06:54,15:06:54,7,150376,135320,cap-wifi3,-64,309700000,309700000,556768,426072,00:07:21,00:00:00
|
||||
1788527216,15:06:56,15:06:57,7,180576,117008,cap-wifi3,-64,309700000,309700000,556768,426072,00:07:23,00:00:00
|
||||
1788527219,15:06:59,15:06:59,9,81080,17128,cap-wifi3,-65,344100000,412900000,687448,312096,00:07:25,00:00:00
|
||||
1788527221,15:07:01,15:07:01,6,267072,71760,cap-wifi3,-64,412900000,309700000,1456168,436368,00:07:27,00:00:00
|
||||
1788527223,15:07:03,15:07:03,7,229720,79648,cap-wifi3,-64,412900000,309700000,1456168,436368,00:07:29,00:00:00
|
||||
1788527225,15:07:05,15:07:05,12,613656,242376,cap-wifi3,-65,412900000,344100000,643504,429016,00:07:31,00:00:00
|
||||
1788527227,15:07:07,15:07:07,9,136256,40080,cap-wifi3,-64,412900000,344100000,619904,419664,00:07:33,00:00:00
|
||||
1788527229,15:07:09,15:07:09,11,113040,49536,cap-wifi3,-64,412900000,344100000,619904,419664,00:07:35,00:00:00
|
||||
1788527231,15:07:11,15:07:11,7,85432,17976,cap-wifi3,-64,412900000,309700000,1090376,738848,00:07:37,00:00:00
|
||||
1788527233,15:07:13,15:07:13,5,81944,26128,cap-wifi3,-65,412900000,344100000,947112,611480,00:07:39,00:00:00
|
||||
1788527235,15:07:15,15:07:15,5,954264,397144,cap-wifi3,-65,412900000,344100000,947112,611480,00:07:41,00:00:00
|
||||
1788527237,15:07:17,15:07:17,12,3430312,274976,cap-wifi3,-64,412900000,344100000,1132848,732040,00:07:43,00:00:00
|
||||
1788527239,15:07:19,15:07:19,21,5774264,240088,cap-wifi3,-63,412900000,344100000,886256,615784,00:07:45,00:00:00
|
||||
1788527241,15:07:21,15:07:21,7,419688,124632,cap-wifi3,-63,412900000,344100000,886256,615784,00:07:47,00:00:00
|
||||
1788527243,15:07:23,15:07:23,6,146872,47152,cap-wifi3,-64,412900000,344100000,588616,494568,00:07:49,00:00:00
|
||||
1788527245,15:07:25,15:07:25,6,469520,144920,cap-wifi3,-62,412900000,344100000,576512,462856,00:07:51,00:00:00
|
||||
1788527247,15:07:27,15:07:27,8,87480,21512,cap-wifi3,-62,412900000,344100000,576512,462856,00:07:53,00:00:00
|
||||
1788527249,15:07:29,15:07:29,20,89592,20496,cap-wifi3,-63,455800000,344100000,256840,24640,00:07:55,00:00:00
|
||||
1788527251,15:07:31,15:07:31,9,77304,18144,cap-wifi3,-63,455800000,309700000,883728,710608,00:07:57,00:00:00
|
||||
1788527253,15:07:33,15:07:33,7,84240,17432,cap-wifi3,-63,455800000,309700000,883728,710608,00:07:59,00:00:00
|
||||
1788527255,15:07:35,15:07:35,9,74928,18888,cap-wifi3,-62,455800000,412900000,33632,15216,00:08:01,00:00:00
|
||||
1788527257,15:07:37,15:07:37,12,79856,17376,cap-wifi3,-63,455800000,412900000,859640,23024,00:08:03,00:00:00
|
||||
1788527259,15:07:39,15:07:39,19,91680,31720,cap-wifi3,-62,455800000,412900000,1005448,689888,00:08:06,00:00:00
|
||||
1788527261,15:07:41,15:07:41,7,82760,21192,cap-wifi3,-62,455800000,412900000,1005448,689888,00:08:08,00:00:00
|
||||
1788527263,15:07:43,15:07:44,6,91960,31680,cap-wifi3,-63,516200000,412900000,393768,296624,00:08:10,00:00:00
|
||||
1788527266,15:07:46,15:07:46,12,986832,256184,cap-wifi3,-63,516200000,412900000,558880,414936,00:08:12,00:00:00
|
||||
1788527268,15:07:48,15:07:48,8,204344,305984,cap-wifi3,-63,516200000,412900000,558880,414936,00:08:14,00:00:00
|
||||
1788527270,15:07:50,15:07:50,21,90376,25984,cap-wifi3,-63,455800000,344100000,423096,346496,00:08:16,00:00:00
|
||||
1788527272,15:07:52,15:07:52,9,106024,28632,cap-wifi3,-63,455800000,412900000,549712,433200,00:08:18,00:00:00
|
||||
1788527274,15:07:54,15:07:54,8,86752,24568,cap-wifi3,-63,455800000,412900000,549712,433200,00:08:20,00:00:00
|
||||
1788527276,15:07:56,15:07:56,8,68568,17040,cap-wifi3,-63,455800000,344100000,391568,303576,00:08:22,00:00:00
|
||||
1788527278,15:07:58,15:07:58,7,104792,53200,cap-wifi3,-62,455800000,344100000,715856,336320,00:08:24,00:00:00
|
||||
1788527280,15:08:00,15:08:00,17,304368,102592,cap-wifi3,-62,455800000,344100000,715856,336320,00:08:26,00:00:00
|
||||
1788527282,15:08:02,15:08:02,10,74432,14824,cap-wifi3,-62,455800000,344100000,1540504,579064,00:08:28,00:00:00
|
||||
1788527284,15:08:04,15:08:04,15,84656,54904,cap-wifi3,-62,455800000,412900000,241664,55784,00:08:30,00:00:00
|
||||
1788527286,15:08:06,15:08:06,3,157752,48776,cap-wifi3,-62,455800000,412900000,241664,55784,00:08:32,00:00:00
|
||||
1788527288,15:08:08,15:08:08,6,93880,28544,cap-wifi3,-61,455800000,344100000,662200,323008,00:08:34,00:00:00
|
||||
1788527290,15:08:10,15:08:10,5,92704,21680,cap-wifi3,-62,455800000,412900000,1547016,993208,00:08:36,00:00:00
|
||||
1788527292,15:08:12,15:08:12,4,1096952,456376,cap-wifi3,-62,455800000,412900000,1547016,993208,00:08:38,00:00:00
|
||||
1788527294,15:08:14,15:08:14,5,96296,34168,cap-wifi3,-62,455800000,412900000,658464,380200,00:08:40,00:00:00
|
||||
1788527296,15:08:16,15:08:16,4,323536,108008,cap-wifi3,-62,516200000,412900000,1653400,1083248,00:08:42,00:00:00
|
||||
1788527298,15:08:18,15:08:18,5,106776,31872,cap-wifi3,-62,516200000,412900000,1653400,1083248,00:08:44,00:00:00
|
||||
1788527300,15:08:20,15:08:20,5,180440,70648,cap-wifi3,-62,516200000,412900000,601784,323352,00:08:46,00:00:00
|
||||
1788527302,15:08:22,15:08:22,5,258520,122376,cap-wifi3,-63,516200000,344100000,1414784,982048,00:08:48,00:00:00
|
||||
1788527304,15:08:24,15:08:24,8,484544,159104,cap-wifi3,-63,516200000,344100000,1414784,982048,00:08:50,00:00:00
|
||||
1788527306,15:08:26,15:08:26,5,85832,21400,cap-wifi3,-62,516200000,412900000,594728,332184,00:08:52,00:00:00
|
||||
1788527308,15:08:28,15:08:28,7,86968,23984,cap-wifi3,-62,455800000,412900000,1676496,1014016,00:08:54,00:00:00
|
||||
1788527310,15:08:30,15:08:30,4,92848,27216,cap-wifi3,-62,455800000,412900000,1676496,1014016,00:08:57,00:00:00
|
||||
1788527312,15:08:32,15:08:32,13,88112,30272,cap-wifi3,-61,455800000,412900000,862336,707464,00:08:59,00:00:00
|
||||
1788527314,15:08:34,15:08:35,6,97568,38688,cap-wifi3,-62,455800000,412900000,802192,493640,00:09:01,00:00:00
|
||||
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-63,455800000,412900000,410264,299608,00:09:03,00:00:00
|
||||
1788527319,15:08:39,15:08:39,7,95672,27872,cap-wifi3,-63,455800000,412900000,410264,299608,00:09:05,00:00:00
|
||||
1788527321,15:08:41,15:08:41,8,81008,14064,cap-wifi3,-62,516200000,412900000,1058008,922664,00:09:07,00:00:00
|
||||
1788527323,15:08:43,15:08:43,8,79480,19824,cap-wifi3,-62,516200000,412900000,396520,170800,00:09:09,00:00:00
|
||||
1788527325,15:08:45,15:08:45,6,83080,28888,cap-wifi3,-62,516200000,412900000,396520,170800,00:09:11,00:00:00
|
||||
1788527327,15:08:47,15:08:47,9,77224,19568,cap-wifi3,-62,516200000,455800000,899408,689584,00:09:13,00:00:00
|
||||
1788527329,15:08:49,15:08:49,7,87976,23544,cap-wifi3,-62,516200000,412900000,44600,15184,00:09:15,00:00:00
|
||||
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-62,516200000,412900000,44600,15184,00:09:17,00:00:00
|
||||
1788527333,15:08:53,15:08:53,4,78784,16504,cap-wifi3,-62,516200000,344100000,903552,691192,00:09:19,00:00:00
|
||||
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-64,412900000,309700000,69328,39008,00:09:21,00:00:00
|
||||
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-64,412900000,309700000,69328,39008,00:09:23,00:00:00
|
||||
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-63,344100000,309700000,1149696,710336,00:09:25,00:00:00
|
||||
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-62,412900000,344100000,2232624,903848,00:09:27,00:00:00
|
||||
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-62,412900000,344100000,2232624,903848,00:09:29,00:00:00
|
||||
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-61,344100000,412900000,756464,448360,00:09:31,00:00:00
|
||||
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-63,344100000,344100000,1392608,910264,00:09:33,00:00:00
|
||||
1788527349,15:09:09,15:09:09,19,213416,92736,cap-wifi3,-63,344100000,344100000,1392608,910264,00:09:35,00:00:00
|
||||
1788527351,15:09:11,15:09:11,6,319104,63216,cap-wifi3,-62,412900000,309700000,1209392,477456,00:09:37,00:00:00
|
||||
1788527353,15:09:13,15:09:13,8,153896,48144,cap-wifi3,-62,412900000,344100000,1506680,898696,00:09:39,00:00:00
|
||||
1788527355,15:09:15,15:09:15,5,190952,58360,cap-wifi3,-62,412900000,344100000,1506680,898696,00:09:41,00:00:00
|
||||
1788527357,15:09:17,15:09:17,7,232928,149512,cap-wifi3,-64,412900000,344100000,1033704,613072,00:09:44,00:00:00
|
||||
1788527359,15:09:19,15:09:19,19,108000,26560,cap-wifi3,-64,309700000,344100000,1108648,735944,00:09:46,00:00:00
|
||||
1788527361,15:09:21,15:09:22,10,2754208,213840,cap-wifi3,-64,309700000,344100000,1108648,735944,00:09:48,00:00:00
|
||||
1788527363,15:09:23,15:09:24,7,314040,73608,cap-wifi3,-63,344100000,275300000,981328,613912,00:09:50,00:00:00
|
||||
1788527366,15:09:26,15:09:26,5,485488,100744,cap-wifi3,-58,309700000,309700000,1262008,690008,00:09:52,00:00:00
|
||||
1788527368,15:09:28,15:09:28,6,123816,28072,cap-wifi3,-58,309700000,309700000,1262008,690008,00:09:54,00:00:00
|
||||
1788527370,15:09:30,15:09:30,19,124944,35616,cap-wifi3,-63,309700000,206500000,260104,31680,00:09:56,00:00:00
|
||||
1788527372,15:09:32,15:09:32,5,171352,44496,cap-wifi3,-61,344100000,309700000,1238528,574776,00:09:58,00:00:00
|
||||
1788527374,15:09:34,15:09:34,6,166240,43784,cap-wifi3,-64,344100000,344100000,531000,227904,00:10:00,00:00:00
|
||||
1788527376,15:09:36,15:09:36,6,150760,49464,cap-wifi3,-64,344100000,344100000,531000,227904,00:10:02,00:00:00
|
||||
1788527378,15:09:38,15:09:38,10,185768,47120,cap-wifi3,-64,344100000,309700000,929200,634112,00:10:04,00:00:00
|
||||
1788527380,15:09:40,15:09:40,18,190032,49512,cap-wifi3,-64,344100000,309700000,666528,183736,00:10:06,00:00:00
|
||||
1788527382,15:09:42,15:09:42,8,97808,22304,cap-wifi3,-64,344100000,309700000,666528,183736,00:10:08,00:00:00
|
||||
1788527384,15:09:44,15:09:44,8,148400,53672,cap-wifi3,-63,412900000,344100000,981232,603784,00:10:10,00:00:00
|
||||
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-62,412900000,309700000,225464,141192,00:10:12,00:00:00
|
||||
1788527388,15:09:48,15:09:48,4,76456,19280,cap-wifi3,-62,412900000,309700000,225464,141192,00:10:14,00:00:00
|
||||
1788527390,15:09:50,15:09:50,17,74488,14496,cap-wifi3,-63,344100000,275300000,731840,568104,00:10:16,00:00:00
|
||||
1788527392,15:09:52,15:09:52,9,81688,114120,cap-wifi3,-64,412900000,309700000,217144,287216,00:10:18,00:00:00
|
||||
1788527394,15:09:54,15:09:54,11,139472,94312,cap-wifi3,-64,412900000,309700000,217144,287216,00:10:20,00:00:00
|
||||
1788527396,15:09:56,15:09:56,8,99376,34800,cap-wifi3,-63,412900000,344100000,522856,417128,00:10:22,00:00:00
|
||||
1788527398,15:09:58,15:09:58,7,95624,20936,cap-wifi3,-64,412900000,344100000,1177520,673088,00:10:24,00:00:00
|
||||
1788527400,15:10:00,15:10:00,11,75688,17080,cap-wifi3,-64,412900000,344100000,1177520,673088,00:10:26,00:00:00
|
||||
1788527402,15:10:02,15:10:02,8,194448,59984,cap-wifi3,-62,412900000,412900000,1678424,596296,00:10:28,00:00:00
|
||||
1788527404,15:10:04,15:10:04,5,87848,23392,cap-wifi3,-62,412900000,412900000,1099136,718696,00:10:30,00:00:00
|
||||
1788527406,15:10:06,15:10:06,4,102440,31824,cap-wifi3,-62,412900000,412900000,1099136,718696,00:10:32,00:00:00
|
||||
1788527408,15:10:08,15:10:08,7,140352,49312,cap-wifi3,-65,412900000,309700000,944912,595928,00:10:34,00:00:00
|
||||
1788527410,15:10:10,15:10:10,20,81216,18128,cap-wifi3,-64,455800000,344100000,1466688,782256,00:10:36,00:00:00
|
||||
1788527412,15:10:12,15:10:12,8,223088,23248,cap-wifi3,-64,455800000,344100000,1466688,782256,00:10:38,00:00:00
|
||||
1788527414,15:10:14,15:10:14,7,139784,51840,cap-wifi3,-63,412900000,344100000,1572056,878688,00:10:40,00:00:00
|
||||
1788527415,15:10:15,RECONNECT
|
||||
|
1
docs/messdaten/tp25-runde-dauerping/sampler-macbook.out
Normal file
1
docs/messdaten/tp25-runde-dauerping/sampler-macbook.out
Normal file
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-macbook.csv (Takt 2s, Client 56:71:6C:22:E6:A9)
|
||||
@@ -0,0 +1,2 @@
|
||||
14:58:12 Verbindung weg -- neuer Versuch in 2 s
|
||||
15:10:15 Verbindung weg -- neuer Versuch in 2 s
|
||||
130
docs/messdaten/tp25-runde-dauerping/sampler-s22.csv
Normal file
130
docs/messdaten/tp25-runde-dauerping/sampler-s22.csv
Normal file
@@ -0,0 +1,130 @@
|
||||
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
|
||||
1788527155,15:05:55,15:05:55,26,215104,164208,cap-wifi3,-50,6000000,6000000,0,0,00:00:50,00:00:18.020
|
||||
1788527157,15:05:57,15:05:57,10,230144,103104,cap-wifi3,-49,309700000,344100000,63424,67648,00:00:52,00:00:00
|
||||
1788527159,15:05:59,15:05:59,27,997352,175928,cap-wifi3,-49,309700000,344100000,63424,67648,00:00:55,00:00:00
|
||||
1788527161,15:06:01,15:06:01,5,496624,179032,cap-wifi3,-49,309700000,344100000,2800,2960,00:00:57,00:00:00
|
||||
1788527163,15:06:03,15:06:03,7,112272,25664,cap-wifi3,-49,309700000,344100000,2800,2960,00:00:59,00:00:00
|
||||
1788527165,15:06:05,15:06:06,6,353280,101384,cap-wifi3,-49,309700000,344100000,2800,2960,00:01:01,00:00:00
|
||||
1788527168,15:06:08,15:06:08,6,137256,37360,cap-wifi3,-53,309700000,344100000,5472,4672,00:01:03,00:00:00
|
||||
1788527170,15:06:10,15:06:10,18,373144,1851168,cap-wifi3,-61,275300000,206500000,2800,2960,00:01:05,00:00:00
|
||||
1788527172,15:06:12,15:06:12,2,79504,15688,cap-wifi3,-61,275300000,206500000,2800,2960,00:01:07,00:00:00
|
||||
1788527174,15:06:14,15:06:14,6,215576,3512448,cap-wifi3,-56,154900000,258100000,3592,4872,00:01:09,00:00:00
|
||||
1788527176,15:06:16,15:06:16,4,170440,37144,cap-wifi3,-51,24000000,229400000,2800,10960,00:01:11,00:00:00
|
||||
1788527178,15:06:18,15:06:18,7,187488,1860720,cap-wifi3,-51,24000000,229400000,2800,10960,00:01:13,00:00:00
|
||||
1788527180,15:06:20,15:06:20,21,418584,3563696,cap-wifi3,-52,275300000,258100000,2800,2960,00:01:15,00:00:00
|
||||
1788527182,15:06:22,15:06:22,6,91920,32648,cap-wifi3,-51,275300000,286800000,2800,10960,00:01:17,00:00:00
|
||||
1788527184,15:06:24,15:06:24,8,229720,340576,cap-wifi3,-51,275300000,286800000,2800,10960,00:01:19,00:00:00
|
||||
1788527186,15:06:26,15:06:26,11,324680,63616,cap-wifi3,-52,275300000,286800000,4184,4376,00:01:21,00:00:00
|
||||
1788527188,15:06:28,15:06:28,7,323944,57120,cap-wifi3,-50,275300000,309700000,3360,3552,00:01:23,00:00:00
|
||||
1788527190,15:06:30,15:06:30,7,89536,26840,cap-wifi3,-50,275300000,309700000,3360,3552,00:01:25,00:00:00
|
||||
1788527192,15:06:32,15:06:32,6,88056,17368,cap-wifi3,-50,275300000,344100000,5344,8864,00:01:27,00:00:00
|
||||
1788527194,15:06:34,15:06:34,6,78232,15688,cap-wifi3,-52,275300000,309700000,3248,3328,00:01:29,00:00:00
|
||||
1788527196,15:06:36,15:06:36,6,77824,19488,cap-wifi3,-52,275300000,309700000,3248,3328,00:01:31,00:00:00
|
||||
1788527198,15:06:38,15:06:38,8,91648,29960,cap-wifi3,-58,275300000,344100000,2800,2960,00:01:33,00:00:00
|
||||
1788527200,15:06:40,15:06:40,6,479584,403096,cap-wifi3,-51,275300000,229400000,2800,2960,00:01:35,00:00:00
|
||||
1788527202,15:06:42,15:06:42,5,83504,18032,cap-wifi3,-51,275300000,229400000,2800,2960,00:01:37,00:00:00
|
||||
1788527204,15:06:44,15:06:44,12,94312,27480,cap-wifi3,-54,275300000,258100000,2800,2960,00:01:39,00:00:00
|
||||
1788527206,15:06:46,15:06:46,11,104592,25288,cap-wifi3,-53,275300000,286800000,2800,10960,00:01:41,00:00:00
|
||||
1788527208,15:06:48,15:06:48,9,77672,15824,cap-wifi3,-52,24000000,286800000,2800,2960,00:01:43,00:00:00
|
||||
1788527210,15:06:50,15:06:50,8,130536,65520,cap-wifi3,-52,24000000,286800000,2800,2960,00:01:46,00:00:00
|
||||
1788527212,15:06:52,15:06:52,6,179704,71320,cap-wifi3,-53,6000000,286800000,3360,3552,00:01:48,00:00:00
|
||||
1788527214,15:06:54,15:06:54,7,150376,135320,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:50,00:00:00
|
||||
1788527216,15:06:56,15:06:57,7,180576,117008,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:52,00:00:00
|
||||
1788527219,15:06:59,15:06:59,9,81080,17128,cap-wifi3,-52,275300000,309700000,2800,2960,00:01:54,00:00:00
|
||||
1788527221,15:07:01,15:07:01,6,267072,71760,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:56,00:00:00
|
||||
1788527223,15:07:03,15:07:03,7,229720,79648,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:58,00:00:00
|
||||
1788527225,15:07:05,15:07:05,12,613656,242376,cap-wifi3,-53,275300000,344100000,2800,2960,00:02:00,00:00:00
|
||||
1788527227,15:07:07,15:07:07,9,136256,40080,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:02,00:00:00
|
||||
1788527229,15:07:09,15:07:09,11,113040,49536,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:04,00:00:00
|
||||
1788527231,15:07:11,15:07:11,7,85432,17976,cap-wifi3,-53,275300000,309700000,2800,2960,00:02:06,00:00:00
|
||||
1788527233,15:07:13,15:07:13,5,81944,26128,cap-wifi3,-56,275300000,286800000,2800,3552,00:02:08,00:00:00
|
||||
1788527235,15:07:15,15:07:15,5,954264,397144,cap-wifi3,-56,275300000,286800000,2800,3552,00:02:10,00:00:00
|
||||
1788527237,15:07:17,15:07:17,12,3430312,274976,cap-wifi3,-50,275300000,344100000,11168,29128,00:02:12,00:00:00
|
||||
1788527239,15:07:19,15:07:19,21,5774264,240088,cap-wifi3,-50,275300000,344100000,3360,3552,00:02:14,00:00:00
|
||||
1788527241,15:07:21,15:07:21,7,419688,124632,cap-wifi3,-50,275300000,344100000,3360,3552,00:02:16,00:00:00
|
||||
1788527243,15:07:23,15:07:23,6,146872,47152,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:18,00:00:00
|
||||
1788527245,15:07:25,15:07:25,6,469520,144920,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:20,00:00:00
|
||||
1788527247,15:07:27,15:07:27,8,87480,21512,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:22,00:00:00
|
||||
1788527249,15:07:29,15:07:29,20,89592,20496,cap-wifi3,-50,275300000,344100000,3360,3552,00:02:24,00:00:00
|
||||
1788527251,15:07:31,15:07:31,9,77304,18144,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:26,00:00:00
|
||||
1788527253,15:07:33,15:07:33,7,84240,17432,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:28,00:00:00
|
||||
1788527255,15:07:35,15:07:35,9,74928,18888,cap-wifi3,-51,275300000,344100000,2240,2368,00:02:30,00:00:00
|
||||
1788527257,15:07:37,15:07:37,12,79856,17376,cap-wifi3,-51,275300000,344100000,2800,2960,00:02:33,00:00:00
|
||||
1788527259,15:07:39,15:07:39,19,91680,31720,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:35,00:00:00
|
||||
1788527261,15:07:41,15:07:41,7,82760,21192,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:37,00:00:00
|
||||
1788527263,15:07:43,15:07:44,6,91960,31680,cap-wifi3,-51,309700000,344100000,4912,4080,00:02:39,00:00:00
|
||||
1788527266,15:07:46,15:07:46,12,986832,256184,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:41,00:00:00
|
||||
1788527268,15:07:48,15:07:48,8,204344,305984,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:43,00:00:00
|
||||
1788527270,15:07:50,15:07:50,21,90376,25984,cap-wifi3,-50,309700000,412900000,2800,2960,00:02:45,00:00:00
|
||||
1788527272,15:07:52,15:07:52,9,106024,28632,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:47,00:00:00
|
||||
1788527274,15:07:54,15:07:54,8,86752,24568,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:49,00:00:00
|
||||
1788527276,15:07:56,15:07:56,8,68568,17040,cap-wifi3,-51,309700000,412900000,2800,2960,00:02:51,00:00:00
|
||||
1788527278,15:07:58,15:07:58,7,104792,53200,cap-wifi3,-48,206500000,344100000,3360,3552,00:02:53,00:00:00
|
||||
1788527280,15:08:00,15:08:00,17,304368,102592,cap-wifi3,-48,206500000,344100000,3360,3552,00:02:55,00:00:00
|
||||
1788527282,15:08:02,15:08:02,10,74432,14824,cap-wifi3,-49,206500000,344100000,2800,2960,00:02:57,00:00:00
|
||||
1788527284,15:08:04,15:08:04,15,84656,54904,cap-wifi3,-48,206500000,344100000,2800,2960,00:02:59,00:00:00
|
||||
1788527286,15:08:06,15:08:06,3,157752,48776,cap-wifi3,-48,206500000,344100000,2800,2960,00:03:01,00:00:00
|
||||
1788527288,15:08:08,15:08:08,6,93880,28544,cap-wifi3,-48,206500000,344100000,3360,3552,00:03:03,00:00:00
|
||||
1788527290,15:08:10,15:08:10,5,92704,21680,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:05,00:00:00
|
||||
1788527292,15:08:12,15:08:12,4,1096952,456376,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:07,00:00:00
|
||||
1788527294,15:08:14,15:08:14,5,96296,34168,cap-wifi3,-48,206500000,344100000,2800,2960,00:03:09,00:00:00
|
||||
1788527296,15:08:16,15:08:16,4,323536,108008,cap-wifi3,-48,206500000,344100000,4184,4376,00:03:11,00:00:00
|
||||
1788527298,15:08:18,15:08:18,5,106776,31872,cap-wifi3,-48,206500000,344100000,4184,4376,00:03:13,00:00:00
|
||||
1788527300,15:08:20,15:08:20,5,180440,70648,cap-wifi3,-49,206500000,344100000,3360,3552,00:03:15,00:00:00
|
||||
1788527302,15:08:22,15:08:22,5,258520,122376,cap-wifi3,-49,206500000,344100000,2800,10960,00:03:17,00:00:00
|
||||
1788527304,15:08:24,15:08:24,8,484544,159104,cap-wifi3,-49,206500000,344100000,2800,10960,00:03:19,00:00:00
|
||||
1788527306,15:08:26,15:08:26,5,85832,21400,cap-wifi3,-48,206500000,344100000,3360,2960,00:03:21,00:00:00
|
||||
1788527308,15:08:28,15:08:28,7,86968,23984,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:24,00:00:00
|
||||
1788527310,15:08:30,15:08:30,4,92848,27216,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:26,00:00:00
|
||||
1788527312,15:08:32,15:08:32,13,88112,30272,cap-wifi3,-49,206500000,344100000,3360,3552,00:03:28,00:00:00
|
||||
1788527314,15:08:34,15:08:35,6,97568,38688,cap-wifi3,-50,206500000,344100000,2800,2960,00:03:30,00:00:00
|
||||
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:32,00:00:00
|
||||
1788527319,15:08:39,15:08:39,7,95672,27872,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:34,00:00:00
|
||||
1788527321,15:08:41,15:08:41,8,81008,14064,cap-wifi3,-49,206500000,344100000,3360,3552,00:03:36,00:00:00
|
||||
1788527323,15:08:43,15:08:43,8,79480,19824,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:38,00:00:00
|
||||
1788527325,15:08:45,15:08:45,6,83080,28888,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:40,00:00:00
|
||||
1788527327,15:08:47,15:08:47,9,77224,19568,cap-wifi3,-49,206500000,309700000,3360,3552,00:03:42,00:00:00
|
||||
1788527329,15:08:49,15:08:49,7,87976,23544,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:44,00:00:00
|
||||
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:46,00:00:00
|
||||
1788527333,15:08:53,15:08:53,7,78784,16504,cap-wifi3,-45,206500000,309700000,2800,2960,00:03:48,00:00:00
|
||||
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-60,206500000,309700000,2800,2960,00:03:50,00:00:00
|
||||
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-60,206500000,309700000,2800,2960,00:03:52,00:00:00
|
||||
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-58,206500000,309700000,2800,2960,00:03:54,00:00:00
|
||||
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-54,6000000,6000000,3360,3552,00:03:56,00:00:00
|
||||
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-54,6000000,6000000,3360,3552,00:03:58,00:00:00
|
||||
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-56,275300000,344100000,2800,2960,00:04:00,00:00:00
|
||||
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-54,275300000,344100000,3360,3552,00:04:02,00:00:00
|
||||
1788527349,15:09:09,15:09:09,19,174312,46976,cap-wifi3,-54,275300000,344100000,3360,3552,00:04:04,00:00:00
|
||||
1788527351,15:09:11,15:09:11,6,359504,63184,cap-wifi3,-54,275300000,309700000,2800,2960,00:04:06,00:00:00
|
||||
1788527353,15:09:13,15:09:13,8,181920,63704,cap-wifi3,-58,24000000,344100000,2800,4896,00:04:08,00:00:00
|
||||
1788527355,15:09:15,15:09:15,5,306368,67704,cap-wifi3,-58,24000000,344100000,2800,4896,00:04:10,00:00:00
|
||||
1788527357,15:09:17,15:09:17,7,306688,60896,cap-wifi3,-57,275300000,309700000,3656,3520,00:04:12,00:00:00
|
||||
1788527359,15:09:19,15:09:19,19,310240,63104,cap-wifi3,-57,154900000,309700000,4384,6048,00:04:14,00:00:00
|
||||
1788527361,15:09:21,15:09:21,10,228704,92160,cap-wifi3,-57,154900000,309700000,4384,6048,00:04:16,00:00:00
|
||||
1788527363,15:09:23,15:09:23,7,292296,160184,cap-wifi3,-61,154900000,309700000,10568,37976,00:04:18,00:00:00
|
||||
1788527365,15:09:25,15:09:25,5,695128,395648,cap-wifi3,-56,154900000,309700000,3360,3552,00:04:20,00:00:00
|
||||
1788527367,15:09:27,15:09:27,6,123816,28072,cap-wifi3,-56,154900000,309700000,3360,3552,00:04:22,00:00:00
|
||||
1788527369,15:09:29,15:09:29,19,124944,35616,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:24,00:00:00
|
||||
1788527371,15:09:31,15:09:31,5,171352,44496,cap-wifi3,-57,154900000,275300000,4040,6584,00:04:26,00:00:00
|
||||
1788527373,15:09:33,15:09:33,6,166240,43784,cap-wifi3,-57,154900000,275300000,4040,6584,00:04:28,00:00:00
|
||||
1788527375,15:09:35,15:09:35,6,150760,49464,cap-wifi3,-56,154900000,309700000,2800,2960,00:04:31,00:00:00
|
||||
1788527377,15:09:37,15:09:37,10,185768,47120,cap-wifi3,-57,24000000,309700000,2800,2960,00:04:33,00:00:00
|
||||
1788527379,15:09:39,15:09:39,18,190032,49512,cap-wifi3,-57,24000000,309700000,2800,2960,00:04:35,00:00:00
|
||||
1788527381,15:09:41,15:09:41,8,97808,22304,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:37,00:00:00
|
||||
1788527383,15:09:43,15:09:43,8,148400,53672,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:39,00:00:00
|
||||
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:41,00:00:00
|
||||
1788527387,15:09:47,15:09:48,4,76456,19280,cap-wifi3,-57,154900000,309700000,2800,3552,00:04:43,00:00:00
|
||||
1788527389,15:09:49,15:09:50,17,74488,14496,cap-wifi3,-58,6000000,309700000,2800,2960,00:04:45,00:00:00
|
||||
1788527392,15:09:52,15:09:52,4,81688,114120,cap-wifi3,-58,6000000,309700000,2800,2960,00:04:47,00:00:00
|
||||
1788527394,15:09:54,15:09:54,8,139472,94312,cap-wifi3,-57,154900000,309700000,2800,2960,00:04:49,00:00:00
|
||||
1788527396,15:09:56,15:09:56,4,99376,34800,cap-wifi3,-57,154900000,309700000,2800,2960,00:04:51,00:00:00
|
||||
1788527398,15:09:58,15:09:58,5,95624,20936,cap-wifi3,-57,154900000,309700000,2800,2960,00:04:53,00:00:00
|
||||
1788527400,15:10:00,15:10:00,19,75688,17080,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:55,00:00:00
|
||||
1788527402,15:10:02,15:10:02,12,194448,59984,cap-wifi3,-56,154900000,344100000,2800,2960,00:04:57,00:00:00
|
||||
1788527404,15:10:04,15:10:04,10,87848,23392,cap-wifi3,-58,154900000,344100000,2800,2960,00:04:59,00:00:00
|
||||
1788527406,15:10:06,15:10:06,9,102440,31824,cap-wifi3,-58,154900000,344100000,2800,2960,00:05:01,00:00:00
|
||||
1788527408,15:10:08,15:10:08,8,140352,49312,cap-wifi3,-56,154900000,309700000,2800,2960,00:05:03,00:00:00
|
||||
1788527410,15:10:10,15:10:10,25,88352,30376,cap-wifi3,-56,154900000,309700000,2800,2960,00:05:05,00:00:00
|
||||
1788527412,15:10:12,15:10:12,7,124328,46808,cap-wifi3,-56,154900000,309700000,2800,2960,00:05:07,00:00:00
|
||||
1788527414,15:10:14,15:10:14,8,84784,23040,cap-wifi3,-57,154900000,344100000,2800,2960,00:05:09,00:00:00
|
||||
1788527415,15:10:15,RECONNECT
|
||||
|
1
docs/messdaten/tp25-runde-dauerping/sampler-s22.out
Normal file
1
docs/messdaten/tp25-runde-dauerping/sampler-s22.out
Normal file
@@ -0,0 +1 @@
|
||||
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-s22.csv (Takt 2s, Client 2A:0D:B0:5D:AD:A7)
|
||||
@@ -0,0 +1,2 @@
|
||||
14:58:12 Verbindung weg -- neuer Versuch in 2 s
|
||||
15:10:15 Verbindung weg -- neuer Versuch in 2 s
|
||||
0
docs/messdaten/tp25-runde-dauerping/stop.flag
Normal file
0
docs/messdaten/tp25-runde-dauerping/stop.flag
Normal file
1280
docs/messdaten/tp25-runde-dauerping/walk-ping-ipad.csv
Normal file
1280
docs/messdaten/tp25-runde-dauerping/walk-ping-ipad.csv
Normal file
File diff suppressed because it is too large
Load Diff
1299
docs/messdaten/tp25-runde-dauerping/walk-ping-iphone.csv
Normal file
1299
docs/messdaten/tp25-runde-dauerping/walk-ping-iphone.csv
Normal file
File diff suppressed because it is too large
Load Diff
1304
docs/messdaten/tp25-runde-dauerping/walk-ping-macbook.csv
Normal file
1304
docs/messdaten/tp25-runde-dauerping/walk-ping-macbook.csv
Normal file
File diff suppressed because it is too large
Load Diff
1302
docs/messdaten/tp25-runde-dauerping/walk-ping-s22.csv
Normal file
1302
docs/messdaten/tp25-runde-dauerping/walk-ping-s22.csv
Normal file
File diff suppressed because it is too large
Load Diff
@@ -62,6 +62,12 @@ teuerste Eigenschaft der Datei zerstört, um ihr billigstes Problem zu lösen. B
|
||||
| [TP27](#tp27) | RouterBOOT-Firmware auf 7.24 nachziehen | ✅ DURCH (2026-08-17/18) |
|
||||
| [TP28](#tp28) | WLAN über CAPsMAN auf `crs326-core` | ↩️ **wieder geöffnet 2026-08-30** (ap3) — Volltext in [teilprojekte.md](teilprojekte.md#tp28) |
|
||||
| [TP-R](#tp-r) | Router-Capabilities-Sweep | FERTIG (docs/research/routeros-capabilities.md) |
|
||||
| [TP39](#tp39) | LXC-Hygiene pve: Resolver-Altlasten, `networking.service`, DB-Reverse-Lookup | ✅ ABGESCHLOSSEN (2026-09-01) — pve+NAS-Sweep grün |
|
||||
| [TP34](#tp34) | Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle) | ❌ VERWORFEN (2026-09-08) — Caddyfile bleibt manuell |
|
||||
| [TP44](#tp44) | Cloudflare-Estate als Dokumentations-SSoT in Nautobot | ✅ DURCH (2026-09-10) |
|
||||
| [TP41](#tp41) | CF-Access-Reparatur + Zero-Trust-Konsolidierung | ✅ ABGESCHLOSSEN (2026-09-10) — Gelis WARP via Android eingerichtet, letzter Blocker weg |
|
||||
| [TP43](#tp43) | dw-Standort-DNS-Uplink (site-spezifische Overrides) | ♻️ REOPENED (2026-09-11) — Volltext zurück in teilprojekte.md; interne BF-Namen über WG am dw offen |
|
||||
| [TP42](#tp42) | Namens-Vereinheitlichung: ein interner Suffix bf.emsenhuber.net | ✅ DURCH (2026-09-02) — `.bf.lan` raus, `.16` abgebaut, Compliance 140/140 |
|
||||
|
||||
Dazu am Ende: **[TP25 (Langfassung)](#tp25-lang)** — die Messchronik und die Funde A–E im Volltext.
|
||||
TP25 selbst ist **nicht** abgeschlossen und steht weiter in `teilprojekte.md`; nur seine 394 Zeilen
|
||||
@@ -1697,3 +1703,277 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
|
||||
2026-08-13 gemessen: ap1 25→2, ap2 7→14). **Nicht während eines Calls deployen.** `/system backup` je AP vorher.
|
||||
- **Abh.:** TP22 ✅ (GC-Deploy-Pipeline). Übernimmt den offenen Rest von **TP3.3**, verwandt **TP3.2** (Coverage-Doku
|
||||
`docs/wifi-p750w-coverage-and-map.md`). **Kein Blocker für TP5/TP6** — läuft parallel.
|
||||
|
||||
<a id="tp39"></a>
|
||||
|
||||
### TP39 — LXC-Hygiene auf pve: Resolver-Altlasten, `networking.service`, DB-Reverse-Lookup ▸ ✅ **ABGESCHLOSSEN (2026-09-01)**
|
||||
|
||||
**Auslöser:** ein 10-Sekunden-Hänger auf `gitea`, gefunden am Rand des TP16.3-§5-Flips. Er hatte mit
|
||||
dem Flip nichts zu tun, war aber nur deshalb sichtbar, weil zum ersten Mal jemand systematisch
|
||||
gemessen hat. Beim Beheben kam eine zweite, unabhängige Altlast zum Vorschein. Beide sind
|
||||
**Hygiene an denselben pve-LXCs** und gehören in **ein** Wartungsfenster — deshalb ein TP, nicht zwei.
|
||||
|
||||
#### Was am 2026-09-01 bereits erledigt ist (Ausgangslage, nicht Aufgabe)
|
||||
|
||||
- **Ursache des Hängers:** MariaDB (LXC **302**, `10.40.20.23`) hatte `skip-name-resolve`
|
||||
**auskommentiert** ⇒ Reverse-Lookup bei **jeder neuen Verbindung**; `/etc/resolv.conf` zeigte auf
|
||||
den **toten** `10.40.41.254` (VLAN1-Altschema). **Gemessen: 10.010 ms je Lookup.**
|
||||
Pool-Verbindungen waren schnell ⇒ das Symptom wirkte sporadisch.
|
||||
- **Blast-Radius, per Verbindungstabelle belegt:** an dieser DB hängen **Vaultwarden (`.127`),
|
||||
Home Assistant (`.105`) und gitea (`.157`)**.
|
||||
- **Fix ausgerollt** (`pct set <id> --nameserver 10.40.20.1` + Reboot) für **fünf** LXCs:
|
||||
`302 mariadb`, `102 mqtt5`, `106 influxdb2`, `107 redis`, `150 iob-exposed`.
|
||||
**Nachher: Lookup 21–24 ms, gitea 0 von 25 Proben langsam** (vorher ~10 % bei 10,1 s).
|
||||
|
||||
#### Scope (alle Punkte erledigt)
|
||||
|
||||
1. ✅ **ERLEDIGT 2026-09-01: `skip-name-resolve` aktiviert.** Vorher `mysql.user` gelesen (User gab
|
||||
den DB-Zugang per `/root/.my.cnf`) — **kein einziger Grant lautet auf einen DNS-Hostnamen**, alle
|
||||
sind `%` / IP-Literal / `localhost`. Damit kann `skip-name-resolve` niemanden aussperren; der
|
||||
Reverse-Lookup war reiner Ballast. Gesetzt als eigenes Drop-in
|
||||
`/etc/mysql/mariadb.conf.d/90-skip-name-resolve.cnf` (nicht die `#`-Zeile in `50-server.cnf`
|
||||
editiert — Paket-Update-stabil), `@@skip_name_resolve=1` nach Neustart verifiziert.
|
||||
**Wirkung: gitea/vw/hass je 0 von 12 frischen Anfragen langsam, max 0,25 s.** Alle drei Clients
|
||||
danach wieder verbunden. Die Ursache ist damit **beseitigt**, nicht nur entschärft.
|
||||
🔴 **Sicherheitsvorfall dabei:** die `.my.cnf` trug `password <wert>` **ohne `=`**, die Maskierung
|
||||
griff nicht ⇒ das **root-DB-Passwort ist ins Transkript geraten** und gehört rotiert (→ TP30).
|
||||
2. ✅ **ERLEDIGT 2026-09-01: `networking.service` + `ifupdown-wait-online.service` in `101`, `102`,
|
||||
`106`, `107` repariert.** **Ursache — dieselbe Altlast wie beim Resolver:** in
|
||||
`/etc/network/interfaces` standen noch `auto`-Stanzas aus dem **alten VLAN1-Schema**
|
||||
(`eth0` → `10.40.41.x`) und aus früheren Versuchen (`veth16`, `veth24`, ein Tippfehler `eth01`) —
|
||||
**alle auf Interfaces, die es im Container nicht gibt.** `ifup -a` scheiterte daran, während das
|
||||
echte `veth20` sauber hochkam: „failed" bei funktionierendem Netz.
|
||||
**Fix:** nur die toten Stanzas entfernt (Backup je Container:
|
||||
`/etc/network/interfaces.bak-20260901`), `lo`/`veth20`/`veth20.2` unangetastet.
|
||||
**Beweis ist ein echter Neustart, nicht der Servicestatus:** `106` neu gestartet ⇒ **influxdb kam
|
||||
nach 5 s von selbst hoch**, `networking active`, **null** fehlgeschlagene Units. Genau der Fall,
|
||||
der vorher scheiterte.
|
||||
🔑 **Nicht durch die Session verursacht:** `101` wurde vor dem Fix nie angefasst und zeigte dasselbe
|
||||
Bild — die Container liefen nur 13+ Tage ohne Neustart, deshalb war es unsichtbar.
|
||||
🟡 **Rest, bewusst liegen gelassen:** `run-rpc_pipefs.mount` (101, 150) und
|
||||
`proxmox-regenerate-snakeoil.service` (108) — vorbestehend, ohne Bezug zu Netz oder DNS.
|
||||
3. ✅ **ERLEDIGT 2026-09-01 (im selben Fenster aufgetaucht): LXC 302 war zu 100 % voll** (62/65 GB),
|
||||
Rootfs `+30G` online gewachsen ⇒ 95 GB / 69 %, MariaDB lief durch. 🔴 **Das ist ein Puffer, kein
|
||||
Fix:** 59 GB davon sind die `homeassistant`-DB (`states.ibd` allein **41 GB**), die unbegrenzt
|
||||
wächst (~1 GB/Tag) — die dauerhafte Lösung ist HA-seitig und liegt in **TP40**.
|
||||
4. ✅ **ERLEDIGT 2026-09-01: Resolver-Sweep durchgezogen — pve UND NAS.** **pve:** alle 13 LXCs
|
||||
(`101,102,105,106,107,108,110,111,112,130,150,302,400`) tragen `nameserver 10.40.20.1`, **kein
|
||||
`.41.254` mehr** — nicht nur die fünf geänderten. **NAS (DS923) via Portainer-API ep14:** alle
|
||||
20 Container gelistet, keiner mit `.41.254`-DNS-Override; alle laufenden lösen über den
|
||||
Embedded-Resolver (`127.0.0.11`) in **66–110 ms** auf (rc=0), inkl. Grenzfall `gitea` (erstellt
|
||||
2026-07-10, um den Host-Fix herum) — **kein eingefrorener Dead-Resolver**, kein Recreate nötig.
|
||||
NAS-Host `/etc/resolv.conf` = `10.40.20.1`. Als **wiederkehrende Kontrolle** bleibt der Sweep als
|
||||
CLAUDE.md-Gotcha verankert (pve-Einzeiler + Synology-DSM-Fallstrick von 2026-07-10).
|
||||
5. ✅ **ERLEDIGT 2026-09-01: Abnahme-Regel festgeschrieben.** „Vor jedem geplanten LXC-Neustart
|
||||
`systemctl --failed` lesen und danach die **Ports gegen vorher** vergleichen" steht als
|
||||
CLAUDE.md-Gotcha (Fall `influxdb2` wäre sonst still durchgerutscht).
|
||||
|
||||
#### Abhängigkeiten
|
||||
|
||||
- Keine blockierenden. Punkt 1 brauchte **DB-Credentials** (siehe **TP30**, Credential-Bestand).
|
||||
- Punkt 2 war unabhängig und lief zuerst.
|
||||
|
||||
#### Abgrenzung
|
||||
|
||||
- **Nicht** TP16.3: dort geht es um cloudflared/Tunnel: der DNS-Fund kam nur *dabei* ans Licht.
|
||||
- **Nicht** TP14.2a: das war 2026-07-10 derselbe Fehlertyp an **anderen** Hosts (NAS + LXC 400) und
|
||||
ist abgeschlossen. **Dass er hier erneut auftrat, ist genau die Begründung für Punkt 4:**
|
||||
die Klasse wurde damals an den bekannten Stellen behoben, nie im Bestand gesucht.
|
||||
- **Nicht** TP31/TP34 (Caddy) und nicht TP11 (Monitoring) — obwohl gilt: ein Monitoring, das
|
||||
DB-Verbindungszeiten kennt, hätte diesen Fall Monate früher gezeigt.
|
||||
- **Nicht** TP40: der HA-Recorder-Wildwuchs (Punkt 3) ist HA-seitig und ein eigenes TP.
|
||||
|
||||
---
|
||||
|
||||
### TP34 — Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle) ▸ ❌ **VERWORFEN (2026-09-08)**
|
||||
> 🔴 **Nachtrag 2026-09-08 (verworfen):** Der Ansatz „Caddyfile via Golden Config rendern" ist
|
||||
> zurückgezogen (Commits `d63dc7b`, `bca8f6e`; Gitea-Issue #24 → `status:dropped`, closed). Der
|
||||
> `420.teilzeitladen.xyz`-Block wurde wieder aus dem GC-gerenderten Caddyfile entfernt; **der
|
||||
> Caddyfile bleibt manuell** in `caddy/Caddyfile`. Gründe: kein zweites SSoT-Modell für Proxy-Routen
|
||||
> nötig, TP37 deckt die Dienst-Doku als `ipam.Service` bereits ab, und der einzige akute Anwendungsfall
|
||||
> ließ sich mit einem manuellen Block lösen. Text unten unverändert als Konzept-Historie.
|
||||
|
||||
> **Konzept + Architektur-Skizze:** [`docs/handoff-20260827-inventur-und-architektur.md`](handoff-20260827-inventur-und-architektur.md) — bitte dort weiterlesen (Architektur-Abschnitt).
|
||||
- **Scope:** Reverse-Proxy-Hosts werden im **Nautobot-Datenmodell** gepflegt (Site, Host, Backend-Spec). **Golden Config** rendert den Caddyfile aus den Daten, Diff-Check gegen die Live-Version auf `caddy-bf1`, Compliance-Checks + Transaktionen identisch zum bestehenden Workflow für Router-Configs.
|
||||
- **Auslöser (Inventur 2026-08-27):** der Caddyfile (`bf-infra/caddy/Caddyfile`) ist heute **manuell gepflegt** — kein Drift-Check, keine Transaktionen, andere Projekte können keine Sites anlegen ohne Christoph. Lösung: **Nautobot/GC**, kein Caddy-API-Sidecar (kein zweites SSoT).
|
||||
- **Erster Anwendungsfall:** `terpene.teilzeitladen.xyz → http://10.40.20.167:8890` (Mac-mini-Backend, dort PostgREST + sync + web via lokalem Caddy `:8890`). Vor TP34: manueller Quick-Win-Caddy-Block.
|
||||
- **Abh.:** TP22 (GC-Pipeline) ✅ · TP23 (DNS/Caddy-Voraussetzungen) ✅ Stufe 1 · 🔴 **NEU 2026-09-06: TP37 Punkt 1+2** — Caddy rendert *Config aus Daten*, die Backend-Dienste müssen als `ipam.Service` in Nautobot existieren, sonst gibt es nichts zu rendern. **TP37 vor TP34.**
|
||||
- **Datenmodell (entschieden 2026-09-06):** native Modelle — Backend = `ipam.Service`, Proxy-Route = Relationship/CustomField Frontend↔Backend, GC-Job rendert den Caddyfile. Keine eigene App (konsistent zu TP44).
|
||||
- **Status:** 🔜 Stub; wartet auf TP37 P1+2. Quick-Win `terpene.teilzeitladen.xyz → 10.40.20.167:8890` als manueller Caddy-Block ist **Schritt 0** des Runbooks. Plan: [`handoff-20260906-tp37-34-36-plan.md`](handoff-20260906-tp37-34-36-plan.md).
|
||||
|
||||
---
|
||||
|
||||
<a id="tp44"></a>
|
||||
### TP44 — Cloudflare-Estate als Dokumentations-SSoT in Nautobot ▸ ✅ **DURCH (2026-09-10): Etappe 1 + Etappe 2 (Teil A IPAM-Prefixe, Teil B Live-Sync als täglicher Nautobot-Job)**
|
||||
> **Entscheid (User, 2026-09-02):** die volle CF-Estate (Tunnel + WARP-Connector + VPC-Service +
|
||||
> Hyperdrive + Workers + alle Access-Apps) als strukturierte, abfragbare SSoT in Nautobot abbilden —
|
||||
> **etappenweise: manuell jetzt, Sync später.** Nautobot kann CF nicht steuern → „SSoT" heißt
|
||||
> **Dokumentations-SSoT; CF bleibt operativer Master.** Detail-Handoff:
|
||||
> [`handoff-20260902-cf-estate-nautobot-ssot.md`](handoff-20260902-cf-estate-nautobot-ssot.md).
|
||||
|
||||
- **Warum eigenes TP, nicht TP36:** TP36 ist eng auf `teilprojekte.md`-Live-Daten geschnitten; gleiche
|
||||
Idee (Nautobot als Doku-SSoT), andere Dimension. TP44 = nächste freie Nummer nach TP43.
|
||||
- **Modell (native `nautobot.cloud`, Nautobot 3.1.7 — keine eigene App):** `Manufacturer "Cloudflare"` →
|
||||
`CloudAccount` (`393c051f…`) → `CloudResourceType ×6` → `CloudNetwork ×4` (`bf-public`/`fm`/`terpene-db`/
|
||||
`bf-core-mesh`) + `CloudService ×14`; Service↔Tunnel über das Through-Modell
|
||||
`cloud-service-network-assignments` (3 Rows). IDs/Ports/Hostnames/Origins je Objekt in `extra_config`.
|
||||
- **Werkzeug:** `nautobot/tp44-cf-estate-seed.py` — idempotenter Seeder (Re-Run = 26/26 „existiert"),
|
||||
Datenstand inline (Live-CF-Inventur 2026-09-02). Token aus `docs/nas-vlan20/stacks/210-nautobot.yml`.
|
||||
- ✅ **Verifikation 2026-09-06 (live gegen die API):** CloudAccount 1 · ResourceType 6 · CloudNetwork 4 ·
|
||||
CloudService 14 — unverändert seit 09-02.
|
||||
- 🔴 **Gotchas:** `CloudService.cloud_networks` ist `read_only` (nur Through-Rows schreiben/lesen) ·
|
||||
VPC-Service-API unter `connectivity/directory/services` (PUT, voller Body) · **VPC-Objekte tragen ihren
|
||||
Identifier in `service_id`, NICHT `id`** (kostete im Sync einen Fehl-Match) · ⚠️ **DRIFT-KORREKTUR
|
||||
2026-09-10:** die frühere Zeile „Repo-`CF_API_TOKEN` darf kein Workers-VPC → über den `cloudflare`-MCP"
|
||||
war **falsch**. Live getestet liest der `CF_API_TOKEN` aus `~/.secrets/credentials.env` Hyperdrive **und**
|
||||
VPC **und** Workers (alle 200). Der schmale Token ist `CF_DNS_API_TOKEN` (403). Der `cloudflare`-MCP ist
|
||||
der **remote OAuth-MCP** (kein API-Token) und für einen serverseitigen Job ohnehin nicht nutzbar.
|
||||
- ✅ **Etappe 2 Teil A (2026-09-08): IPAM-Prefixe live.** `10.40.0.0/16` (container, Route `bf-core-mesh`) +
|
||||
`10.101.0.0/24` (network, Route `fm`) angelegt via `nautobot/tp44-ipam-prefixes.py`; der Seeder-Re-Run
|
||||
hat die zwei `cloud-network-prefix-assignments` eingehängt (count=2, Idempotenz-Gegenprobe grün).
|
||||
- ✅ **Etappe 2 Teil B (2026-09-10): Live-Sync als Nautobot-Job — DURCH.** Governance (User 2026-09-09):
|
||||
periodische externe→Nautobot-Syncs leben als **Nautobot-Jobs** in `bf-infra/jobs/`, in Nautobot geplant —
|
||||
**kein per-Task-Container/-Cron.** Runtime `jobs/cf_estate_sync.py` (`CFEstateSync`, ORM, read-only Pull,
|
||||
403-tolerant, Verwaisung = `extra_config.stale` statt Löschen). Token = Nautobot-Secret `cf-api-token`
|
||||
(Provider env → `CF_API_TOKEN` am Worker, in `210-nautobot.yml` verdrahtet). **Schedule: täglich 03:00Z**
|
||||
(`ScheduledJob "CF Estate Sync – taeglich"`). Verifiziert: Dry-Run + Commit-Run sauber, **4 Networks /
|
||||
14 Services, alle Endpoints lesbar, 0 Drift**. Der REST-Einmalproof `nautobot/tp44-cf-sync.py` bleibt als
|
||||
workstation-seitiges Diagnose-Werkzeug liegen (nicht die kanonische Runtime).
|
||||
- 🔴 **Drei load-bearing Funde (Detail-Handoff `handoff-20260910-tp44-teilb-sync-live.md`):**
|
||||
(1) **Wurzel-`__init__.py` im Repo ist Pflicht** — Nautobot lädt Git-Repo-Jobs via
|
||||
`pkgutil.walk_packages([GIT_ROOT])`, das Namespace-Packages (ohne `__init__.py`) NICHT entdeckt; ohne die
|
||||
Datei bleibt `bf_infra.jobs` unsichtbar (Symptom: Sync SUCCESS + „No jobs were registered"). bf-infra ist
|
||||
das erste Git-Repo mit `extras.job`. (2) `register_jobs()` gehört ins **Paket-`__init__`**, nicht nur ins
|
||||
Submodul. (3) `Meta.has_sensitive_variables=False` nötig, sonst verweigert Nautobot das Scheduling.
|
||||
- **Beziehung zu TP37:** TP44 hat **TP37 Punkt 3** (CF-Connectoren) vorweggenommen — dieselbe native-Modell-
|
||||
Linie, die TP37 P1+2 (Substrat/Dienste) fortsetzt.
|
||||
|
||||
### TP41 — CF-Access-Reparatur + Zero-Trust-Konsolidierung ▸ ✅ **ABGESCHLOSSEN (2026-09-10)** — Auth-Kern seit 2026-09-01 komplett; **Gelis WARP-Client am 2026-09-10 via Android erfolgreich eingerichtet** (letzter Blocker weg, User-Bestätigung). Optionale Restpunkte (T6 Rate-Limit, geli-CGNAT-Policy-Cleanup) bewusst nicht gezogen; Keystore-Rotation läuft unter TP30 #7.
|
||||
|
||||
**Auslöser:** CF-Access zwang Christoph **und Geli** täglich zum OTP-Login (soll: 30 Tage); GitHub/Google
|
||||
„funktionieren nicht". Root-Causes: Team-Domain-Rename `bf4`→`emsenhuber` (Provider-Callback veraltet),
|
||||
App-Session 24h, diverse Ordnungs-/Sicherheitslecks. Vollständiger Verlauf + offene Schritte:
|
||||
**[`docs/handoff-20260901-tp41.md`](handoff-20260901-tp41.md)**. Branch `tp41-cf-access-repair`.
|
||||
|
||||
**✅ Live erledigt:** Session 720h (Wildcard/vw/Warp-Login) · login_method-Loch zu (reusable Policy
|
||||
`bf-users` = nur `email:christoph`+`email:geli`) · `8e44f5d1` von 4 Apps auf **nur Terpenfinder**
|
||||
entkoppelt · Access-**Gruppen** `zt-humans`/`zt-home`/`zt-automation`, Policies zeigen darauf · **vw voll
|
||||
Bypass** (Lebensader offen) + **`vw/admin` per WAF-Regel öffentlich geblockt** (CF-Edge + Mobilfunk
|
||||
verifiziert) · API-Token auf das vollständige `…4148` konsolidiert (User hat Service-Tokens- + Zero-Trust-
|
||||
Write ergänzt), altes `…2174` revoken.
|
||||
|
||||
**✅ T4 DURCH (2026-09-01, Variante B):** ein Access-Service-Token **`zt-svc`** (`65f1821a`, rotiert) über
|
||||
Gruppe `zt-automation`; Terpene-Worker per `wrangler secret put TERPENE_SVC_CLIENT_ID` auf zt-svc
|
||||
umgestellt (Worker-Pin `index.js:44`); `terpene-verify`+`-v2` **gelöscht**; `test_whoami` grün.
|
||||
**Token-Altlast geklärt:** `b00722` = LIVE Caddy-DNS-Token (LXC130 caddy.env, SSoT), `d47435` = stale
|
||||
Kopie (kein Consumer) → **User revoket `d47435`**; `credentials.env`-Kopie auf b00722 realignt.
|
||||
|
||||
**✅ T3 APPLIED (2026-09-01):** Default-Profil (`0197d1b3`; das custom „Cloudflare Mesh" matcht nur den
|
||||
`warp_connector`) `fallback_domains += emsenhuber.net → [10.40.20.36, 10.40.20.37]`; Tunnel-Route
|
||||
`10.40.0.0/16` (`d1da7c8a`) da, kein `10/8`-Exclude → routbar. ⏳ Client-Verify: WARP neu verbinden.
|
||||
**✅ T2 DURCH (2026-09-01):** WAF-Regel `f26744eb` gelöscht; Caddy `vw`-Block `respond @cf_admin 404` bei
|
||||
Header `CF-Connecting-IP` (LXC130). Verify: Edge `/admin`=404, lokal/WARP `/admin`=200. ✅
|
||||
|
||||
**✅ T5 DURCH (2026-09-01, User-bestätigt):** GitHub-Login läuft; Google-Login läuft nach dem
|
||||
Consent-Screen-Fix (§A des Follow-up-Handoffs: User Type *Internal*→*External*/veröffentlicht).
|
||||
Callback für beide `https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback`.
|
||||
**❌ Facebook/Meta für TP41 abgesagt (2026-09-01, User-Entscheid):** optional, kein Bedarf — Geli ist
|
||||
über OTP `angelikahy@outlook.de` + Google `pillepalle670@gmail.com` voll gedeckt. **Keine Facebook-App,
|
||||
kein CF-Facebook-IdP angelegt → nichts aufzuräumen.** Instagram hat ohnehin keinen CF-IdP.
|
||||
**✅ App-Launcher (D1):** je eine Bookmark-Kachel vw/hass/terpenfinder, Wildcard-Kachel raus, Launcher
|
||||
gestylt (Follow-up-Handoff §D, Policies unverändert).
|
||||
|
||||
**✅ Geli in WARP — CF-seitig nichts zu tun (2026-09-01 live geprüft):** Device-Enrollment läuft über
|
||||
die App **„Warp Login App"** (`6c32fe23…`, type `warp`) → Policy `bf-users` → Gruppe **`zt-humans`**, die
|
||||
Gelis beide Mails **schon enthält** → sie **darf bereits enrollen** (deshalb war „Device enrollment
|
||||
permissions" nicht als fehlendes Setting zu finden). Terpenfinder-`geli`-Policy lässt sie per E-Mail durch.
|
||||
✅ **Client am 2026-09-10 via Android erfolgreich eingerichtet** (WARP installiert, Team `emsenhuber`,
|
||||
Login OTP `angelikahy@outlook.de` — User-Bestätigung); damit ist der einzige verbliebene Handgriff erledigt.
|
||||
🔑 **Permission-Frage beantwortet:** CF-seitig **keine** nötig. Für generelle WARP/Enrollment/User-Verwaltung
|
||||
per Account-Token: *Access: Apps and Policies → Edit* + *Access: Organizations, IdPs, and Groups → Edit*
|
||||
(User erteilt 2026-09-01). **Seat-Verwaltung (`/access/seats`) bleibt per MCP gesperrt** — `10405 Method
|
||||
not allowed for this authentication scheme` (Endpoint will User-Token, nicht Account-Token; kein Scope-Fix,
|
||||
für Enroll irrelevant).
|
||||
|
||||
**🔻 Optionale Restpunkte (bewusst nicht gezogen, kein Blocker):** **T6** optional Rate-Limit ·
|
||||
🔴 `TERPENE_ANDROID_KEYSTORE_PW`-Rotation (→ **TP30 Posten #7**, Transkript-Leak) · **Security-Cleanup:**
|
||||
die `geli`-Terpenfinder-Policy hat **OR-Semantik** und enthält den breiten CGNAT-Bereich
|
||||
`94.154.138.0/24` als IP-Include → jeder aus dieser geteilten Range käme **ohne Login** rein. Über WARP ist
|
||||
der Egress ohnehin Cloudflare (nicht diese IP) → der IP-Include wäre dann überflüssig und entfernbar.
|
||||
**d47435-Revoke ✅ · T3-WARP-Client-Verify ✅** (User, 2026-09-01).
|
||||
|
||||
**Abgrenzung:** hass/gitea bleiben (diese Runde) öffentlich; Terpenfinder-Human-Policies nicht angefasst;
|
||||
**Gitea-Least-Privilege** = eigener künftiger TP (jedes Projekt repo-scoped Login, Admin nur Claude/Christoph).
|
||||
- Bezug **TP11** (Monitoring): eine Plattenfüllstand-Warnung hätte das Wochen früher gezeigt.
|
||||
|
||||
### TP43 — dw-Standort-DNS-Uplink (site-spezifische Overrides) ▸ ♻️ **REOPENED 2026-09-11 → Volltext zurück in [`teilprojekte.md`](teilprojekte.md) (Abschnitt TP43)**
|
||||
|
||||
Kurz zwischen 2026-09-11 verworfen und am selben Tag reopened: die 420-Prämisse war gegenstandslos
|
||||
(public CF-Worker, via WARP/TP41 gelöst), aber die **interne** BF-Namensauflösung über WG am dw blieb
|
||||
dabei offen (`portainer.bf.emsenhuber.net` am dw nicht erreichbar). Korrigierter Scope + verworfene
|
||||
420-Historie stehen jetzt aktiv in `teilprojekte.md`. Gitea-Issue #32 = `status:todo` · `thema:firewall-dns`.
|
||||
|
||||
### TP42 — Namens-Vereinheitlichung: ein interner Suffix bf.emsenhuber.net ▸ ✅ **DURCH (2026-09-02)** — ein interner Suffix `bf.emsenhuber.net`, `.bf.lan` raus, `.16` (adguard_bf1) abgebaut, Compliance 140/140. Offen nur der an **TP37** gekoppelte Nautobot-Doku-Teil.
|
||||
|
||||
**Auslöser (2026-09-01, TP41-Randbefund):** live gemessen liefern die realen Client-Resolver
|
||||
`10.40.20.36`/`.37` `*.emsenhuber.net → 10.40.20.40` (Caddy) — korrekt. Daneben existiert aber ein
|
||||
zweiter, gedrifteter interner Namensraum: der **Core** trägt in `/ip dns static` 11 Einträge auf
|
||||
`*.bf.lan`, der **Caddyfile** doppelt jeden internen Namen als `*.bf.emsenhuber.net`, und die alten
|
||||
AdGuard `.16`/`.17` antworten noch mit `nginx*.bf.emsenhuber.net` bzw. totem VLAN1 `10.40.41.123`.
|
||||
Christoph: „aus emsenhuber.net wurde schon wieder bf.lan — das müssen wir ein für alle mal aus allen
|
||||
Geräten rausprügeln und in Nautobot festhalten."
|
||||
|
||||
**Ziel:** genau **ein** interner Namensraum `emsenhuber.net` (Split-Horizon `.36/.37 → .40`). `.bf.lan`
|
||||
und `.bf.emsenhuber.net` werden entfernt; Sollzustand in Nautobot dokumentiert.
|
||||
|
||||
**Scope (Reihenfolge = eigene Session):**
|
||||
1. **Bestandsaufnahme** aller Fundstellen: Core `/ip dns static` (`*.bf.lan`), DHCP-Option
|
||||
`domain`/Search-Domain je Netz, Caddyfile-Aliase (`*.bf.emsenhuber.net`), AdGuard-Rewrites `.36/.37`,
|
||||
stale `.16/.17`, Geräte-`identity`.
|
||||
2. **Entscheidung Zielschema** (nur `emsenhuber.net`, ggf. `bf.emsenhuber.net` als *einzige* interne
|
||||
Zone — Christoph-Entscheid) und Migrationsreihenfolge ohne DNS-Loch.
|
||||
3. **Umsetzen:** Core-DNS + DHCP + Caddyfile angleichen; stale `.16/.17` klären/abbauen.
|
||||
4. **Nautobot:** interne Namen/Records als Sollzustand erfassen (Bezug TP37 Datenmodell).
|
||||
|
||||
**Abgrenzung:** kein CF-Public-DNS-Umbau (Zone `emsenhuber.net` öffentlich bleibt); kein Resolver-Swap
|
||||
(`.36/.37` bleiben); `.1`-als-DNS-Reste auf Clients sind separat/tolerierbar (User: „bis jetzt kein
|
||||
Problem"). **Abh.:** TP37 (Nautobot-Datenmodell) für Punkt 4; sonst nichts Offenes.
|
||||
|
||||
#### ✅ Bestandsaufnahme LIVE (2026-09-02) — Drift hat 80 % schon erledigt
|
||||
Gegen die Geräte gemessen (MikroMCP + dig), nicht aus dem Handoff:
|
||||
|
||||
| Fundstelle | Handoff 09-01 | Live 09-02 |
|
||||
|---|---|---|
|
||||
| Core `/ip dns static` | 11× `*.bf.lan` | ✅ **0× `.bf.lan`** — 10× `*.bf.emsenhuber.net` (deckt sich mit GC-Template Z.284–293) |
|
||||
| DHCP `domain` (7 Netze) | „prüfen" | `emsenhuber.net` (GC-Template Z.133 = gleich ⇒ **keine Drift**), DNS `.36/.37` |
|
||||
| `.36/.37` (Soll) | aktiv | `vw.emsenhuber.net→.40` ✅ · `macmini.bf.emsenhuber.net→.20.167` ✅ · **`macmini.emsenhuber.net→leer`** ❌ |
|
||||
| Caddyfile | `*.bf.emsenhuber.net`-Aliase | unverändert, **konsistent** mit Core-Static |
|
||||
| `.16`/`.17` | tot | laufen (:53), liefern totes VLAN1; **kein Core-Objekt** (Firewall/NAT/DNS-Upstream/Addr-List) hängt an `.16` |
|
||||
|
||||
**Kernkonflikt:** DHCP verteilt `emsenhuber.net` (bare), Records leben unter `bf.emsenhuber.net` ⇒ bare `macmini` löst nicht.
|
||||
|
||||
#### ✅ Entscheidungen (User, 2026-09-02)
|
||||
1. **Zielschema = `bf.emsenhuber.net`** (der wenig-Arbeit-Weg): DHCP-domain → `bf.emsenhuber.net`, dann
|
||||
löst `macmini` bare korrekt; Core-Static + Caddyfile bleiben (tragen schon `.bf.`). Öffentliche Zone
|
||||
`emsenhuber.net` bleibt getrennt.
|
||||
2. **`.16` (adguard_bf1) abbauen**, **`.17` (adguard_fm2 = Standort FM) NICHT anfassen.**
|
||||
|
||||
#### ✅ Umsetzung DURCH (2026-09-02)
|
||||
- **(A) DHCP-domain `emsenhuber.net → bf.emsenhuber.net` über GC ✅** — kein Direkt-Write:
|
||||
`mikrotik_routeros.j2` Z.133 gehoben → `push-gc-template.py` (Commit `7a4068c4`, **Nebenbefund:** das
|
||||
Remote-Template hing dem lokalen hinterher — es trug noch `*.bf.lan`+`router.lan`, obwohl Gerät+lokal
|
||||
längst `.bf.emsenhuber.net` fuhren; der Push hat das GC-Repo an den Live-Stand angeglichen) →
|
||||
GitRepo-Sync (SUCCESS) → manueller ConfigPlan **`tp42-dhcp-domain`** (`set [find] domain=…`, weil
|
||||
`add` das Netz doppelt anlegen würde) → Deploy an **crs326-core** → Live **7/7 = bf.emsenhuber.net**,
|
||||
Compliance **140/140, keine Drifts**. Der Job steht dauerhaft in `nautobot/gc-configplan.py`.
|
||||
- **(B) `.16`-Teardown ✅** — `adguard_bf1` lag im geteilten Portainer-Stack **195 `adguard`** (Docker-LXC
|
||||
`.126`, **ep2** — *nicht* ep14) **zusammen mit `adguard_fm2` (`.17`, Standort FM!)**. Deshalb **nicht**
|
||||
Stack löschen, sondern compose auf nur `.17` getrimmt + Stack redeployt (Prune): `.16`-Container weg,
|
||||
`.16:53` tot; **`.17` läuft** (⚠️ ~40 s mit-neugestartet durch den Redeploy — kurzer FM-DNS-Blip,
|
||||
danach sauber). Rollback-compose gesichert. 🧹 Daten-Dirs `/opt/docker/adguard_bf1/*` bleiben als
|
||||
harmlose Leichen auf dem LXC.
|
||||
- **(C) Nautobot-Soll** (Scope-Punkt 4) bleibt an **TP37** gekoppelt (Datenmodell), separat — kein Blocker.
|
||||
|
||||
**Status:** ✅ **Namensraum vereinheitlicht (2026-09-02)** — ein interner Suffix `bf.emsenhuber.net`,
|
||||
`.bf.lan` raus, `.16` abgebaut, Compliance 140/140. Offen nur der TP37-gekoppelte Nautobot-Doku-Teil.
|
||||
Handoff: [`docs/handoff-20260901-tp42-naming.md`](handoff-20260901-tp42-naming.md).
|
||||
|
||||
@@ -25,209 +25,24 @@ IP-Blöcke: `.1–10` Router/Gateways · `.11–20` Switches/APs. **GW je VLAN =
|
||||
Mgmt (VLAN99, Ist 2026-08-16): core `.99.1` · branch `.99.2` · ap1 `.99.11` · ap2 `.99.12`.
|
||||
*(Historisch, überholt: „ap1=.1, ap2=.2 · ALLNET=.11, Omada=.12" — aus der Zeit vor dem Core-Cutover.)*
|
||||
|
||||
## Ist-Stand (Kurz)
|
||||
## Status & Index → Gitea-Board (SSoT seit 2026-09-07, TP36-Cutover)
|
||||
|
||||
**Stand 2026-08-28 — live gegen die Geräte geprüft (MikroMCP/REST), nicht aus der Doku abgeschrieben.**
|
||||
**Die Compliance-Zeile unten ist am 2026-08-23 gegen die Nautobot-API nachgezogen.**
|
||||
*(Die Fassung vom 2026-08-16 stand bis zum 18. hier und war an vier Stellen überholt. Wer diesen Block
|
||||
liest, liest ihn als Erstes: er wird bei jeder Änderung mitgezogen, nicht nur die TP-Abschnitte.)*
|
||||
- 🆕 **MCP-Bestand 2026-08-28 korrigiert:** **9 MCPs identisch** in `~/.claude.json` und `~/.config/opencode/opencode.jsonc` (vorher Asymmetrie 7 vs. 11 — `portainer-mcp`/`shelly-mcp` raus, `gitea-mcp`/`n8n-mcp` rein). **Mac mini = n8n-Host, NICHT zentraler MCP-Host** (Performance-Restriktion); zentraler MCP-Host = **DS923** (`nas-bf`, Portainer Endpoint 14). Inventur-Stand `mcp/INVENTORY.md` + Policy `docs/mcp-host-policy.md`.
|
||||
- 🆕 **MCP-Migration FQDN→IP (2026-08-29, TP35 Schicht 1):** `gitea-mcp` und `n8n-mcp` in `~/.config/opencode/opencode.jsonc` von CF-FQDN auf LAN-IP umgestellt — `gitea-mcp` → `http://10.40.20.167:3000/mcp` (macmini, **ohne** Bearer, intern), `n8n-mcp` → `http://10.40.20.167:3001/mcp` (mit `Bearer {env:N8N_MCP_BEARER}`). **Befund dabei:** der Handoff 1.2 nannte für gitea-mcp die falsche IP `.157:3000` (das ist die Gitea-Web-UI, `400 Invalid CSRF`); der echte gitea-mcp läuft auf `.167:3000` (`serverInfo: gitea-mcp 0.0.10`). `cloudflare`-MCP bleibt auf dem offiziellen FQDN (User-Direktive).
|
||||
- 🆕 **TP37 angelegt (2026-08-30, User-Okay):** Nautobot soll durchgehende Netzwerkdoku werden, erster
|
||||
Anwendungsfall die CF-Connectoren. 🔴 **Befund dabei, live gegen die API:** Nautobot kennt heute
|
||||
**nur die 8 Netzgeräte** (4 aktiv, 4 decommissioned) — `ipam.Service`, `CustomField`, `Relationship`,
|
||||
`VirtualMachine` und `Tag` sind **alle 0**, installiert ist nur `golden-config`. Kein Host, kein
|
||||
Container, kein Dienst ist erfasst. **TP37 ist damit zuerst eine Datenmodell-Frage** und liefert das
|
||||
Fundament, das **TP34** (Caddyfile via GC) und **TP36** (SSoT für diese Datei) ebenfalls brauchen —
|
||||
Reihenfolge: **TP37 vor TP34**.
|
||||
- 🆕 **CF-Public-Strang eingedampft (2026-08-30, TP16.3 grosser Schnitt):** **12 Hostnames** aus Ingress
|
||||
**und** DNS entfernt — `pve`/`portainer`/`pve-mcp`/`ha-mcp`/`ds-bf`/`ccu`/`iobroker`/`z2m25`/`pbs`
|
||||
plus die drei CF-Access-SSH-Ziele. Ingress: `bf-mm` 6→4, `bf-nas` 6→3, `bf-pve` 9→2. **Öffentlich
|
||||
bleiben nur `vw`/`hass`/`n8n`/`gitea`** (weiterhin HTTP 200). Intern unverändert über AdGuard→Caddy
|
||||
(9× HTTP 200). ✅ **Nachtrag 2026-08-30 (F1 durch): `gitea-mcp`/`n8n-mcp` sind jetzt AUCH
|
||||
geschnitten** — damit **14 Hostnames** gesamt und `bf-mm` **4→2** (nur noch `n8n` + Catch-all).
|
||||
Möglich wurde das, weil zuvor **12 MCP-Client-Configs** auf LAN-IP migriert wurden (nicht 10 wie
|
||||
geschätzt: zwei Worktree-Kopien in `bf-network-r6{,.opencode}` kamen dazu). 🔴 **`bf-public` hat weiterhin 0 Connectoren** — er gehört
|
||||
laut Entscheid auf **ap1/ap2**, dort fehlen aber `container`-Paket **und** `device-mode container=yes`
|
||||
(physische Bestätigung nötig). Bis dahin stehen `bf-mm`/`bf-nas`/`bf-pve` mit **6 Containern**.
|
||||
Backups: `docs/cf-backup/*-20260830-vor-tp16.3-schnitt.json`.
|
||||
- 🆕 **Globale Verhaltensregeln konsolidiert (2026-08-29, TP35 Schicht 3):** `~/.config/opencode/AGENTS.md` ist jetzt die **SSoT** für globale Verhaltensregeln (Secrets, VLAN-Schema, 5 Lessons, SoC, Übergabe-Mechanik, Mid-Action-Checkpoint, Commit-Hinweis, Backup-Guard). `~/.claude/CLAUDE.md` hält denselben Block als Claude-Code-Spiegelung mit Verweis auf die SSoT. opencode liest AGENTS.md mit Vorrang vor `~/.claude/CLAUDE.md`.
|
||||
|
||||
- **Alle fünf MikroTik laufen auf RouterOS 7.24.1** (🆕 **Angleichung am 2026-08-31 von Christoph
|
||||
selbst durchgezogen, TP27 damit erledigt** — ap2 08:56, core 14:36, ap1 14:50, branch 14:52;
|
||||
ap3 kam bereits so). Vorher: vier auf 7.24 (08-17), nur ap3 auf 7.24.1.
|
||||
- **L3 + WAN-Edge = `crs326-core`** (CRS326-24G-2S+, Technik UG): Routing, DHCP (7 Server,
|
||||
54 Reservierungen), DNS, NAT, **NTP-Server für den Standort** und der WG-Hub (TP10, Peers `fm`/`dw`)
|
||||
laufen hier. Mgmt-SVI **`10.40.99.1`** (vlan99), Gateway `.1` je VLAN. **WAN = `vlan100`** — DHCP-Client
|
||||
hält die öffentliche Liwest-IP **`90.146.33.177/24`** direkt vom Arris (Bridge-Mode) → kein Double-NAT.
|
||||
**DNS-Upstream = DoH zum CF-Gateway mit `verify-doh-cert=yes`** (TP23 Stufe 1 ✅ 08-18);
|
||||
`servers=1.1.1.1` steht nur noch als Bootstrap für den DoH-Hostnamen.
|
||||
- 🔥 **Die Firewall ist deny-by-default — in BEIDEN Ketten** (TP5 E3/E4 ✅ 08-18). `TP10-seal-lan` ist
|
||||
`disabled`; Mgmt-Input kommt nur noch aus VLAN10, von HA (`8728`), von Nautobot (`22`) und über
|
||||
`cf-mesh`. Ein neuer Dienst über eine VLAN-Grenze braucht ab jetzt eine explizite Regel.
|
||||
- **L2-Branch = `crs326-branch`** (Technik OG): reiner L2-Switch, Mgmt **`10.40.99.2`**,
|
||||
Uplink `ether1` → core `ether8`.
|
||||
- **WLAN = CAPsMAN auf dem Core** (TP28 ✅ 08-17, GC-Modell nachgezogen 08-18): ap1 **`10.40.99.11`**
|
||||
(an core `ether15`), ap2 **`10.40.99.12`** (an branch `ether24`), beide **reine CAPs** —
|
||||
`cap enabled=yes`, `discovery-interfaces=vlan99`. Die APs halten **keine eigene WLAN-Config** mehr;
|
||||
Kanäle, SSIDs, Security und Steering kommen vom Manager. 802.11r/k/v aktiv, `ft-over-ds=yes`.
|
||||
🆕 **Dritter AP `ap3` (cAP ax) ✅ LIVE seit 2026-08-30** (TP28 dafür wieder geöffnet):
|
||||
`10.40.99.13`, Uplink `ether1` → **core `ether21`** (Trunk), reiner CAP, **RouterOS 7.24.1**
|
||||
(🆕 **seit 2026-08-31 die ganze Flotte** — die frühere Versionsdifferenz ist aufgelöst). Kanäle
|
||||
**`5180/ax/Ce/I`** + **`2437/ax`** (ch6) nach dem TP25-Plan vom 2026-08-24, am Gerät nachgemessen.
|
||||
🔴 **ap1 ist funkstill** — es steht bis zu seinem Umzug ans Sideboard direkt neben ap3 und würde
|
||||
auf 5180 kollidieren; es hat deshalb bewusst **keine Provisioning-Regel** am Manager, bleibt aber
|
||||
erreichbar. Beim Umzug: ap1 → `5260/Ce` (Band B, DFS, **Frequenz-Liste statt Einzelwert**),
|
||||
ap2 → `5300/Ce`, Uplink ap1 → `core ether3`.
|
||||
**Compliance jetzt 130/130 / 0 Drifts über 5 Geräte** (vorher 104/104 über 4).
|
||||
- **SSDP-Relay** (TP7.1, **nachgebessert 08-25**): LXC **108 `mcast-relay`** auf pve, zweibeinig
|
||||
`10.40.10.21` (VLAN10) + `10.40.40.21` (VLAN40) — dafür trägt `core ether13` beide VLANs; mDNS macht
|
||||
weiterhin der Core. **Läuft seit 08-25 ohne `--ssdpUnicastAddr`** — die Flagge verwarf die M-SEARCH
|
||||
der App auf dem Weg nach VLAN40 (Messung: **0 Pakete `via eth1` gegen 308 `via eth0`** in 20 min,
|
||||
**0×** `Received SSDP Unicast` im ganzen Journal seit 08-18). Der Rückweg läuft jetzt **nativ geroutet**
|
||||
über die längst offene Regel `TP5: MEDIA->MAIN`; nachgemessen kommen `HTTP/1.1 200 OK` von
|
||||
`10.40.40.193/.195` an beiden MacBook-Beinen an. Unit liegt im Repo: **`mcast-relay/multicast-relay.service`**,
|
||||
Details als Gotcha in `CLAUDE.md`. ⚠️ **Der Fall hatte zwei unabhängige Ursachen** — nach der
|
||||
Relay-Reparatur suchte die **App** immer noch nicht (macOS-Local-Network-Gate stand auf „an" und
|
||||
griff nicht; Fix war Schalter aus/ein + Neustart, User-bestätigt 08-25). **Beide sind erledigt.**
|
||||
- **Reverse Proxy = `caddy-bf1`** (LXC 130 auf pve, **`10.40.20.40`**, TP31 ✅ Schritt 1–3 seit
|
||||
2026-08-25, **`hass` 400 behoben 2026-08-26, Split-Horizon seit 2026-08-26**): Caddy 2.11.4,
|
||||
**16 Sites** (4 public, 12 intern mit `.bf.`-Suffix), Zertifikate ausschliesslich
|
||||
per **DNS-01** mit einem eng geschnittenen `Zone:DNS:Edit`-Token (`CF_DNS_API_TOKEN`, **nicht** das
|
||||
account-weite). Abnahme über den Host-Header von einem zweiten Host: 11× 200, `nautobot` 302.
|
||||
Offen: Schritt 5–6 (Tunnel `bf-public`, Abbau).
|
||||
- **DNS/Resolver = AdGuard-Paar `agh-bf1`/`agh-bf2`** (LXC 110/111 auf pve, **`10.40.20.36`/`.37`**,
|
||||
TP23 Stufe 2 + TP31 Schritt 4 ✅ seit 2026-08-26): Upstream DoH zum CF-Gateway, conditional
|
||||
`[/bf.emsenhuber.net/] → 10.40.20.1`, 47 Rewrites (16 Service → Caddy `.20.40` + 10 Host-Namen
|
||||
mit `.bf.`-Suffix + alte suffixlose parallel). DHCP liefert `.36`/`.37` als DNS in allen 7 VLANs
|
||||
(`domain=emsenhuber.net`), Firewall forward UDP+TCP/53 auf beide. Der Core-Resolver (`10.40.X.1`)
|
||||
bleibt als Bootstrap unverändert (DoH, `allow-remote-requests=yes`, `mdns-repeat-ifaces`).
|
||||
- **Ausgebaut / gelöscht:** ALLNET-`sw1` und Omada-`sw2` sind **physisch weg** (2026-08-08 bzw. 2026-07-23,
|
||||
in Nautobot *Decommissioned*); Omada-Controller + `omada-mcp` gelöscht (2026-07-16); FritzBox 6660 raus
|
||||
seit 2026-07-01 (Liwest-Tausch auf Arris). **VLAN1 ist leer** (`/ip arp` auf `bridge` = 0 Einträge,
|
||||
08-18) — TP19 ist geschlossen; `cudy1` hängt stromlos an core `ether11`, physischer Ausbau ist hands-on.
|
||||
- 🆕 **WLAN-Logging persistent seit 2026-08-30 (TP25 Fund E):** `wireless` + `caps` gehen vom Core
|
||||
in den TP5-Kollektor (`10.40.20.18:514`); `/system logging` steht unter der **27. ComplianceRule**
|
||||
`system-logging`. Vorher nur Ringpuffer → ein seit Wochen gemeldeter iPhone-Abbruch war rückwirkend
|
||||
nicht diagnostizierbar.
|
||||
- 🔴 **TP25 Fund E — Hebel 1 ist GESCHEITERT (Stand 2026-08-31 nachmittags):** `sec-main` steht am
|
||||
Core auf **`ft=yes ft-over-ds=no`** (seit 08:09), aber das Symptom blieb: **124× `reauthenticating`
|
||||
nach dem Eingriff** und **zwei von Christoph erlebte Ausfälle** — 13:16 (Videocall bricht ab,
|
||||
7 min ohne WLAN) und 14:23 (5,5 min, nur durch WLAN-Toggle beendet). Stundenvergleich auf
|
||||
gleicher Firmware: **07:00–08:00 = 79 · 14:00–15:00 = 70**. Erfolgskriterium war „~0" ⇒ nicht
|
||||
eingetreten. Gewertet wird bewusst nur **08:09–14:36** (danach kommt das TP27-Upgrade als zweite
|
||||
Variable dazu; Christoph-Entscheid: „Vormittag als Ergebnis werten").
|
||||
⇒ Transaktion **`TP25-fund-e-ft-over-ds` bleibt OFFEN** (Ablauf **2026-09-03**), **Compliance
|
||||
weiter bewusst 134/135**; Rollback oder Commit ist eine Entscheidung, kein Aufräumen.
|
||||
Geräte-Backup `pre-tp25-funde-ftoverds.backup` liegt auf dem Core.
|
||||
**Nächste Entscheidung:** Hebel 2 (`ft=no`) **oder** `authentication-types=wpa2-psk,wpa3-psk` —
|
||||
`sec-main` ist auch die einzige SSID ohne `wpa2-psk`, und `association rejected, no cached PMK`
|
||||
(157× am 31.08., 0× am 30.08.) ist eine SAE/PMKSA-Meldung. **Vorher prüfen, ob 7.24.1 auf dem
|
||||
Manager das Verhalten schon verändert hat** — zwischen 14:37 und 15:12 stand nur **1**
|
||||
`reauthenticating` im Log, keines vom iPhone (35 min = noch keine Aussage).
|
||||
Details: [`handoff-20260831-tp27-upgrade-und-hebel1-befund.md`](handoff-20260831-tp27-upgrade-und-hebel1-befund.md).
|
||||
- ⚠️ **Messfalle, die diese Session fast erwischt hat:** die 13 CAP-`joined`/`activity timeout` vom
|
||||
31.08. sahen nach CAPWAP-Instabilität aus — es waren die **Reboots des TP27-Upgrades**. Und die
|
||||
**`cap-wifiN`-Karte hat sich an einem Tag zweimal verschoben** (08:09, 14:36), womit die im
|
||||
Vorgänger-Handoff festgehaltene Tabelle nach sechs Stunden falsch war. Interface-Namen in
|
||||
Logzeilen sind ohne zeitnahen Karten-Snapshot **nicht zuschreibbar**.
|
||||
- **Kontrolle / Governance:** MikroMCP für Reads/Debug (alle 5 Geräte in der Registry),
|
||||
**Config-Änderungen ausschließlich über Nautobot Golden Config** (TP21/TP22 — Deploy-Pipeline scharf,
|
||||
**135/135 Compliance-Checks grün, 0 Drifts** bei **27 Rules × 5 Geräten** (Stand 2026-08-30;
|
||||
**seit 2026-08-31 vorübergehend 134/135 — der eine Drift ist die offene Transaktion
|
||||
`TP25-fund-e-ft-over-ds`, s. oben, kein Fehler**) — live gegen die API
|
||||
geprüft am **2026-08-23**; zuletzt dazugekommen: **`wifi-access-list`** (08-22), **`queue`**
|
||||
(08-23, TP6) und **`ip-firewall-mangle`** (08-23, TP6.1), s. TP22-Nachtrag im Archiv).
|
||||
*(Hier stand bis zum 08-23 „100/100 bei 25 Rules" — eine Zählung, die TP6.1 am selben Tag überholt
|
||||
hat. Die Merkregel gilt: der Ist-Stand-Block wird bei jeder Änderung mitgezogen, nicht nur der TP.)*
|
||||
|
||||
<details><summary>📜 Historische Fassung (Stand bis 2026-08-08, Topologie <b>vor</b> dem Core-Cutover — bewusst erhalten, nicht als Ist lesen)</summary>
|
||||
|
||||
> ALLNET-Core `.11` (FW2.2.1, VLANs 10/20/30/40/50/90/99/100; GE1/GE2/GE8 Trunk; **TP1 ✅ 2026-06-15**). Omada-Switch `.12` (adopted, **TP2 ✅ 2026-06-15**; Trunk-ALL auf P1+P2, Access-Profile auf P3-P8; Profile noch PVID=1 bis Omada-PVID-Fix).
|
||||
> Omada-Controller **`.175`** (DS923/macvlan, mbentley 6.2, 🟢 live). omada-mcp **`.176`** (pve-LXC, StreamableHTTP, 🟢 live, 84 read-Tools; Controller-API v2 intern via christoph@emsenhuber.com).
|
||||
> 2× hAP ax² (7.23.1): ap1 `.1` (ALLNET P1) — **TP4 ✅ 2026-07-01: Router + WAN-Edge** (VLAN-Subinterfaces, DHCP, DNS, NAT, Public-Edge). ap2 `.2` (Omada P2 — Trunk).
|
||||
> **Edge-Cutover ✅ 2026-07-01:** FB6660 physisch entfernt (Liwest-Kabelmodemtausch, kein Zurück), Arris-Kabelmodem im Bridge-Mode; WAN = `sw1 gi16 Access VLAN100 → gi15 Trunk → ap1 ether2 → vlan100 auf bridge` (**NICHT** ether1); ap1 hält Public-IP direkt (Liwest, kein CGNAT), Double-NAT weg. Telefonie war auf der FB und wird nicht weitergeführt. Vorarbeit: TP10-Kern durch (2026-06-27, WG-Hub live) → Bridge-Gate vorher gelöst. Runbook: `routeros/wan-cutover-runbook.md`.
|
||||
> Kontrolle: MikroMCP (MikroTik) live · ALLNET = Klickanleitungen · Omada → Controller + omada-mcp 🟢.
|
||||
|
||||
</details>
|
||||
|
||||
**Nächster Schritt (Stand 2026-08-30): Vor-Ort-Session ap1/ap2** — sie ist der einzige Weg, den
|
||||
Public-Strang auf `bf-public` zu heben und die drei Alt-Tunnel samt sechs Containern abzubauen
|
||||
(TP16.3 Follow-up F2). ✅ **F1 ist am 2026-08-30 durch** (12 Client-Configs auf LAN-IP, danach
|
||||
`gitea-mcp`/`n8n-mcp` aus Ingress+DNS geschnitten) — davor unabhängig machbar bleibt nur noch die
|
||||
**Announcement-Doku (TP35 Schicht 4)**, die den anderen Projekten die neuen MCP-URLs mitteilt.
|
||||
|
||||
**Vorherige Fassung (Stand 2026-08-28): drei Folge-Sessions parallel** (siehe `docs/handoff-20260828-mcp-bestand-und-performance.md`):
|
||||
> - ✅ **Session A** — `/projektstatus`-Skill global für opencode (TP35 Schicht 6). Funktionsbeweis erbracht 2026-08-28.
|
||||
> - 🔜 **Session B** — shelly-mcp-Container auf DS923 (`10.40.20.10`) deployen (live, ssh). Repo-Materialien committed (`mcp/shelly/{Dockerfile,BUILD.md,requirements.txt,.gitignore}`); `.env` und Tunnel-Secret lokal — kein MCP-Client (User-Direktive).
|
||||
> - 🔜 **Session C** — `caddy/cf-sync.py`-Drift-Check + Backup-Guard (`~/dev/.bin/backup-guard.sh`, TP35 Schicht 5).
|
||||
> 🧭 **Ist-Stand, kritischer Pfad und Quick-Index leben ab jetzt als Gitea-Issues**, nicht mehr in
|
||||
> dieser Datei: **[admin/bf-infra · Issues](https://gitea.emsenhuber.net/admin/bf-infra/issues)**.
|
||||
> **TP = Issue · Status = Label `status:*`** (todo/wip/paused/idea/concept/done/dropped) ·
|
||||
> **Gruppierung = Label `thema:*`**. Filtern über die Label-Chips der Issue-Liste, z.B.
|
||||
> [nur offene](https://gitea.emsenhuber.net/admin/bf-infra/issues?type=issue&state=open).
|
||||
>
|
||||
> 🆕 **Strukturelle Folge = TP36:** SSoT für `teilprojekte.md`-Live-Daten via Nautobot (eigene Session, nicht heute). Befund 2026-08-28: manuell gepflegte Datei verliert gegen die Realität, sobald sie lang wird. Quickref-Index, TP-Abschnitt und Ist-Stand-Block müssen bei jedem Edit mitgezogen werden — keine schlägt die andere. **Merkregel im Lessons-Block.**
|
||||
|
||||
> 🆕 **Neu am 2026-08-24/25:** [TP31](#tp31) löst **TP16** und **TP16.2** ab und dampft cloudflared
|
||||
> von **sechs Containern auf einen** ein; [TP32](#tp32) gibt die Nummern- und Adress-Systematik vor
|
||||
> (und hat nebenbei die **falsche Startreihenfolge auf pve repariert** — HA startete vor seiner
|
||||
> Datenbank). **TP16 ✅, TP25 ✅ und TP16.3 (Pilot) ✅** sind am 24./25. durchgezogen worden.
|
||||
|
||||
**Vorherige Fassung (Stand 2026-08-23): Christoph entscheidet — der kritische Pfad ist LEER.**
|
||||
> 🎯 **Das Projekt ist in seinem Kern fertig.** deny-by-default steht (TP5), Golden Config steht und
|
||||
> meldet **104/104 compliant bei 0 Drifts** (live geprüft 2026-08-23), WLAN steht über CAPsMAN auf dem
|
||||
> Core (TP28), VLAN1 ist leer (TP19) — und **TP6 ist beantwortet statt offengelassen**: CAKE gebaut,
|
||||
> gemessen, wieder ausgebaut. **Nichts blockiert mehr etwas.**
|
||||
> 🟢 **Was zuletzt wirklich etwas gebracht hat, war TP6.1** (2026-08-23): nicht Shapen, sondern
|
||||
> **Klassentrennung** — NAS-Bulk `priority=8` gegen interaktiv `priority=1` drückt dieselbe Strecke
|
||||
> unter derselben Sättigung von **40,8 auf 11,0 ms (−73 %)**. Die zuerst notierte DOCSIS-Erklärung aus
|
||||
> TP6 ist damit **widerlegt**; der Fehler lag in der Messmethode (Last und Messung vom selben Host).
|
||||
> 📋 **Offen und ohne Blockadewirkung:** **TP25** (Fund F = 5:05-Takt bei IoT, plus die Entscheidung
|
||||
> „5 GHz auf 20 MHz") · **TP16** (CF-Tunnel-HA degradiert, vier tote Alt-Tunnel) · **TP16.2/16.3** ·
|
||||
> **TP23 Stufe 2** · **TP24** (DC-USV) · **TP13/TP14.4** (beide mit fertigem Runbook) ·
|
||||
> ❌ **TP17.1 VERWORFEN 2026-08-23** (Zigbee-Weg bewiesen, Ziel damit nicht erreichbar — das Gerät
|
||||
> bleibt WLAN-Client; `s9` zurückgebaut) · ✅ **TP17.3 ERLEDIGT** (Ursache **`eco_mode`** bewiesen;
|
||||
> `s23` + `s26` repariert; **`eco_mode` flottenweit aus**, 22/22 außer `s24`) ·
|
||||
> ➡️ **TP17.2 ist am 2026-08-24 in TP30 aufgegangen** (Shelly-Gerätepasswort = Erstvergabe eines
|
||||
> Credentials; TP30 ist das Sammelbecken dafür) ·
|
||||
> 🔑 **Alle Passwort-/Token-Rotationen sind seit 2026-08-24 TP30** (Sammel-TP) — **bewusst
|
||||
> gebündelt gegen Projektende**, User-Entscheid. Damit ist die ältere Einreihung „hinter TP17.1"
|
||||
> gegenstandslos (TP17.1 ist verworfen). **Etappe 1 — die Service-Accounts — ist durch;**
|
||||
> das `admin`-Passwort selbst ist **nicht rotiert** und bleibt es bis dahin bewusst.
|
||||
> 📌 **Einstieg für die nächste Session:
|
||||
> [`handoff-20260825-agh-dns-cutover.md`](handoff-20260825-agh-dns-cutover.md)** — AdGuard als
|
||||
> Resolver + Split-Horizon (TP23 Stufe 2 ∥ TP31 Schritt 4). **Bewusst eigene Session:** der Schritt
|
||||
> verschiebt die DNS-Auflösung des ganzen Standorts in einen Container.
|
||||
> 📜 Älter: [`handoff-20260824-session.md`](handoff-20260824-session.md)
|
||||
> — ⚠️ dessen Empfehlung „Start bei der Passwort-Rotation Etappe 2" ist durch den TP30-Entscheid
|
||||
> **überholt**; der Rest der Übergabe gilt. Ältere Sitzungsvorschläge:
|
||||
> [`handoff-20260822-naechste-schritte.md`](handoff-20260822-naechste-schritte.md).
|
||||
> ✅ **`crs326-core` ist transaktionsfrei** (seit 2026-08-22, geprüft): ein gemeldeter Drift ist ab
|
||||
> jetzt **echt**, nicht beabsichtigt — `python3 nautobot/gc-transaktion.py status`.
|
||||
|
||||
<details><summary>📜 Vorherige Fassungen dieses Absatzes (2026-07-22 → 2026-08-21, bewusst erhalten)</summary>
|
||||
|
||||
> *Fassung 2026-08-21 abends (erledigt — TP25s Dead Spot ist am 08-22 repariert, TP6 am 08-23 geschlossen):*
|
||||
> **Nächster Schritt: TP25 — Steering-Test in den Schlafräumen.**
|
||||
> 📋 **Einstieg: [`handoff-tp25-session-20260821.md`](handoff-tp25-session-20260821.md)** — dort steht
|
||||
> der verifizierte Ist-Stand, die Messfallen und der nächste Test.
|
||||
> ✅ **`crs326-core` ist transaktionsfrei (2026-08-22).** `TEST-ether3-trunk-ap1-sideboard` und
|
||||
> `TEST-infra-ssid-matter-pairing` sind beide zurückgerollt und geschlossen; ap1 hängt wieder auf
|
||||
> `ether15`, `ether3` ist wieder untagged VLAN40. Ein gemeldeter Drift ist ab jetzt **echt**, nicht
|
||||
> beabsichtigt — `python3 nautobot/gc-transaktion.py status`.
|
||||
> 🆕 **TP29** (Anwesenheitserkennung fürs Energiesparen) ist als Idee angelegt, nicht auf dem Pfad.
|
||||
> 📌 **Die TP6-Prämisse ist am 2026-08-20/21 gemessen** (Runbook §5): formal Fall B (+28…+47 ms unter
|
||||
> Dauer-Upload), aber im Videocall **nicht wahrnehmbar** — kein einziger Problem-Klick über sechs
|
||||
> Lastphasen. Laut war stattdessen der Funk: **Sticky Client + Band-Ping-Pong, zwölf Wechsel in neun
|
||||
> Minuten**, je Wechsel bis zu 4 s ohne Durchsatz →
|
||||
> [`tp25-wlan-roaming-messung-20260820.md`](tp25-wlan-roaming-messung-20260820.md). Deshalb steht jetzt
|
||||
> **TP25 vor TP6**; TP6 bleibt offen und begründet, aber nachrangig.
|
||||
> **Diese Datei führt nur noch die per-TP-Prosa** — die `### TPnn`-Abschnitte unten; Abgeschlossenes im
|
||||
> **[Archiv](teilprojekte-archiv.md)**. **Live-Gerätedaten** (Compliance-Zahl, RouterOS-Version …) kommen
|
||||
> aus **Nautobot**, nicht von hier. Sync-Werkzeug Datei/Archiv → Gitea (idempotent, Dry-Run default):
|
||||
> `bin/gitea-tp-sync.py`.
|
||||
>
|
||||
> *Vorherige Fassung (Stand 2026-08-18, erledigt):*
|
||||
TP6 wird hier seit Monaten als „DAS Ziel" geführt, aber `docs/call-quality-diagnosis.md` hat den
|
||||
Bufferbloat 2026-06-16 bereits gemessen (**A/A+**, „CAKE wäre marginal, nicht deployt"). Die Messung
|
||||
stammt aus der FritzBox-Ära, der Edge ist seither getauscht — also **einmal gegen den heutigen Edge
|
||||
nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Nacht auf den 18. abgeschlossen worden (Etappe 3 + 4: deny-by-default in `forward` **und** `input`, MGMT isoliert, `seal-lan` abgeschaltet), TP23 Stufe 1 (DoH auf dem Core) ebenfalls. Nebenher offen, blockiert nichts: **TP25** (Signal-Boden + Re-Walk), **TP28-Rest** (die fünf `wifi-*`-Features vom AP-Scope auf den Core umhängen — die einzigen verbliebenen Compliance-Drifts), **TP7.1** (SSDP-Relay für die macOS-Sonos-App), **TP16.3**, **TP24**.
|
||||
> *Vorherige Fassung (Stand 2026-08-14, überholt): „TP5 — Deny-by-default am Ende von `forward`." Alles Davorliegende ist durch:* CRS326-Bring-up + L3-Umzug ap1→`crs326-core` (TP15/TP21.1 ✅ 2026-08-08), WLAN-Neuprovisionierung ohne CAPsMAN (TP3 ✅ 2026-08-08), Nautobot-Plattform + Fleet-Adoption + Deploy-Pipeline (TP21/TP22 ✅ 2026-08-13). Danach **TP6 (CAKE) = das Projektziel**. Kleine Follow-ups nebenher: DoH-Cloudflare auf core, DC-USV (**TP24**, seit 2026-08-16 eigener TP). ⚪ **Omada-PVID-Fix ist obsolet** (User-Entscheid 2026-07-22 — Omada spielt seit der TP15-Korrektur keine Rolle mehr im Netz, nie mehr aufgreifen).
|
||||
> *Vorherige Fassung (Stand 2026-07-22, erledigt): „TP15 CRS326-Bring-up als neuer L3-Core, danach WLAN-Neuprovisionierung ohne CAPsMAN; TP5 folgt nach TP21/CRS326-Adoption."*
|
||||
> *(TP36-Cutover 2026-09-07: die frühere Quick-Index-Tabelle und der chronologische „Ist-Stand (Kurz)"-Block
|
||||
> sind aus dieser Datei entfernt, damit TP-Branches nicht mehr auf der Steuerungs-Doku kollidieren — Status-
|
||||
> Updates gehen nach Gitea statt in diese Datei. Die alte Ist-Stand-Historie steht in der Git-Historie.)*
|
||||
|
||||
</details>
|
||||
## Governance & genehmigte Ausnahmen (stehende Regeln — kein Status)
|
||||
|
||||
> 🎯 **Ziel: sauberes System „from scratch", keine Leichen/Altlasten.** Migrations-Session-Endstand = **VLAN1 + altes cudy-WLAN komplett weg** (VLAN1 nur noch Mgmt, `defconf`-Client-DHCP zurückgezogen, cudy-Uplinks aufs Ziel-Client-VLAN getaggt oder cudy abgebaut). **Unterpunkte/Aufräum-Liste bei Migration:** (a) die Interim-Härtung ap2 `wifi1/wifi2 frame-types=admit-only-vlan-tagged` (TP3.1, 2026-07-06) bleibt gültig — verschwindet automatisch mit VLAN1; (b) ~~`st-main rrm/wnm` = reines Roaming-Provisorium~~ → **kein Provisorium mehr (2026-08-13, TP3.3): Steering ist fester Bestandteil des Golden-Config-Templates + ComplianceFeature `wifi-steering`** — es war die Neuprovisionierung, die es stillschweigend verloren hatte; (c) ~~**cudy1 = verbleibender aktiver VLAN1-Leak**~~ → **ERLEDIGT (User-bestätigt + verifiziert 2026-08-14): cudy1 ist offline.** `core ether11` trägt **kein Link** (kein `R`-Flag), Nautobot-Status *Offline* (TP22 Schritt 5). Damit existiert kein aktiver VLAN1-Leak mehr; der Dual-DHCP-Race aus `project_vlan1_dhcp_incident` ist Historie. Der formale Teardown (Gerät ausbauen, Doku/Inventar) bleibt TP19.
|
||||
> ⚠️ **HW-Constraint hAP ax²:** 1 GB RAM, aber nur **128 MB Flash + KEIN USB** → **Container auf dem Router NICHT praktikabel**.
|
||||
@@ -252,38 +67,7 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
|
||||
> ~~**TP17.2** ↔ TP17~~ *(TP17.2 ist am 2026-08-24 in **TP30** aufgegangen und kein eigenes TP mehr)*
|
||||
> und **TP20.1** ↔ TP20).
|
||||
>
|
||||
> ### 📊 Quick-Index (nur dieser Block ist für den Statusbaum nˆtig — 1 Read)
|
||||
>
|
||||
> | # | Status | Kurztitel | Abschluss |
|
||||
> |---|---|---|---|
|
||||
> | TP5.1 | ⏸️ | DNS-Visibility Airfryer | — |
|
||||
> | TP8 | ⏸️ | Identity / 802.1X | — |
|
||||
> | TP11 | ⏸️ | Monitoring | — |
|
||||
> | TP12 | ⏸️ | IPv6 (3 Standorte) | — |
|
||||
> | TP12.1 | 🔜 | IPv6 ULA + v6-Firewall | — |
|
||||
> | TP13 | 🔜 | Botschafts-WLANs | — |
|
||||
> | TP14.4 | 🔜 | CF-Access-Token | — |
|
||||
> | TP16 | ✅ | CF-Tunnel HA wieder voll | 2026-08-24 |
|
||||
> | TP16.2 | 🔜 | Härtung bypass-Dienste | — |
|
||||
> | TP16.3 | ⏳ | cloudflared-Reduktion (14 Hostnames geschnitten 08-30, F1 durch; Abbau braucht Vor-Ort-Session) | — |
|
||||
> | TP17.1 | ❌ | Shelly Gen4 → Zigbee | 2026-08-23 |
|
||||
> | TP17.3 | ✅ | Shelly-Regression behoben | 2026-08-23 |
|
||||
> | TP18 | 🔜 | Garage-Objektspeicher | — |
|
||||
> | TP20.1 | 🔜 | Vaultwarden → Platform-PG | — |
|
||||
> | TP23 | ✅ | DNS-Policy (Stufe 1+2 ✅) | 2026-08-26 |
|
||||
> | TP24 | 🔜 | DC-USV | — |
|
||||
> | TP25 | 🔬 | WLAN-Stabilisierung (Kern ✅) — **Fund E offen, Hebel 1 `ft-over-ds=no` läuft, Messung bis 09-01** | 2026-08-31 |
|
||||
> | TP28 | ✅ | WLAN/CAPsMAN — dritter AP `ap3` (cAP ax) **live** | 2026-08-30 |
|
||||
> | TP29 | 💡 | Anwesenheitserkennung (Idee) | — |
|
||||
> | TP30 | 🔜 | Credentials (Etappe 1 ✅, Rest gebündelt) | — |
|
||||
> | TP31 | ✅ | Reverse Proxy Caddy (Schritt 1–4 ✅) | — |
|
||||
> | TP32 | 🟢 | Nummern-Systematik (Konzept) | — |
|
||||
> | TP33 | 💡 | Sonos fern (Idee, zurückgestellt) | — |
|
||||
> | TP34 | 🔜 | Caddyfile via Nautobot/GC (Stub, Inventur-Handoff 2026-08-27) | — |
|
||||
> | TP35 | ⏳ | MCP-Schichtung + 3-Schicht-CLAUDE.md + Backup-Guard (Schicht 1+3+6 ✅) | — |
|
||||
> | TP36 | 🔜 | SSoT via Nautobot für teilprojekte.md-Live-Daten + Datei-Aufteilung | — |
|
||||
> | TP37 | 🔜 | Nautobot als Netzwerkdoku: Hosts/Container/Dienste + CF-Connectoren (Okay 08-30) | — |
|
||||
> | — | — | **34 archivierte TPs** in `teilprojekte-archiv.md` | — |
|
||||
> 📊 **Index/Statustabelle → [Gitea-Board](https://gitea.emsenhuber.net/admin/bf-infra/issues)** (siehe Kopf dieser Datei). Hier unten folgt nur noch die per-TP-Prosa.
|
||||
|
||||
### TP5.1 — DNS-Visibility & Flow-Observability für Low-Trust-Geräte (Airfryer-Fall) ▸ vorgemerkt
|
||||
- **Kontext (2026-07-08/09):** Airfryer „airschreier" (Philips/Versuni, ESP, `10.40.30.180`) bekam per DHCP-Option 6 `dns 1.1.1.1` als Override, weil das OTA-Update über den ap1-DoH-Gateway-Pfad nicht durchging (DoH-Latenz beim primitiven ESP-Stack — **kein** Content-Block, via Gateway-Logs bewiesen, s. `memory/ref_esp_ota_doh_not_block`). Nebenwirkung: public **1.1.1.1 = anonymer Consumer-Resolver ≠ accountgebundener Gateway-DoH** (`px35ynlol3.cloudflare-gateway.com`) → **DNS-Sicht auf das Gerät weg**, Gerät umgeht zudem die Filterung.
|
||||
@@ -401,11 +185,15 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
|
||||
- ⚠️ **Recht vor Scharfschalten prüfen (User privat, AT):** offenes WLAN + Portal berührt Impressumspflicht/Störerhaftung — **reine Namens-SSIDs ohne offenen Zugang sind unkritisch** (kein Fremd-Datenverkehr); im Zweifel nur die Beacon-Variante.
|
||||
- **Abh.:** ~~TP3-Rebuild ✅ (Standalone-APs — SSID-Änderung = 1 Deploy/GC-Job)~~ → **TP28 ✅** (CAPsMAN auf dem Core) + **TP22 ✅** (GC-Deploy-Pipeline). SSID-Änderung = **ein** Deploy auf den Core; Direkt-Edit am Gerät ist durch den Governance-Entscheid ausgeschlossen.
|
||||
|
||||
### TP14.4 — Session D: CF-Access-Profil für Claude ▸ 🔜 **AUSFÜHRBAR (Runbook 2026-08-19)** — `docs/tp14.4-cf-access-token-runbook.md` · nicht cutoff-kritisch
|
||||
> 📌 Ist-Stand geprüft: in `mcp/cloudflare/.env` stehen **weder** `CF_ACCESS_CLIENT_ID` **noch** `_SECRET` —
|
||||
> es ist also nichts halb erledigt. ⚠️ Das Secret existiert **nur im Moment der Rotation**.
|
||||
> Abnahme braucht **beide** Fälle (mit Headern antwortet / ohne Header 403), sonst ginge ein
|
||||
> bypass-Hostname wie `vw` fälschlich als Erfolg durch. Kein CF-Write erfolgt.
|
||||
### TP14.4 — Session D: CF-Access-Profil für Claude ▸ ✅ **IN TP41 T4 AUFGEGANGEN (2026-09-01)** — `docs/tp14.4-cf-access-token-runbook.md` (historisch)
|
||||
> ✅ **Erledigt über TP41 T4 (2026-09-01), nicht als eigenständiger `claude-mcp`-Token:** der
|
||||
> `claude-mcp`-Service-Token war die Basis (`t4a.py`), wurde **→ `zt-svc` umbenannt + rotiert** und über
|
||||
> Gruppe `zt-automation` konsolidiert. `mcp/cloudflare/.env` trägt jetzt **beide** Keys
|
||||
> `CF_ACCESS_CLIENT_ID`/`CF_ACCESS_CLIENT_SECRET` (Block „TP41 T4 zt-svc"), verifiziert
|
||||
> (`test_whoami.py` → `admin:true`, `common_name=zt-svc`). Handoff: [`handoff-20260901-tp41.md`](handoff-20260901-tp41.md) §T4.
|
||||
> 📌 *Überholt (Ist-Stand vor 09-01, bewusst erhalten):* „in `mcp/cloudflare/.env` stehen weder
|
||||
> `CF_ACCESS_CLIENT_ID` noch `_SECRET` — nichts halb erledigt." Das war bis zum 2026-09-01 richtig;
|
||||
> TP41 T4 hat die Keys dann geschrieben. Abnahme-Regel bleibt gültig (mit Headern antwortet / ohne 403).
|
||||
- CF-Token „claude code mcp" hat jetzt `Access: Service Tokens: Write`+`Read` → `claude-mcp` rotieren (`POST …/access/service_tokens/{id}/rotate`) → `CF_ACCESS_CLIENT_ID`/`_SECRET` in `mcp/cloudflare/.env` (chmod600). Memory `ref-cf-access-claude-profile`.
|
||||
- 📋 **Runbook: `docs/tp14.4-cf-access-token-runbook.md`** (2026-08-19). **Ist-Stand verifiziert:**
|
||||
`mcp/cloudflare/.env` enthält bisher weder `CF_ACCESS_CLIENT_ID` noch `_SECRET` — es ist nichts halb
|
||||
@@ -475,7 +263,70 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
|
||||
- **Reihenfolge:** (1) Client-IP-Weitergabe fixen (inkl. HA `trusted_proxies`) → (2) `/admin`-Pfade path-scoped schützen → (3) App-Limits + 2FA → (4) Edge-Rules → (5) CrowdSec/fail2ban mit CF-Bouncer.
|
||||
- **Abh.:** TP16 ✅ (Tunnel-HA). Verwandt: **TP20.1** (vw wandert auf Platform-Postgres — DB-HA ≠ Access, getrennt halten), **TP23** (dessen WARP-Managed-Network-Idee ist durch diesen Constraint **entlastet**: `vw` verlangt keine Device-Identity, also kollidiert „WARP zuhause aus" nicht mehr mit dem Access-Strang).
|
||||
|
||||
### TP16.3 — cloudflared-Reduktion: was der Mesh als Datenpfad kann (und was nicht) ▸ ⏳ **GROSSER SCHNITT DURCH (2026-08-30), Public-Strang blockiert** — `docs/tp16.3-nautobot-mesh-only-runbook.md §8`
|
||||
### TP16.3 — cloudflared-Reduktion: was der Mesh als Datenpfad kann (und was nicht) ▸ ✅ **ABGESCHLOSSEN 2026-09-01** — Flip (§5) + Abbau (§6) durch; öffentlich nur noch `bf-public` (+`fm`) — `docs/tp16.3-bf-public-ap-connector-runbook.md`
|
||||
|
||||
#### ✅ §6 Abbau — AUSGEFÜHRT 2026-09-01 (vom User vorgezogen, „es wird nichts mehr sein")
|
||||
|
||||
Die 7-Tage-Wartefrist war auf **User-Entscheid** hinfällig. Reihenfolge eingehalten: **erst Container,
|
||||
dann Tunnel** (umgekehrt gäbe es 530er).
|
||||
|
||||
- **Vorbedingung geprüft:** alle vier Namen auf `bf-public`, **kein** Name mehr an den Alttunneln ⇒
|
||||
Abbau gefahrlos.
|
||||
- **7 Container entfernt** (per exakter Namensliste, nicht per Filter — „Namen lesen, nicht Zeilen
|
||||
zählen"): LXC 400 `cloudflared-bfmm`/`-bfnas`, macmini `-bfpve`/`-bfnas`, NAS ep14 `-bfpve`/`-bfmm`,
|
||||
**plus `terpene-cloudflared`** — Letzterer auf zusätzlichen User-Entscheid, weil `420.teilzeitladen.xyz`
|
||||
jetzt über Caddy/CF läuft. **Kein Stack dahinter** ⇒ kein Wiederauferstehen.
|
||||
- **Beweis vor der Tunnel-Löschung:** `420.teilzeitladen.xyz` lieferte **mit bereits entferntem
|
||||
`terpene-cloudflared`** echten Origin-Inhalt (assetlinks-JSON, 200) — der Dienst hängt also nicht
|
||||
mehr am Tunnel.
|
||||
- **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.emsenhuber.net` (4) healthy; alle vier
|
||||
BF-Namen und `420` weiterhin **200**.
|
||||
- ℹ️ Der `terpene-db`-Tunnel-Token stand kurz im `docker inspect`-Output — mit der Tunnel-Löschung
|
||||
**ungültig**, kein Rotationsbedarf.
|
||||
|
||||
#### 🔜 Follow-up F2 — `bf-public`-Connector auf die APs (Runbook 2026-08-30)
|
||||
**Runbook: [`tp16.3-bf-public-ap-connector-runbook.md`](tp16.3-bf-public-ap-connector-runbook.md)**
|
||||
— Vor-Ort-Session an **ap1 + ap3 (Technik UG)** und **ap2 (Technik OG)**, weil der
|
||||
`device-mode`-Wechsel eine **physische** Bestätigung am Gerät verlangt.
|
||||
|
||||
- 🆕 **ap3 ist neu und nicht baugleich** (live 08-30): **cAP ax** (`cAPGi-5HaxD2HaxD`, `10.40.99.13`),
|
||||
arm64, 96 MB Flash frei, 689 MB RAM frei. ~~Zwei verschiedene `container.npk`~~ — **überholt seit dem
|
||||
ROS-Upgrade 08-31: alle drei auf `7.24.1`/arm64 ⇒ EINE Datei** (`container-7.24.1-arm64.npk`,
|
||||
1.187.985 B — exakt die Grösse, die die APs selbst für das Paket melden, damit belegt statt
|
||||
angenommen). ap3 steht auf `device-mode=basic` (nicht `home`), dort ist `fetch` bereits erlaubt —
|
||||
wir nutzen trotzdem auf allen dreien den `.tar`-Import, damit alle dasselbe Image fahren.
|
||||
- ✅ **Blocker A — Redirect-Schleife, behoben 2026-08-31.** `bf-public` zeigt auf `http://10.40.20.40:80`; Caddy antwortet
|
||||
dort mit **308 → `https://<name>/`**, also zurück durch Cloudflare in denselben Tunnel ⇒
|
||||
`ERR_TOO_MANY_REDIRECTS` für alle vier Namen. **Fällt heute nicht auf**, weil die drei Alttunnel
|
||||
**an Caddy vorbei** direkt aufs Backend gehen — die Schleife entsteht erst mit dem Umstieg.
|
||||
Fix = `https://10.40.20.40:443` + `originServerName` je Regel (über 443 mit korrekter SNI: 4× 200).
|
||||
- ✅ **Blocker B — die Freigabe fehlte, angelegt 2026-08-31 über Nautobot GC.** Die `forward`-Kette des Core wurde vollständig
|
||||
gelesen (36 Regeln, Nr. 35 = `TP5: deny-by-default`): **keine** Regel `vlan99 → vlan20` für 80/443.
|
||||
Die einzige MGMT→INFRA-Regel (Nr. 26) ist ein `src-port=8728`-**Rückweg** der API.
|
||||
⚠️ **Der Vorgänger-Runbook behauptet das Gegenteil** („Regel 27 deckt `vlan99→vlan20:80` ab ✅") —
|
||||
Regel 27 ist `IOT->INFRA http-rueckweg`, `in-interface=vlan30`. Ohne neue Regel läuft der Connector
|
||||
in `TP5-WOULD-DROP` + Drop. Egress zu CF (Regel 13 `LAN->WAN`) und DNS (Regeln 30–33) sind dagegen ✅.
|
||||
⇒ Das `masquerade` des `veth`-Netzes ist deshalb **Pflicht**, nicht Kosmetik: sonst kommen die Pakete
|
||||
mit `172.17.0.2` am Core an, wo weder Route noch Regel sie kennt.
|
||||
- ✅ **Blocker C — `ROUTER_AP3_PASS` fehlte in `~/.secrets/credentials.env`, nachgetragen 2026-08-31** (steht nur in
|
||||
`~/.claude.json`), gegen die Credential-Store-Konvention. Der `sshpass -e`-Reboot-Weg braucht es dort.
|
||||
⚠️ Nebenbefund: **`credentials.env` lässt sich in zsh nicht sourcen** — ab ~Zeile 69 stehen rohe
|
||||
WireGuard-Zeilen, zsh bricht ab und lässt die Variablen **leer**; das sieht aus wie ein ungültiger
|
||||
Token. Alle Snippets im Runbook laufen deshalb in `bash -c`.
|
||||
- 🔩 **Kein PoE als Abkürzung:** beide CRS326 haben nachweislich gar kein PoE-Menü
|
||||
(`bad command name poe`) ⇒ es gibt **keinen** Remote-Power-Cycle, die Bestätigung ist wirklich physisch.
|
||||
- 🧹 **Abbau (frühestens 7 Tage nach dem Flip):** Tunnel `bf-mm`/`bf-nas`/`bf-pve` löschen und die
|
||||
**sechs** Container entfernen — LXC 400 (`cloudflared-bfmm`, `-bfnas`), macmini (`-bfpve`, `-bfnas`),
|
||||
NAS ep14 (`-bfpve`, `-bfmm`); alle drei Hosts 08-30 verifiziert. **Erst Container, dann Tunnel** —
|
||||
umgekehrt erzeugt man 530er. 🚫 **`terpene-cloudflared` (LXC 400) und `fm.emsenhuber.net` bleiben.**
|
||||
- 🔴 **Ehrliche Einschränkung (aus TP31, gilt unverändert):** solange Caddy nur auf `caddy-bf1` liegt,
|
||||
ist das Origin aller drei Connectoren **derselbe Rechner** — drei Connectoren kaufen
|
||||
**Hardware-Diversität am Eingang, aber keine Verfügbarkeit**. Der echte Gewinn kommt mit `caddy-bf2`
|
||||
(LXC 131); für `vw` gilt dabei die TP20.1-Bremse (Schreibzugriffe auf einen read-only Standby).
|
||||
- **Rollback:** `docs/cf-backup/*-20260830-vor-tp16.3-schnitt.json` (vier Ingress-Configs + CNAMEs
|
||||
inkl. Record-IDs), am 2026-08-30 **neu angelegt**.
|
||||
- ▶️ **Schnitt ausgeführt 2026-08-24:** `nautobot.emsenhuber.net` ist aus dem Ingress von `bf-nas`
|
||||
entfernt (**8 → 7 Regeln**, Catch-all weiterhin letzte). Rollback-Sicherung liegt unter
|
||||
`docs/cf-backup/bf-nas-ingress-20260824-vor-tp16.3.json` — Rückweg ist ein `PUT`, eine Minute.
|
||||
@@ -500,6 +351,72 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
|
||||
(mit den CF-Leichen am 08-29 gelöscht, Commit `39ba5da`) — der Dienst ist vollständig aus dem
|
||||
öffentlichen Strang heraus und ausschließlich über `10.40.20.30:8080` bzw. intern über Caddy erreichbar.
|
||||
|
||||
##### ✅ §2/§3 durchgezogen — Vor-Ort-Session 2026-08-31
|
||||
|
||||
**Ergebnis:** je ein `cloudflared` auf ap1/ap2/ap3, `bf-public` **healthy mit 12 Connectoren**
|
||||
(3 APs × 4 CF-Edges, alle `2026.6.1`, Egress über `90.146.33.177`). WLAN auf allen drei zurück
|
||||
(CAPs `state=Ok`), Flash je AP **54–55 MiB frei**.
|
||||
|
||||
- 🔴 **Die Platzrechnung des Runbooks war falsch — Faktor 2,5.** §3.5 rechnete mit „28 MB `.tar`
|
||||
+ ~28 MB entpackte Layer ≈ 39 MB Rest". Die 28 MB sind die **komprimierte** Archivgrösse; das
|
||||
entpackte Image misst **72.926.208 B = 69,5 MiB** (`docker export | wc -c`). Spitzenbedarf beim
|
||||
Import ist **Tar + entpacktes Abbild gleichzeitig** ⇒ 26,2 + 69,5 = **95,7 MiB gegen 90,5 MiB frei**.
|
||||
Das offizielle `cloudflare/cloudflared`-Image passt auf diese Geräte **nicht** — auf keinem der drei.
|
||||
⚠️ **`docker image inspect .Size` führt hier in die Irre** (meldete 27.463.950); `docker history`
|
||||
summiert auf ~70 MB. **Für Flash-Budgets `docker export` messen, nicht `inspect`.**
|
||||
- ✅ **Lösung: eigenes Minimal-Image, `FROM scratch`.** Das Binary im offiziellen Image ist
|
||||
**statisch gelinkt** (verifiziert) und 36,8 MB gross; die restlichen ~33 MB sind distroless-Debian,
|
||||
das cloudflared nicht braucht. Das selbst gebaute Archiv (Binary + CA-Bundle) misst **35,3 MiB**,
|
||||
Spitzenbedarf 70,6 MiB. Gepinnt über die **Binary-SHA256 `e93824f6…`** — cloudflared bestätigt sie
|
||||
beim Start selbst (`Version 2026.6.1 (Checksum e93824f6…)`), das ist der Reproduzierbarkeits-Nachweis.
|
||||
Build-Skript erzeugt das docker-v1-Archiv direkt, ohne Docker-Umweg.
|
||||
- 🔴 **`docker save` taugt seit Docker 25 nicht mehr als Quelle.** Mit containerd-Image-Store schreibt
|
||||
es ein **OCI-Layout** (`blobs/sha256/`, gzip-Layer); RouterOS will docker-v1 und quittiert das mit
|
||||
**`no config found in manifest`** — eine Meldung, die nach kaputtem Image klingt, nicht nach Format.
|
||||
- 🔴 **`/container/envs` heisst auf ROS 7.24.1 `list=`, nicht `name=`.** Das Runbook (§3.5) und das
|
||||
MikroMCP-Tool `manage_container_env` benutzen beide `name=` und scheitern mit
|
||||
`unknown parameter name`. Token-Übergabe deshalb per `.rsc` + `/import` (Datei danach löschen) —
|
||||
so steht der Wert weder in `ps` noch im Transkript.
|
||||
- 🔴 **Der `device-mode`-Bestätigungs-Boot installiert KEINE Pakete.** Auf ap1 wurde die `.npk` vor
|
||||
dem Setzen von `device-mode` hochgeladen, um Christoph einen Reboot zu sparen: der Stromzyklus hat
|
||||
`container: yes` bestätigt und die Datei **verbraucht, ohne sie zu installieren** — `/system package
|
||||
print` zeigte danach nur zwei Pakete. **Reihenfolge ist also Pflicht: erst Paket-Reboot, dann
|
||||
`device-mode`.** Nachholen ging ohne physischen Gang (SSH-Reboot).
|
||||
- 🟡 **`A - AVAILABLE` bei `/system package print` ist ein Download-Katalog, kein Paket auf dem Gerät.**
|
||||
Gegenprobe: `crs326-core` hat 2,9 MB frei von 16 MB, listet aber `wifi-qcom` (10,1 MB) und
|
||||
`rose-storage` (4,3 MB) als „available"; die Grössen sind zudem arch-spezifisch. Ein
|
||||
`/system package enable` löst also einen Internet-Fetch aus — auf ap1/ap2 per `device-mode=home`
|
||||
gesperrt. **Der `.npk`-Weg bleibt richtig.**
|
||||
- 🟡 **MikroMCPs `export_config` liefert einen unvollständigen Export** (301 B gegen 6,2 KiB bei
|
||||
direktem `/export`) — ein Rollback-Artefakt, das existiert und trotzdem leer ist. Für die Backups
|
||||
dieser Session wurden die MCP-Exporte verworfen und `/export file=…` verwendet.
|
||||
- ✅ **ERLEDIGT 2026-08-31: die sechs Drifts sind ins Soll gehoben, Compliance 139/140.**
|
||||
Entscheid Christoph: ins Template heben (nicht als Transaktion führen), und `/interface veth`
|
||||
bekommt eine **eigene ComplianceRule** — vorher war es das tragende Stück ohne jede Überwachung.
|
||||
Umgesetzt in `nautobot/mikrotik_routeros.j2` (Block `[7]`), `nautobot/ingest-ap-configcontext.py`
|
||||
(`ap.container`) und neu `nautobot/ingest-veth-rule.py`. **Kein Geräte-Write.**
|
||||
🔴 **Der veth-Export trägt zwei gerätevergebene MACs** (`mac-address`, `container-mac-address`,
|
||||
je AP verschieden). Ohne Vorbehandlung hätte die neue Regel auf **allen drei APs Dauer-Drift**
|
||||
erzeugt — also genau die immer-rote Zahl, die niemand mehr liest. Zwei `ConfigReplace`-Regeln
|
||||
normalisieren sie im Backup, eng auf die veth-Zeile verankert (`[^\n]*?` plus Lookbehind, damit
|
||||
VAP-/Bridge-/Ethernet-MACs nicht mitgefangen werden; Selbsttest im Skript).
|
||||
⚠️ **Ehrlich dazugesagt:** das kostet Backup-Treue — die veth-MACs stehen in `bf-golden-config`
|
||||
nicht mehr im Klartext. Vertretbar, weil RouterOS sie beim Neuanlegen ohnehin neu vergibt; was die
|
||||
Regel beweist, ist die **Existenz** des veth mit der richtigen Adressierung.
|
||||
*(Der ursprüngliche Befund, zur Nachvollziehbarkeit:)*
|
||||
- 🟢 **War: Compliance stand auf 128/135, nicht 134/135.** §3.4 schreibt
|
||||
Direkt-Writes für `veth` / `ip address` / `nat` vor, während `/ip address` und `/ip firewall` unter
|
||||
GC-Drift-Kontrolle stehen — **Runbook und Governance widersprechen sich.** Folge: je AP zwei neue
|
||||
`extra`-Drifts (`ip-address` mit `172.17.0.1/24 interface=veth-cf`, `ip-firewall-nat` mit dem
|
||||
`TP31: cloudflared egress`-Masquerade), also **sechs**. Sie sind **inhaltlich richtig** — die Config
|
||||
soll dort stehen. Der saubere Weg ist, sie ins Soll zu heben (AP-Template/ConfigContext), **nicht**
|
||||
ein Re-Baseline und **nicht** ein Rückbau. ⚠️ Bis dahin ist die Zahl erklärt, aber nicht in Ordnung.
|
||||
(Die siebte Drift, `crs326-core` / `wifi-security` / `ft-over-ds`, ist die bekannte und unverändert.)
|
||||
- ⚠️ **WLAN-Abnahme mit Einschränkung:** `main` (3) und `iot` (27) haben Clients und frische Leases;
|
||||
`media`/`untrusted`/`guest` hatten **schon vor** dem Umbau null Clients — für die drei gibt es
|
||||
keinen Lease-Nachweis, weil niemand eine zieht. Kein Rückschritt, aber auch kein Beleg.
|
||||
|
||||
|
||||
#### ▶️ Der grosse Schnitt — ausgefuehrt 2026-08-30 (User-Entscheid „kompletter Schnitt in einem Zug")
|
||||
- **12 Hostnames entfernt**, aus Ingress **und** DNS, in einem Durchgang:
|
||||
`pve` · `portainer` · `pve-mcp` · `ha-mcp` · `ds-bf` · `ccu` · `iobroker` · `z2m25` · `pbs`
|
||||
@@ -1057,7 +974,26 @@ des Dimmers (= Lichtausfall in Diele UG/Wohnzimmer) wurde daraufhin **nicht** au
|
||||
- **Verwandt/Abgrenzung:** vw ist auch in **TP16** offen (CF-Access: `bypass`→WARP-geschützt) — **DB-HA ≠ Access**, getrennt behandeln. Reziprokes 2-Site-Muster analog **TP16**/**TP18**.
|
||||
- Abh.: **TP20** (Tier-1 Postgres muss stehen), **TP10** (WG-Transport für Phase-2), **TP18** (Backup-Schirm). Kein Blocker für TP21.
|
||||
|
||||
### TP23 — DNS-Policy & Self-Service-Ausnahmen ▸ ⏳ **STUFE 1 DURCH, STUFE 2 VORBEREITET (2026-08-18)**
|
||||
### TP23 — DNS-Policy & Self-Service-Ausnahmen ▸ ⏳ **STUFE 1–5 DURCH (2026-09-04); offen nur Stufe 6 (Bypass-Sperre, in TP5)**
|
||||
> 🟢 **Update 2026-09-04 — Stufe 4 + 5 gebaut, live verifiziert. Der `.16`-Text unten ist überholt**
|
||||
> (Stufe 2 lebt seit 08-26 auf dem Paar `agh-bf1`/`agh-bf2` = `.36`/`.37`, LXC 110/111 — s. Ist-Stand-Block):
|
||||
> - **Stufe 4 (CIDR-Substrat):** 7 VLAN-Gruppen + `dns-bypass-exempt` in `clients.persistent` auf beiden
|
||||
> Instanzen; Policy-Matrix (INFRA/MEDIA/MGMT `filtering=aus`, GUEST safe-search+parental an). Neuer
|
||||
> AGH-API-User `automation` (PW in `~/.secrets` → TP30). Sync-Werkzeug `adguard/agh-sync.py`
|
||||
> (`check`/`push`), Repo-SSoT `adguard/AdGuardHome.yaml` mit **redigierten** Hashes. Invariante `.36==.37`.
|
||||
> - **Stufe 5 (HA-Self-Service):** `agh-exception.py` (RMW-CLI, `allow-domain`/`unallow`/`unfilter`/`refilter`)
|
||||
> auf HAOS deployt; `shell_command` + 5 Helper + Timer + 2 Automations (`ha-mcp`). Button → Domain für
|
||||
> 15 min/1 h/4 h entsperren, nativer `timer` revertiert; RouterOS-`jit-dns-bypass`-Backstop erst mit Stufe 6.
|
||||
> Doku: `adguard/README.md` + `adguard/ha-self-service.md`. End-to-End getestet (Start + Ablauf).
|
||||
> - **Offen:** nur **Stufe 6** (DNS-Bypass-Sperre) — bewusst NICHT geschaltet. Runbook für eine
|
||||
> **separate Session**: [`docs/tp23-stufe6-bypass-sperre-runbook.md`](tp23-stufe6-bypass-sperre-runbook.md).
|
||||
> 🔴🔴 **HARTES VOR-ORT-GATE:** macht AGH `.36/.37` zum harten DNS-SPOF, aus der Ferne nicht
|
||||
> reparierbar → **NUR vor Ort, NICHT während Christoph abwesend ist** (2026-09-06: ~1 Woche weg →
|
||||
> in dem Fenster gar nicht anfangen). Methodik: log-only-Vorstufe zuerst, Drop mit Auto-Revert zuletzt.
|
||||
> - **WARP-Managed-Network (Stufe 2 im alten Plan)** bleibt offen (TP41-nah). Der `.16`-basierte
|
||||
> Abschnitt darunter ist die historische Fassung (2026-08-18), bewusst erhalten.
|
||||
|
||||
**[Historische Fassung 2026-08-18 — `.16`-basiert, durch den Block oben überholt:]**
|
||||
- ✅ **Stufe 1 — DoH auf dem Core scharf** (`routeros/tp23-stufe1-doh-core.rsc`), schliesst zugleich
|
||||
**TP21.1 TODO 1**. `use-doh-server=https://px35ynlol3.cloudflare-gateway.com/dns-query`,
|
||||
**`verify-doh-cert=yes`**. `servers=1.1.1.1` bleibt als Bootstrap fuer den DoH-Hostnamen stehen.
|
||||
@@ -1142,7 +1078,7 @@ des Dimmers (= Lichtausfall in Diele UG/Wohnzimmer) wurde daraufhin **nicht** au
|
||||
- **Abh.:** keine harten. **TP15 ✅** (die zu versorgende Hardware steht und hat DC-Eingänge). Verwandt: **TP18** (Garage-Nodes brauchen je Site eine Stromversorgung), **TP11** (USV-Zustand ins Monitoring). **Kein Blocker für TP5/TP6.**
|
||||
- **Historie:** war bis 2026-08-16 Unterpunkt von TP15 („🔋 DC-USV: MeanWell LRS-150-48 + DDR-120-48 + LiFePO4 20Ah (~€190), 48V-Bus; CRS326 DC-input passt"). Vollständige Recherche inkl. Schaltbild, Effizienzvergleich und Gerätetabelle: `docs/hw-refresh-requirements.md §9` (+ §10 D/E/F für die offenen Fragen).
|
||||
|
||||
### TP25 — WLAN-Stabilisierung ▸ 🔬 **FUND E OFFEN, HEBEL 1 LÄUFT (2026-08-31 08:09): `ft-over-ds=no` auf `sec-main`, Messung bis 2026-09-01** · Kern erledigt: 🟢 **(2026-08-22) Dead Spot Terrasse repariert** (43 % → 9 % Verlust, 20,4 s → 1,0 s). **Fund F ✅ aufgelöst (08-24, geräteseitig — kein Netzfehler)**, **5-GHz-Umfeldscan ✅ (08-24)**, Kanalplan für AP 3 ✅ gerechnet. Offen nur noch die Umsetzung, wenn der dritte AP kommt. Nicht mehr kritischer Pfad — Sammel-TP für Christophs Beobachtungen 1–6
|
||||
### TP25 — WLAN-Stabilisierung ▸ ⏳ **FUND E ✅ GESCHLOSSEN 2026-09-02: die Abschlussmessung ist ruhig (4 reauth in 8,6 h, 0 Ausfälle, Verlauf 218→40→4) ⇒ `7.24.1` (TP27) war die Ursache, nicht `ft-over-ds`. Hebel 1 widerlegt+zurückgebaut, Hebel 2–4 entfallen, kein Geräte-Write** ([Handoff](handoff-20260902-tp25-fund-e-messung.md)) — **offen bleibt nur: ap2 unterperformt (2 m/−80 dBm, 23:02-Befund) als eigener In-situ-Unterpunkt** · Kern erledigt: 🟢 **(2026-08-22) Dead Spot Terrasse repariert** (43 % → 9 % Verlust, 20,4 s → 1,0 s). **Fund F ✅ aufgelöst (08-24, geräteseitig — kein Netzfehler)**, **5-GHz-Umfeldscan ✅ (08-24)**, Kanalplan für AP 3 ✅ gerechnet. Offen nur noch die Umsetzung, wenn der dritte AP kommt. Nicht mehr kritischer Pfad — Sammel-TP für Christophs Beobachtungen 1–6
|
||||
> 📚 **Kondensiert am 2026-08-23 (Doku-Session, Punkt F).** Dieser Abschnitt war mit 394 Zeilen
|
||||
> 18 % der Datei. Die **Langfassung steht vollständig und unverändert** im Archiv:
|
||||
> [`teilprojekte-archiv.md` → TP25 (Langfassung)](teilprojekte-archiv.md#tp25-lang) — Messchronik (A)–(G),
|
||||
@@ -1393,10 +1329,18 @@ die alte Liste führte `2g-probe-delay` an, das aber **Band-Steering** adressier
|
||||
|
||||
| # | Hebel | Begründung der Reihenfolge | Risiko | Stand |
|
||||
|---|---|---|---|---|
|
||||
| 1 | **`ft-over-ds=no`** auf `sec-main` | nimmt die Änderung vom 08-17 zurück; FT bleibt über `ft=yes` (over-the-air) erhalten. Kleinster Eingriff, der die verdächtige Achse trifft | gering | 🔬 **gezogen 2026-08-31 08:09**, Messung läuft |
|
||||
| 2 | `ft=no` auf `sec-main` | falls (1) nicht reicht: FT komplett aus. Kostet Roaming-*Geschwindigkeit*, nicht Roaming | mittel | 🔜 nur wenn (1) nicht greift |
|
||||
| 3 | `2g-probe-delay=yes` (2,4-GHz-Configs) | MikroTiks *dafür gebautes* Werkzeug; verzögert nur Probe-Antworten und **kann keinen Client stranden lassen**. Adressiert die **Band-Oszillation** — ein anderes Symptom | sehr gering | 🔜 |
|
||||
| 4 | `signal-range`-Boden per `access-list` (Fund E im Original) | **kann Clients aussperren** — genau das war 08-22 das Gegenargument; nur mit gemessenem Wert | hoch | 🔜 |
|
||||
| 1 | **`ft-over-ds=no`** auf `sec-main` | nimmt die Änderung vom 08-17 zurück; FT bleibt über `ft=yes` (over-the-air) erhalten. Kleinster Eingriff, der die verdächtige Achse trifft | gering | ❌ **widerlegt** — lief 6,4 h allein → 124× (≈19/h) + 2 Ausfälle, **zurückgebaut 2026-09-01** |
|
||||
| 2 | `ft=no` auf `sec-main` | falls (1) nicht reicht: FT komplett aus. Kostet Roaming-*Geschwindigkeit*, nicht Roaming | mittel | ✅ **gezogen 2026-09-04** (User-Entscheid, Dauerzustand — Template + bf-golden-config + Nautobot-Sync) |
|
||||
| 3 | `2g-probe-delay=yes` (2,4-GHz-Configs) | MikroTiks *dafür gebautes* Werkzeug; verzögert nur Probe-Antworten und **kann keinen Client stranden lassen**. Adressiert die **Band-Oszillation** — ein anderes Symptom | sehr gering | ⏹️ entfällt (Fund E geschlossen) |
|
||||
| 4 | `signal-range`-Boden per `access-list` (Fund E im Original) | **kann Clients aussperren** — genau das war 08-22 das Gegenargument; nur mit gemessenem Wert | hoch | ⏹️ entfällt (Fund E geschlossen) |
|
||||
|
||||
> ✅ **Ergebnis 2026-09-02 (Abschlussmessung, [Handoff](handoff-20260902-tp25-fund-e-messung.md)):** Der Sturm ist mit
|
||||
> `ft-over-ds=yes` **und** 7.24.1 verschwunden — 09-02 nur **4 reauth in 8,6 h** (alle iPhone `F2:62`, isolierte
|
||||
> Einzel, 0 Ausfälle), Verlauf **218 → 40 → 4**. Vorbedingung geprüft (Core-Uptime 1d18h, `caps joined=0`).
|
||||
> ⇒ **7.24.1 war die Ursache/der Fix, nicht `ft-over-ds`.** Hebel 1 widerlegt+zurückgebaut, Hebel 2–4 entfallen,
|
||||
> **kein Geräte-Write** (Soll stand: `ft=yes ft-over-ds=yes`, Compliance 140/140). **Am 2026-09-04 hat
|
||||
> Christoph `ft=no` auf `sec-main` als Dauerzustand entschieden** (Hebel 2 doch gezogen). Der folgende Detailblock zu
|
||||
> Hebel 1 ist historisch.
|
||||
|
||||
#### 🔬 Hebel 1 — gezogen am 2026-08-31 08:09, Messung läuft bis 2026-09-01
|
||||
|
||||
@@ -1479,16 +1423,20 @@ während eines Calls deployen, `/system backup` je AP vorher.
|
||||
- 🔴 **Ein vom Pin abgewiesener Verbindungsversuch ist in Ping-Daten nicht von einem Funkloch zu
|
||||
unterscheiden** — und der Manager protokolliert ihn auf `info`-Ebene **gar nicht**. Android quittiert
|
||||
die Abweisung mit „Verbindung fehlgeschlagen" und **wählt das Netz ab**; danach misst der Rest des
|
||||
Rundgangs Stille. Die Klick-Konsole schlägt deshalb Alarm, sobald das gepinnte Gerät nirgends hängt,
|
||||
und schreibt nach 45 s `UNERREICHBAR=apX` — denn „der Gegen-AP trägt hier nicht" **ist das Messergebnis**.
|
||||
- 📐 **Eine Runde, zwei Messpunkte** (Christophs Aufbau 2026-08-22): das frei roamende iPhone zeigt, was
|
||||
ein normaler Client wählt — interessant ist der **andere**. Das S22 wird per `access-list` auf den
|
||||
Gegen-AP gezwungen ([`tp25-pin-s22.sh`](tp25-pin-s22.sh)). Gute Referenz + schlechte Sonde = die
|
||||
Abdeckung steht, die Rückfallebene nicht. Memory `ref_gegen_ap_messung`.
|
||||
Rundgangs Stille. Die Klick-Konsole schlägt deshalb Alarm, sobald ein **gepinnter** Client nirgends
|
||||
hängt (`sta_iface=absent` in `sampler-<name>.csv`) — denn „der Gegen-AP trägt hier nicht" **ist das
|
||||
Messergebnis**.
|
||||
- 📐 **Eine Runde, N Messpunkte** (seit 2026-09-04): die frei roamenden Clients zeigen, was ein normaler
|
||||
Client wählt — interessant sind die **gepinnten**. Jeder Client wird **band-genau** auf einen AP
|
||||
gezwungen ([`tp25-pin-multi.sh`](tp25-pin-multi.sh), `TP25_PINSPEC="name|mac|ap|band;…"`), direkt aus
|
||||
der Klick-Konsole. Gute Referenz + schlechte Sonde = die Abdeckung steht, die Rückfallebene nicht.
|
||||
Memory `ref_gegen_ap_messung`. *(Die alte 2-Client-`access-list`-Automatik über `tp25-pin-s22.sh` ist
|
||||
mit dem Multi-Pin-Umbau entfallen; `tp25-pin-s22.sh` liefert nur noch die `map`.)*
|
||||
- ▶️ **Start ohne Werkzeugkette: `bash docs/tp25-runde.sh [name]`** — legt den Lauf unter
|
||||
`docs/messdaten/tp25-runde-<name>/` an, friert die AP-Karte ein, startet Konsole (Port 3031) und
|
||||
Messung, sagt die **vom Interface gelesene** Adresse fürs Telefon an und löst beim Beenden den Pin.
|
||||
Auswertung: `tp25-gehweg-auswertung.py --dir …`.
|
||||
Messung, sagt die **vom Interface gelesene** Adresse fürs Telefon an. In der Konsole: **pinnen**
|
||||
(N Clients je AP/Band) → **gehen** (🚶/📍) → **Räume antippen** → **stoppen**; beim Beenden löst der
|
||||
Wrapper den Multi-Pin. Auswertung: `tp25-gehweg-auswertung.py --dir …`.
|
||||
- ℹ️ **Und das alles passiert TROTZ aktivem 802.11k/v und FT** (`st-main` mit `rrm=yes`/`wnm=yes`,
|
||||
`ft-over-ds=yes`, live geprüft). Die Merkregel `ref_ft_is_not_roaming` („11k/v fehlen") ist
|
||||
**historisch**. Bei −48…−55 dBm kostet eine Übergabe 0–2,6 s, meist unter einer halben Sekunde —
|
||||
@@ -1514,6 +1462,53 @@ die Redundanzfrage oben.
|
||||
- **Abh.:** TP22 ✅ (GC-Deploy-Pipeline). Verwandt **TP3.2** (`docs/wifi-p750w-coverage-and-map.md`),
|
||||
**TP29** (nutzt dieselbe Datenquelle als Sensor). **Kein Blocker für irgendetwas.**
|
||||
|
||||
#### 🔬 Fund E — 2026-09-01: der `ap2`-Teilbefund (gültig) und eine widerlegte Heilungs-Wertung
|
||||
|
||||
**Anlass:** Christoph meldete **2026-08-31 23:02** eine Störung am Schreibtisch (5G, iPhone, kein
|
||||
Telefonat). Analyse (alles read-only am Manager `crs326-core`):
|
||||
|
||||
- **AP-Karte** (stabil seit letztem CAP-Rejoin 15:57, kein Rejoin danach — Attribution belastbar):
|
||||
`cap-wifi5/6 = ap2`, `cap-wifi3/4 = ap3`, `cap-wifi1/2 = ap1` (funkstill, Radios da, 0 Clients).
|
||||
- **23:02-Ereignis:** iPhone `F2:62:4C:E1:AF:09` ping-pongt im Sekundentakt `cap-wifi5 ↔ cap-wifi6`
|
||||
= **ap2s 5G (5220) ↔ ap2s 2,4G (ch11/2462)** — Band-Steering-Thrash auf **demselben** AP, plus
|
||||
`disconnected, not responding` um 22:37:40 (−76) und **23:01:00** (−82). Feldstärke der Roams
|
||||
**−75…−88 dBm**.
|
||||
- 🔴 **Christophs Fakt kippt die Coverage-Deutung:** iPhone und **ap2 nur 2 m** entfernt, gleicher
|
||||
Raum, ap2 auf 2,3 m. Bei 2 m Sicht wären −35…−45 dBm normal. −80 auf 2 m ist **kein** Coverage-
|
||||
und **kein** FT-Problem. Dazu: **aktuell 0 Clients auf ap2**, alle 29 auf ap3 — die Clients *meiden*
|
||||
ap2. ⇒ **ap2s Funk selbst unterperformt** (RF/Antenne/HW) und/oder die **DTU-Störung auf ap2/ch11**
|
||||
(Transaktion `TP17.1-dtu-pin-ap2`, Wechselrichter `54:F2:9F:12:51:F0` mit −59 dBm auf ap2s 2,4-Radio).
|
||||
- **In-situ zu messen** (nachts nicht möglich — Phone idle auf ap3): Registration-Signal live prüfen,
|
||||
während ein Client auf ap2 hängt; Kandidaten-Eingriffe — DTU-Pin lösen/verlegen, `dirtyvader-main`
|
||||
auf ap2 temporär deaktivieren (ap3 übernimmt den Schreibtisch), ap2-Antenne/HW prüfen. **Keine
|
||||
Änderung ohne diese Messung.**
|
||||
|
||||
🔴 **WIDERRUFEN am 2026-09-01 vormittags — der zweite Teil dieses Abschnitts war ein Messfehler.**
|
||||
Ursprünglich stand hier: „Fund E ist im sauberen Fenster geheilt — 0× `reauthenticating` seit dem
|
||||
14:36-Reboot (`sinceMinutes=1440`, total 0), also hat Hebel 1 sein Ziel erreicht."
|
||||
|
||||
**Warum das nicht trägt:** `get_log` liest den **flüchtigen Ringpuffer des Routers**, nicht den
|
||||
Kollektor. Live nachgemessen fasst er **1000 Zeilen und reicht bis 01.09. 00:38:58 zurück** — keine
|
||||
9 Stunden. Der Core-Reboot um 14:36 hatte ihn geleert; der 31.08. Vormittag war darin gar nicht
|
||||
enthalten. `total 0` hieß **„im Puffer nichts", nicht „in 24 h nichts"**. Das ist exakt die Falle,
|
||||
wegen der am 30.08. das persistente Logging gebaut wurde.
|
||||
|
||||
**Was der Kollektor zeigt:** im upgrade-freien Fenster 08:09–14:36 (Hebel 1 **allein**) **124×
|
||||
`reauthenticating`** — 09h=1 · 11h=2 · 12h=20 · 13h=31 · 14h=70, **alle vom iPhone allein**, dazu
|
||||
Christophs zwei erlebte Ausfälle 13:16 und 14:23. Zwischen 09:00 und 14:36 lag **kein Reboot**.
|
||||
⇒ Hebel 1 wurde am 2026-09-01 **zurückgebaut**; der Rückbau ist das entscheidende Experiment
|
||||
(s. Ist-Stand-Block oben).
|
||||
|
||||
✅ **Der `ap2`-Teilbefund oben bleibt davon unberührt und gültig** — er ist unabhängig gemessen und
|
||||
erklärt die 23:02-Störung, die weder FT noch Coverage erklärt.
|
||||
|
||||
**Commit-Weg (wartet auf Christophs Go — git-push-Kette):** Template `nautobot/mikrotik_routeros.j2`
|
||||
**Z. 220** `sec-main` von `ft-over-ds=yes` → `ft-over-ds=no`; dann Template-Repo nach Nautobot syncen,
|
||||
`gc-configplan.py --refresh-compliance` (Backup→Intended→Compliance), dann
|
||||
`gc-transaktion.py commit --change-id TP25-fund-e-ft-over-ds`. Danach `wifi-security` wieder driftfrei.
|
||||
🔴 Kreuzt git-push (Backup-Guard + Commit-Hinweis-Regel) und Live-Nautobot-Jobs — **nicht autonom.**
|
||||
Handoff: [`handoff-20260901-tp25-ap2-verdacht.md`](handoff-20260901-tp25-ap2-verdacht.md).
|
||||
|
||||
<a id="tp28"></a>
|
||||
|
||||
### TP28 — WLAN über CAPsMAN auf `crs326-core` ▸ ✅ **ap3 LIVE (2026-08-30)** — wieder geöffnet und durchgezogen
|
||||
@@ -1784,6 +1779,10 @@ Umzug **nebeneinander**, ein zweiter AP am selben Punkt bringt nichts und stört
|
||||
| 2 | **IoT-WLAN-PSK** (`sec-iot`) | `dirtyvader-iot`, 26 Clients | steht **im Klartext** im TP17-Text ⇒ auch in der **Git-Historie**; Redigieren holt ihn dort nicht raus | Hebel `multi-passphrase` am Core verifiziert vorhanden, Tabelle leer | 23 Shellys per Skript + **3 von Hand** (`.249` NSPanel Pro, `.244` Nuki Bridge, `.227` SwitchBot) |
|
||||
| 3 | **Shelly-Gerätepasswort** *(vormals TP17.2)* | 23 Shellys | Härtung (bisher **keine** Auth auf den Geräten) | ✅ Werkzeug fertig (`migrate.py cmd_auth` + Digest-Fallback) | **je Gerät ein HA-Re-Auth-Flow** — das ist der Aufwand, nicht `SetAuth` |
|
||||
| 4 | **CF-Access-Service-Token** (`CF_API_TOKEN`) | Cloudflare-Zugang, s. TP14.4 | ⏳ **läuft am 2027-01-09 ohnehin ab** — harter Termin, unabhängig vom Projektende | Runbook liegt (`tp14.4-cf-access-token-runbook.md`) | Token neu ausstellen + `~/.secrets` nachziehen; **account-owned**, anderer verify-Endpoint |
|
||||
| 5 | **Nautobot-Tokens** (`NAUTOBOT_SUPERUSER_API_TOKEN`, `NAUTOBOT_GITEA_TOKEN`) | Nautobot-Superuser + Gitea-Anbindung | 🔴 in der TP16.3-§2/§3-Session (2026-08-31) durch schwache `sed`-Maskierung **ins Transkript** geraten | Werte in `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored) | neu ausstellen + Stack-YML nachziehen; Superuser-Token wird von den `gc-*`-Skripten gelesen |
|
||||
| 6 | **MariaDB `root`** (LXC 302, `10.40.20.23`) | root-DB-Login | 🔴 am 2026-09-01 (TP39) ins Transkript geraten — die `/root/.my.cnf` trug `password <wert>` **ohne `=`**, die Feld-Maskierung ankerte auf `=` und griff nicht | Wert in `/root/.my.cnf` (chmod 600) | `SET PASSWORD` + `.my.cnf` nachziehen; **kein** externer Konsument (Dienste nutzen eigene DB-User) ⇒ billigste Rotation der Liste |
|
||||
| 7 | **`TERPENE_ANDROID_KEYSTORE_PW`** | Terpene-Android-TWA-Signing (`android/android.keystore`, alias `terpene`) | 🔴 am 2026-09-01 (TP41) durch **Regex-Suffix-Loch** (`_PW` nicht abgedeckt) ins Transkript geraten | Wert in `~/.secrets/credentials.env` + Keystore-Datei | **Store-/Key-Passwort** via `keytool -storepasswd`/`-keypasswd` ändern + `credentials.env` nachziehen; Konsument = Android-Build/Play-Signing (**Cross-Projekt blaueblüten**) — den **Key selbst NICHT** neu erzeugen |
|
||||
| 8 | **`N8N_SMTP_PASS`** (Gmail-App-PW für `johnny.claw.0x00@gmail.com`) | SMTP-Versand aus n8n (Portainer-Stack 174 `n8n`, macmini) | 🔴 am 2026-09-01 (n8n-mcp-SSRF-Session) beim Ausgeben des Stack-174-Files ins Transkript geraten — Redaktionsmuster hatte `PASSWORD`, aber **nicht bare `PASS`** → `N8N_SMTP_PASS=<wert>` blieb stehen | Wert in Portainer-Stack 174 (`environment`) | **Gmail-App-Passwort widerrufen** (Google-Konto → App-Passwörter) + neues erzeugen, Stack-174-Env nachziehen + redeploy; Konsument = n8n-SMTP-Node(s) |
|
||||
|
||||
> ✅ **Der Leak-MECHANISMUS hinter #1 ist seit 2026-08-31 zu — der Wert bleibt trotzdem verbrannt.**
|
||||
> Alle sechs Skripte im Repo, die `sshpass -p <PW>` benutzten (`nautobot/gc-transaktion.py` und
|
||||
@@ -1795,6 +1794,28 @@ Umzug **nebeneinander**, ein zweiter AP am selben Punkt bringt nichts und stört
|
||||
> also nicht blind. 🔴 **Das ändert an #1 nichts:** ein Wert, der einmal in einem Transkript stand,
|
||||
> wird nicht dadurch sauber, dass der Weg dorthin geschlossen ist. Rotation bleibt fällig.
|
||||
>
|
||||
> 🔴 **Posten #6 ist die dritte Maskierungs-Panne derselben Klasse** (nach `SHELLY_DEVICE_PW` 08-28
|
||||
> und den Nautobot-Tokens 08-31): das Muster ankerte auf ein **Trennzeichen** (`=`), das im
|
||||
> konkreten File gar nicht stand (`password <wert>` mit Leerzeichen). **Merkregel, jetzt zum dritten
|
||||
> Mal:** vor jedem Ausgeben einer Secret-Datei den **Schlüsselnamen** ankern und das ganze Feld
|
||||
> ersetzen, nie auf ein Trennzeichen vertrauen, das evtl. fehlt — und Werte gar nicht erst suchen,
|
||||
> um sie zu sehen. #6 ist zugleich der **billigste** Posten (kein externer Konsument), aber die
|
||||
> Panne dahinter ist der teure Teil.
|
||||
>
|
||||
> 🔴 **#7 ist die vierte Maskierungs-Panne derselben Klasse** (nach `SHELLY_DEVICE_PW` 08-28,
|
||||
> Nautobot-Tokens 08-31, MariaDB-root 09-01): diesmal ein **Regex-Suffix-Loch** — das Muster
|
||||
> `(TOKEN|PASS|PASSWORD|SECRET|KEY|CLIENT_ID)` deckte den Suffix `_PW` **nicht** ab, also blieb der
|
||||
> Wert von `TERPENE_ANDROID_KEYSTORE_PW` beim maskierten Lesen stehen. **Dieselbe Merkregel, erweitert:**
|
||||
> die Alternation muss `PW`/`PWD` mit enthalten (`…|PW|PWD|…`), sonst greift die Feld-Ersetzung nicht.
|
||||
>
|
||||
> 🔴 **#8 ist die fünfte Maskierungs-Panne derselben Klasse** (SHELLY 08-28, Nautobot-Tokens 08-31,
|
||||
> MariaDB-root #6, Keystore-`_PW` #7): diesmal enthielt das Muster zwar `PASSWORD`, aber **nicht das
|
||||
> bare `PASS`** — `N8N_SMTP_PASS` endet auf `PASS`, nicht `PASSWORD`, also blieb der Wert stehen.
|
||||
> **Die Merkregel steht jetzt zum fünften Mal da und wurde zum fünften Mal gebrochen** — Konsequenz
|
||||
> ist nicht noch eine Notiz, sondern ein **fixes, geteiltes Redaktions-Snippet**, das man nicht jedes
|
||||
> Mal neu (und falsch) tippt: `sed -E 's/([A-Z0-9_]*(PASS|PASSWORD|PWD|PW|TOKEN|SECRET|KEY|BEARER))=[^[:space:]]*/\1=<redacted>/g'`
|
||||
> — ankert auf den **Schlüsselnamen inkl. Präfix** und deckt alle bisher gesehenen Suffixe ab.
|
||||
>
|
||||
> ℹ️ **#3 war bis 2026-08-24 TP17.2** und ist jetzt vollständig hier (s. Detailabschnitt unten) —
|
||||
> es benutzt denselben Geräte-Durchgang wie #2, **ein Reboot statt zwei**. #4 gehört sachlich zu
|
||||
> **TP14.4**, das als TP bestehen bleibt (dort steckt das CF-Access-Profil, nicht nur der Token).
|
||||
@@ -1987,7 +2008,16 @@ unabhängig vom gebündelten Durchgang.**
|
||||
|
||||
|
||||
<a id="tp31"></a>
|
||||
### TP31 — Reverse Proxy für innen und außen; cloudflared von sechs Knoten auf einen ▸ 🔜 **GEPLANT 2026-08-25**
|
||||
### TP31 — Reverse Proxy für innen und außen; cloudflared von sechs Knoten auf einen ▸ ✅ **ABGESCHLOSSEN 2026-09-01**
|
||||
> ✅ **Durch — Schritt 5+6 sind über den Piloten [TP16.3](#tp163) miterledigt (2026-09-01):** `bf-public`
|
||||
> **healthy, 12 Connectoren** auf ap1/ap2/ap3; `vw`/`hass`/`n8n`/`gitea` laufen über CF → **Caddy**
|
||||
> (`https://10.40.20.40:443`), die drei Alttunnel `bf-nas`/`bf-pve`/`bf-mm` **gelöscht**. Damit steht das
|
||||
> Zielbild: **eine** Host→Origin-SoT im `Caddyfile`, öffentlich nur vier Namen. Abnahme-Tool
|
||||
> [`caddy/cf-sync.py`](../caddy/cf-sync.py) **grün** (2026-09-02: die vier geflippten Namen wurden vorher
|
||||
> als Fehlalarm gemeldet — das Tool prüfte nur `http://`, gebaut ist `https://…:443`; Einzeiler-Fix in `cf-sync.py`).
|
||||
> 📎 **Überholt:** Schritt-6-Teil „MCP-Clients auf FQDN umstellen" ist durch **TP35 Schicht 1**
|
||||
> **andersherum** entschieden (FQDN→LAN-IP). 🧹 Rest-Kleinkram (verwaistes `grafana`-Zertifikat) läuft
|
||||
> mit dem Grafana-Wiederaufbau nach TP32.
|
||||
> **Auslöser (User 2026-08-24):** „ich weigere mich, für public applications 2 cloudflare container zu
|
||||
> installieren. … ich habe [den Core] unter der prämisse gekauft, dass über diesen dann auch die public
|
||||
> apps laufen können. wir wollten doch den core als single point of failure platzieren."
|
||||
@@ -2092,10 +2122,14 @@ Alles andere ist intern; **19 Ingress-Zeilen über drei Tunnel werden EINE Catch
|
||||
🔑 **Deshalb als Paar bauen** — TP32 reserviert `110`/`111` fuer DNS, und die geloeschten
|
||||
Altlasten hiessen nicht zufaellig `adguard-bf1`/`adguard-bf2`: die Redundanz war urspruenglich
|
||||
schon einmal geplant. **Ein einzelner AGH waere ein DNS-SPOF auf pve.**
|
||||
5. **Tunnel `bf-public`** + Connectoren auf ap1/ap2, CNAMEs umhängen (`n8n` → `gitea` → `hass` → `vw`).
|
||||
6. **Abbau:** `bf-nas`/`bf-pve`/`bf-mm` löschen, sechs Container weg, SSH-Browser-Rendering entfällt,
|
||||
**MCP-Clients auf FQDN umstellen** (`~/.claude.json` spricht heute `10.40.20.105:9583` und
|
||||
`10.40.20.173:3000` roh; `n8n-mcp`/`gitea-mcp` kommen dabei wieder in Betrieb).
|
||||
5. ✅ **ERLEDIGT via [TP16.3](#tp163) §5 (2026-09-01) — Tunnel `bf-public`** + Connectoren auf ap1/ap2/ap3
|
||||
(12 conns healthy), CNAMEs geflippt (`n8n`/`gitea`/`hass`/`vw` → CF → Caddy `https://10.40.20.40:443`).
|
||||
Je Name einzeln geflippt, dazwischen gemessen; Antwortzeiten vorher/nachher unverändert.
|
||||
6. ✅ **ERLEDIGT via [TP16.3](#tp163) §6 (2026-09-01) — Abbau:** `bf-nas`/`bf-pve`/`bf-mm` gelöscht,
|
||||
7 cloudflared-Container weg. 🔴 **Ausnahme, bewusst umgekehrt:** der Teil „**MCP-Clients auf FQDN
|
||||
umstellen**" ist durch **TP35 Schicht 1** **andersherum** entschieden — `gitea-mcp`/`n8n-mcp` sprechen
|
||||
heute die **LAN-IP** (`10.40.20.167:3000`/`:3001`), nicht den FQDN. Der ursprüngliche Plan ist damit
|
||||
gegenstandslos, nicht offen.
|
||||
|
||||
#### ✅ Stand 2026-08-25 nach dem Bau — Caddy laeuft, zwei Backends fielen dabei auf
|
||||
**17 von 17 Zertifikaten** per DNS-01 von Let's Encrypt geholt, Dienst `active`+`enabled`,
|
||||
@@ -2320,16 +2354,6 @@ kann in Ruhe nachziehen.
|
||||
|
||||
---
|
||||
|
||||
### TP34 — Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle) ▸ 🔜 STUB
|
||||
> **Konzept + Architektur-Skizze:** [`docs/handoff-20260827-inventur-und-architektur.md`](handoff-20260827-inventur-und-architektur.md) — bitte dort weiterlesen (Architektur-Abschnitt).
|
||||
- **Scope:** Reverse-Proxy-Hosts werden im **Nautobot-Datenmodell** gepflegt (Site, Host, Backend-Spec). **Golden Config** rendert den Caddyfile aus den Daten, Diff-Check gegen die Live-Version auf `caddy-bf1`, Compliance-Checks + Transaktionen identisch zum bestehenden Workflow für Router-Configs.
|
||||
- **Auslöser (Inventur 2026-08-27):** der Caddyfile (`bf-infra/caddy/Caddyfile`) ist heute **manuell gepflegt** — kein Drift-Check, keine Transaktionen, andere Projekte können keine Sites anlegen ohne Christoph. Lösung: **Nautobot/GC**, kein Caddy-API-Sidecar (kein zweites SSoT).
|
||||
- **Erster Anwendungsfall:** `terpene.teilzeitladen.xyz → http://10.40.20.167:8890` (Mac-mini-Backend, dort PostgREST + sync + web via lokalem Caddy `:8890`). Vor TP34: manueller Quick-Win-Caddy-Block.
|
||||
- **Abh.:** TP22 (GC-Pipeline) ✅ vorhanden · TP23 (DNS-Policy + Caddy-Voraussetzungen) ✅ Stufe 1. Hängt an **nichts**, eigene Implementierung im Runbook nach dem Quick-Win.
|
||||
- **Status:** 🔜 Stub; Konzept + Architektur-Skizze vollständig in Handoff-Datei. Implementierung in eigenem Runbook nach terpene-Caddy-Quick-Win.
|
||||
|
||||
---
|
||||
|
||||
### TP35 — MCP-Schichtung global/projekt/user + 3-Schicht-CLAUDE.md + Announcement-Mechanismus + Backup-Guard ▸ ⏳ **ANGELEGT 2026-08-28, Schicht 1 (FQDN→IP) + Schicht 3 (globale Regeln) + Schicht 6 (Skill) ✅**
|
||||
- **Auslöser:** Bestandsaufnahme Session 2026-08-28 (Handoff `docs/handoff-20260828-pre-opencode-migration.md`). Erkenntnis: MCP-Configs sind heute über `~/.config/opencode/opencode.jsonc` UND `~/.claude.json` verstreut, ohne klares Schema.
|
||||
- **Befund (geprüft):** 11/12 Backups im Verzeichnis `~/dev/.pre-opencode-migration-backups/20260828-150335/` gzip-valid; `uwe-job-bewerbung.tar.gz` korrupt (Source unverändert da). Repos und globale Configs md5-/HEAD-identisch zum Vor-Session-Stand. Synology-Drive-Sync aktiv (Anwender, manuell).
|
||||
@@ -2347,20 +2371,136 @@ kann in Ruhe nachziehen.
|
||||
|
||||
---
|
||||
|
||||
### TP36 — SSoT via Nautobot für `teilprojekte.md`-Live-Daten + Datei-Aufteilung ▸ 🔜 ANGELEGT 2026-08-28, Scope-Ausarbeitung eigene Session
|
||||
- **Auslöser:** Skill-Run 2026-08-28 (`docs/handoff-20260828-session-a-projektstatus.md`) lieferte „Nächster Schritt (2026-08-26): TP31 Schritt 5" als Output, obwohl seit dem 26. drei Folge-Sessions parallel offen waren. **Manuell gepflegte Doku mit Live-Daten verliert gegen die Realität, sobald sie lang wird.**
|
||||
- **Befund:** Drei Stellen pro Edit berücksichtigen müssen — Quick-Index (Tabelle), TP-Abschnitt, Ist-Stand-Block. Keine schlägt die andere. Wer eine ändert, **muss** die anderen mitlesen. Die Datei hat aktuell 1940 Zeilen, der Ist-Stand-Block steht bei Z. 28, das Archiv-Cover bei Z. 1771. Strukturelles Risiko, kein Einzelfall.
|
||||
- **Scope (Skizze, eigene Session):**
|
||||
1. **Nautobot Custom Fields für Live-Daten** — RouterOS-Version, Compliance-Zahl (104/104, 26 Rules × 4 Geräte), DHCP-Server-Anzahl, MGMT-IPs, DNS-Upstream-Modus. Script `nautobot/gc-snapshot.py` rendert `docs/teilprojekte.md` (oder einen schmaleren Ersatz) als **read-only Snapshot**.
|
||||
2. **Datei-Aufteilung** — `docs/teilprojekte-index.md` (1 Seite: nur aktive TPs, Titel + Status + Datum), `docs/teilprojekte-aktuell.md` (Live-Snapshot aus Nautobot), `docs/teilprojekte-archiv.md` (bleibt Volltext). `/projektstatus`-Skill liest Index + Archiv, nicht die Snapshot-Datei.
|
||||
3. **Archiv-Anzeige im Quick-Index** — die heute 34 Namen stehen heute in *einer* Zeile am Ende. Sichtbarkeit = „Geschichte zählt". Quick-Index-Block bekommt eine zweite Tabelle mit „abgeschlossen seit …" und Link aufs Archiv.
|
||||
4. **Migrationspfad** — kompatibel mit bestehendem Workflow (`/projektstatus`-Skill konsumieren, niemand außer mir editiert Live-Markdown). Testphase = beide Dateien parallel führen.
|
||||
- **Abgrenzung:** TP36 ist Querschnitt, nicht Kern-BF. Eigene Session, eigener Handoff. Nicht heute.
|
||||
- **Verzahnt mit:** TP22 (Nautobot-GC als Vorbild), TP35 (geht Hand in Hand — beide sind „SSoT + Konsolidierung"), `bf-infra/CLAUDE.md`-Lessons.
|
||||
- **Referenzen:** Lessons-Block-Eintrag „Manuell gepflegte Doku mit Live-Daten verliert gegen die Realität" · Handoff Session A 2026-08-28.
|
||||
### TP36 — Index/Status als SSoT nach Gitea (Steuerung aus der branchbaren Datei herauslösen) ▸ ⏳ **CUTOVER 2026-09-07** — Index/Status = Gitea-Issues, Prosa bleibt Datei
|
||||
- **Auslöser:** Skill-Run 2026-08-28 (`docs/handoff-20260828-session-a-projektstatus.md`) lieferte einen überholten „Nächster Schritt"-Output; **manuell gepflegte Doku mit Live-Daten verliert gegen die Realität, sobald sie lang wird.** Verschärft 2026-09-06: `docs/teilprojekte.md` wurde in **40/40** letzten Commits angefasst — jeder TP editierte Quick-Index **und** Ist-Stand-Block → **Merge-Konflikt-Magnet**, der Branch-pro-TP verhinderte (ein Parallel-Branch hatte so die TP37-Doppelvergabe verursacht).
|
||||
- 🔄 **Reframe 2026-09-06 (Christoph):** von „SSoT via **Nautobot**" auf „SSoT via **Gitea**". Grund: Index+Status sind **kuratierte Steuerung** (Reihenfolge, Marker, Abhängigkeiten), kein Geräte-Live-Zustand — die gehören auf ein **Issue-Board**, nicht in Custom Fields. **Nautobot bleibt nur für Live-Gerätedaten** relevant (Compliance-Zahl, RouterOS-Version …) → als optionaler Rest unten, entkoppelt von diesem TP.
|
||||
- **Modell (umgesetzt):** TP = **Gitea-Issue** in [`admin/bf-infra`](https://gitea.emsenhuber.net/admin/bf-infra/issues) · Status = Label `status:*` (todo/wip/paused/idea/concept/done/dropped) · Gruppierung = Label `thema:*`. Seeder `bin/gitea-tp-sync.py` (idempotent, Dry-Run default, `--commit` schreibt; Token aus `~/.hermes/.env`, **nie ausgeben**). Erstlauf: **68 Issues (25 open/43 closed) + 15 Labels**.
|
||||
- ✅ **Erledigt (A1–A3):** Labels/Modell · 68 TPs → Issues · Board = Index (Label-Filter statt Handtabelle).
|
||||
- ⏳ **Cutover 2026-09-07 (diese Session):**
|
||||
- **A4** — Quick-Index-Tabelle + „Ist-Stand (Kurz)"-Block aus dieser Datei entfernt; Header zeigt aufs Gitea-Board; die vier **Genehmigten Ausnahmen** unter eigenem Governance-Header behalten. Alle `### TPnn`-Prosa bleibt.
|
||||
- **A5** — `/projektstatus` liest Baum+Status aus der **Gitea-API** (Issues + `status:*`/`thema:*`), Transaktionen weiter aus `nautobot/gc-transaktion.py status`, Prosa-Detail bei Bedarf aus dem Repo. Beide Skill-Kopien (`~/.claude/skills/…` **und** `~/.config/opencode/skills/…`, `cp`, kein Symlink).
|
||||
- **A6** — Projekt-`CLAUDE.md`: Pflichtlektüre = Gitea-Board (Status) + Prosa-Datei (Detail); Branch-Konvention (`tpNN-kurz` jederzeit, Merge nach `main` wenn Code/Config steht, Steuerungs-Updates nach Gitea); SSoT-Notiz.
|
||||
- 🔜 **Optionaler Rest (entkoppelt, „TP36-Live"):** Live-Daten-CustomFields auf den **4 `dcim.Device`** (`ros_version`, `compliance_pct`, `dhcp_server_count`, `mgmt_ip`, `dns_upstream_mode`) + Snapshot-Skript `nautobot/gc-snapshot.py` (existiert noch nicht). Unabhängig von diesem Cutover; nur relevant, wenn die Doku Live-Zahlen tragen soll. ⚠️ **Namensfalle bereinigt:** `nautobot/tp36-cf-estate-seed.py` gehörte **nie** zu TP36 → seit 2026-09-06 `tp44-cf-estate-seed.py`.
|
||||
- **Verzahnt mit:** TP35 (SSoT + Konsolidierung), TP44 (native Nautobot-Modelle), `bf-infra/CLAUDE.md`-Lessons. Plan: `~/.claude/plans/geht-das-los-auch-reflective-lark.md`.
|
||||
|
||||
<a id="tp37"></a>
|
||||
### TP38 — Out-of-Band-Management: ein untagged-VLAN99-Port je Switch ▸ 🔜 **ANGELEGT 2026-08-31**
|
||||
|
||||
*(Nummer 2026-08-31 von 37 auf 38 korrigiert und von Christoph bestätigt: TP37 war zeitgleich in
|
||||
einem zweiten Branch für „Nautobot als Netzwerkdoku" vergeben worden.)*
|
||||
|
||||
> **Auslöser (User 2026-08-31, aus eigener Anschauung):** *„ich durfte beim Neustart vom core gerade
|
||||
> erleben, dass ich nicht mehr auf den branch zum verbinden kam. weil das eben alles über den core
|
||||
> läuft."*
|
||||
|
||||
#### Der Befund, live nachgemessen (2026-08-31)
|
||||
Das Management des Standorts hat **einen einzigen Weg**, und der führt über den Core:
|
||||
|
||||
| | `crs326-core` | `crs326-branch` |
|
||||
|---|---|---|
|
||||
| Mgmt-IP | `10.40.99.1` (VLAN99-SVI) | `10.40.99.2` (`vlan99` auf der Bridge) |
|
||||
| VLAN99 auf der Bridge | SVI + Trunks | **`tagged=ether1,ether24,bridge`**, `untagged=""` |
|
||||
| Weg dorthin | direkt | **nur über `ether1` → core `ether8`** |
|
||||
|
||||
⇒ **`crs326-branch` ist ausschließlich durch den Core hindurch erreichbar.** Rebootet der Core, ist der
|
||||
Branch für die Dauer weg — nicht weil er ausfällt, sondern weil der einzige Pfad zu ihm fehlt. Dasselbe
|
||||
gilt für jeden Fehler, der den Core-Trunk oder dessen VLAN99-Konfiguration betrifft. **Wer den Core
|
||||
zerkonfiguriert, verliert den Branch gleich mit** — und damit die Möglichkeit, es vom Branch aus zu
|
||||
reparieren.
|
||||
|
||||
🔴 **Der zweite Befund ist der unangenehmere: `crs326-branch` hat KEINE `input`-Firewallregeln** (Kette
|
||||
leer, live gelesen). Sein gesamter Schutz besteht heute darin, dass VLAN99 nur über den Core erreichbar
|
||||
ist und **dessen** `forward`-Kette seit TP5 deny-by-default fährt. **Die Erreichbarkeitsbeschränkung
|
||||
IST die Zugangskontrolle.** Das ist für die Lösung unten kein Detail, sondern die Hauptauflage.
|
||||
|
||||
#### Zielbild
|
||||
**Je Switch ein Port, untagged in VLAN99** — ein Laptop direkt daran erreicht das Gerät ohne jeden
|
||||
Umweg über den Core, ohne Trunk, ohne funktionierendes Routing.
|
||||
|
||||
```
|
||||
Laptop ──(statische IP 10.40.99.x/24)── ether23 (untagged VLAN99) ── crs326-branch 10.40.99.2
|
||||
^ funktioniert auch, wenn der Core steht
|
||||
```
|
||||
|
||||
**Kandidat `ether23` auf beiden Geräten** — auf core **und** branch heute `running=false`, also frei,
|
||||
und symmetrisch (ein Port, eine Nummer, an beiden Standorten dieselbe). *(Core hat reichlich freie
|
||||
Ports; auf dem Branch sind `ether23` und die Reihe darunter frei, `ether24` ist ap2.)*
|
||||
|
||||
#### Umsetzung (Skizze — eigene Session)
|
||||
1. **Port aus dem Trunk-Verhalten nehmen und in VLAN99 untaggen:**
|
||||
`bridge port` mit `pvid=99` + `frame-types=admit-only-untagged-and-priority-tagged`,
|
||||
dazu `ether23` als `untagged`-Member in die `bridge vlan`-Zeile für VLAN99.
|
||||
2. **Kein DHCP dort** — der VLAN99-DHCP läuft auf dem Core, und genau der soll ja nicht Voraussetzung
|
||||
sein. ⇒ **statische IP am Laptop** (`10.40.99.50/24`), im Runbook mitschreiben.
|
||||
3. **Beschriftung.** Ein OOB-Port, den niemand erkennt, wird im Zweifel für „ist ja frei" gehalten.
|
||||
4. **Abnahme, die den Zweck wirklich prüft:** Laptop an `ether23` des Branch, **Core-Trunk `ether1`
|
||||
gezogen** (oder Core im Reboot) → `10.40.99.2` muss antworten. Alles andere misst nur den Normalfall.
|
||||
|
||||
#### 🔴 Auflage, ohne die das TP nicht gebaut werden darf
|
||||
Ein untagged-MGMT-Port ist **ein physischer Generalschlüssel**: wer ihn steckt, steht ungefiltert im
|
||||
Management-VLAN eines Geräts, das (Branch) keinerlei `input`-Filter hat. Deshalb gehört **eine** der
|
||||
folgenden Absicherungen dazu, und die Entscheidung darüber in die Umsetzungs-Session:
|
||||
- **Port `disabled=yes` im Normalbetrieb**, im Bedarfsfall am *anderen* Gerät freigeschaltet — schützt,
|
||||
kostet aber genau dann Zugriff, wenn das andere Gerät weg ist (halbierter Nutzen, ehrlich benennen);
|
||||
- **oder** `input`-Regeln auf beiden Switches nachziehen (der Branch braucht sie ohnehin — das ist die
|
||||
eigentliche Lücke, die dieses TP nebenbei aufgedeckt hat);
|
||||
- **oder** rein physisch: abschließbarer Schrank, Port beschriftet und dokumentiert.
|
||||
|
||||
⚖️ **Meine Einschätzung:** die `input`-Regeln sind der richtige Weg, weil sie eine Lücke schließen, die
|
||||
**unabhängig von diesem TP** besteht. Der OOB-Port macht sie nur sichtbar.
|
||||
|
||||
#### Abgrenzung
|
||||
- **Nicht** Teil von TP16.3 — dort wird nur festgestellt, dass dreimal Geräte rebooten, deren Mgmt am
|
||||
Core hängt. TP37 entschärft das für künftige Sessions, ist aber **keine Voraussetzung** dafür.
|
||||
- **Nicht** VLAN-Schema-Änderung (TP32 bleibt unberührt), **nicht** Konsolen-/Serial-Zugang (das wäre
|
||||
echtes OOB im engeren Sinn; hier geht es um ein zweites *Netz*-Bein).
|
||||
- **Abh.:** TP5 (Firewall-Systematik, liefert das Muster für die `input`-Regeln), TP15 (Portbelegung
|
||||
beider CRS326), TP22 (die Umsetzung läuft über Golden Config, `ip-firewall-filter` und
|
||||
`bridge`-Sektionen stehen unter Drift-Kontrolle).
|
||||
|
||||
---
|
||||
|
||||
### TP40 — Home-Assistant-Recorder-Retention: die 41-GB-`states`-Tabelle beschneiden ▸ 🔜 **ANGELEGT 2026-09-01 (User-Okay erteilt)**
|
||||
|
||||
**Auslöser:** LXC 302 (MariaDB) lief am 2026-09-01 auf **100 %** voll. Sofortmassnahme war `+30G`
|
||||
(TP39 Punkt 3), aber 59 der 65 GB sind die **`homeassistant`-Datenbank**, und die wächst weiter —
|
||||
`+30G` verschiebt das Problem um ~4 Wochen, es löst es nicht.
|
||||
|
||||
#### Befund (live gemessen)
|
||||
|
||||
| Tabelle | Größe |
|
||||
|---|---|
|
||||
| `homeassistant.states` | **41 GB** |
|
||||
| `homeassistant.state_attributes` | 8,6 GB |
|
||||
| `homeassistant.statistics_short_term` | 8,1 GB |
|
||||
| `homeassistant.statistics` / `events` | je ~0,7 GB |
|
||||
|
||||
Der HA-Recorder schreibt **unbegrenzt** — es ist keine `purge_keep_days`-Grenze wirksam, sonst wäre
|
||||
`states` nicht auf 41 GB gewachsen. Das ist ein Konfigurations-, kein Plattenproblem.
|
||||
|
||||
#### Scope
|
||||
|
||||
1. **HA-`recorder`-Retention setzen** (`configuration.yaml` bzw. `.storage`): `purge_keep_days`
|
||||
auf einen bewussten Wert (Vorschlag 30) — **Christoph entscheidet die Zahl**, das ist eine
|
||||
Aufbewahrungs-Policy, keine rein technische Größe.
|
||||
2. **Rauschende Entities ausschließen** (`recorder: exclude`) — die üblichen Verdächtigen sind
|
||||
hochfrequente Sensoren (Leistung, Netz-Durchsatz, `sensor.time`/`date`). Vorher per
|
||||
`SELECT COUNT(*) … GROUP BY entity_id` die Top-Schreiber ermitteln, nicht raten.
|
||||
3. **`recorder.purge` mit `repack: true`** — erst nach 1+2, sonst wächst es sofort nach. `repack`
|
||||
gibt den Plattenplatz auf InnoDB-Ebene **real** frei (ohne repack bleibt die `.ibd`-Datei gross).
|
||||
🔴 **`states` hängt per FK an `state_attributes` und `events`** — purge räumt beide mit; die
|
||||
Reihenfolge macht HA selbst, **nicht** von Hand einzelne Tabellen truncaten.
|
||||
4. **Danach die TP39-Vergrösserung bewerten:** schrumpft `states` deutlich, waren die `+30G`
|
||||
Vorhalt und keine Dauerlösung — die Platte lässt sich zwar nicht online verkleinern, aber der
|
||||
Druck ist weg.
|
||||
|
||||
#### Abgrenzung
|
||||
|
||||
- **Nicht** TP39: das ist LXC-/DB-Hygiene (Resolver, `networking`, `skip-name-resolve`). Der
|
||||
Resize tauchte dort nur auf; die **Ursache** (HA-Retention) ist HA-seitig und darum ein eigenes TP.
|
||||
- 🔴 **Kein eigenmächtiger Datenlöschvorgang** — `purge` wirft echte Historie weg; die
|
||||
Aufbewahrungsdauer ist eine Nutzerentscheidung. Diese Session hat **nur** vergrössert und gemessen.
|
||||
|
||||
### TP37 — Nautobot als durchgehende Netzwerkdoku: Hosts/Container/Dienste, erster Anwendungsfall CF-Connectoren ▸ 🔜 ANGELEGT 2026-08-30 (User-Okay erteilt)
|
||||
> **Christophs Formulierung (2026-08-30):** *„können wir das setup mit den cf-connectoren dann auch in
|
||||
> nautobot abbilden. quasi eine durchgehende netzwerkdoku stück für stück. muss eh fast sein, da du auf
|
||||
@@ -2385,10 +2525,10 @@ kann in Ruhe nachziehen.
|
||||
„wo läuft was" steht.
|
||||
2. **Dienste abbilden** — `ipam.Service` je exponiertem Port (Caddy `:80/:443`, AdGuard `:53`,
|
||||
Nautobot `:8080`, n8n `:5678`, …). Das ist Nautobot-Kernmodell, **keine eigene App nötig**.
|
||||
3. **CF-Connectoren als erster Anwendungsfall** — Tunnel (`bf-public`, historisch `bf-mm`/`bf-nas`/`bf-pve`)
|
||||
als Objekt, Connector als Relation Tunnel↔Host, Ingress-Regel als Hostname→Backend-Paar.
|
||||
Modellwahl offen: Custom Fields + Relationships auf Bestandsmodellen **oder** eine kleine eigene App.
|
||||
🔴 **Erst Punkt 1–2 entscheiden, dann diese Frage** — umgekehrt entsteht ein Modell für einen Sonderfall.
|
||||
3. ✅ **CF-Connectoren — ERLEDIGT via [TP44](teilprojekte-archiv.md#tp44) (Etappe 1, 2026-09-02).** Die Modellwahl ist damit
|
||||
entschieden: **native `nautobot.cloud`-Modelle** (Tunnel/WARP = `CloudNetwork`, VPC/Hyperdrive/Worker/
|
||||
Access-App = `CloudService`, IDs/Ports/Origins in `extra_config`), **keine eigene App**. Offen nur noch
|
||||
TP44 Etappe 2 (CF-API→Nautobot-Sync). ⇒ **Punkt 1+2 unten sind der echte Rest von TP37.**
|
||||
4. **Drift-Check** — Skript liest CF-API (`cfd_tunnel` + `configurations`) und vergleicht gegen Nautobot,
|
||||
analog `nautobot/gc-configplan.py --refresh-compliance`. **Read-only zuerst**; ob Nautobot je nach
|
||||
Cloudflare *schreibt*, ist eine spätere, eigene Entscheidung.
|
||||
@@ -2406,7 +2546,11 @@ kann in Ruhe nachziehen.
|
||||
die Pipeline ist stabil und **104/104 compliant**. TP37 vergrößert die Angriffsfläche dieser Pipeline.
|
||||
Deshalb Punkt 1–2 als eigener, abnehmbarer Schritt **mit Compliance-Gegenprobe danach**, nicht als
|
||||
Nebeneffekt von Punkt 3.
|
||||
- **Status:** 🔜 angelegt 2026-08-30, Scope-Ausarbeitung in eigener Session. Kein Runbook.
|
||||
- **Status:** ⏳ **Punkt 3 (CF) ✅ via TP44; Punkt 1+2 (Substrat + Dienste) offen** — das ist die
|
||||
fehlende Voraussetzung für TP34. Datenmodell **entschieden 2026-09-06 (native Modelle:
|
||||
`virtualization.Cluster/VirtualMachine` + `ipam.Service`, keine App)**. Runbook liegt jetzt vor:
|
||||
[`handoff-20260906-tp37-34-36-plan.md`](handoff-20260906-tp37-34-36-plan.md). Live-Ausgangslage:
|
||||
VM 0 · Cluster 0 · `ipam.Service` 0 · CustomField 0 (2026-09-06 gegen die API gelesen).
|
||||
|
||||
---
|
||||
|
||||
@@ -2426,7 +2570,7 @@ Kurzorientierung, wo was zu finden ist:
|
||||
| **Firewall / QoS** | [TP5](teilprojekte-archiv.md#tp5) deny-by-default · [TP26](teilprojekte-archiv.md#tp26) `ip-firewall-filter` unter Drift-Kontrolle · [TP6](teilprojekte-archiv.md#tp6) CAKE *(geschlossen statt gebaut)* · [TP6.1](teilprojekte-archiv.md#tp6-1) Upload-Priorisierung |
|
||||
| **Discovery / Media** | [TP7](teilprojekte-archiv.md#tp7) mDNS · [TP7.1](teilprojekte-archiv.md#tp7-1) SSDP-Relay · [TP7.2](teilprojekte-archiv.md#tp7-2) HA↔Sonos |
|
||||
| **Hosts / Migration** | [TP14](teilprojekte-archiv.md#tp14) (+[.1](teilprojekte-archiv.md#tp14-1)/[.2](teilprojekte-archiv.md#tp14-2)/[.2a](teilprojekte-archiv.md#tp14-2a)/[.3](teilprojekte-archiv.md#tp14-3)/[.5](teilprojekte-archiv.md#tp14-5)) VLAN20-Cutover · [TP17](teilprojekte-archiv.md#tp17) Shelly→VLAN30 · [TP19](teilprojekte-archiv.md#tp19) VLAN1-Retirement |
|
||||
| **Control-Plane** | [TP20](teilprojekte-archiv.md#tp20) Platform-Postgres · [TP21](teilprojekte-archiv.md#tp21) Nautobot GC · [TP22](teilprojekte-archiv.md#tp22) Adoption + Compliance-Push · [TP27](teilprojekte-archiv.md#tp27) RouterBOOT 7.24 · [TP-R](teilprojekte-archiv.md#tp-r) Capabilities-Sweep |
|
||||
| **Control-Plane** | [TP20](teilprojekte-archiv.md#tp20) Platform-Postgres · [TP21](teilprojekte-archiv.md#tp21) Nautobot GC · [TP22](teilprojekte-archiv.md#tp22) Adoption + Compliance-Push · [TP27](teilprojekte-archiv.md#tp27) RouterBOOT 7.24 · [TP-R](teilprojekte-archiv.md#tp-r) Capabilities-Sweep · [TP44](teilprojekte-archiv.md#tp44) CF-Estate Doku-SSoT |
|
||||
| **Zugang** | [TP10](teilprojekte-archiv.md#tp10) Multi-Site-VPN *(offen nur der DDNS-Updater, s. Follow-ups)* · [TP16.1](teilprojekte-archiv.md#tp16-1) natives CF-Mesh |
|
||||
| **Verworfen** | [TP9](teilprojekte-archiv.md#tp9) Gateway-HA (User-Entscheid 2026-08-08) |
|
||||
|
||||
@@ -2581,3 +2725,78 @@ TP22 · TP-R · **TP3.2** (08-17) · **TP5** (08-18) · **TP7.1** (08-18) · **T
|
||||
7. **Foundation (2026-07-14):** **TP15** (MikroTik-Switching / Omada-WLAN, 2× CRS326 bestellt) ∥ **TP20 (Platform-Postgres, single-site replication-ready)** → **TP21 (Nautobot Golden Config)** ∥ **TP20.1 (Vaultwarden→PG + 2-Site-HA)**. TP20 hängt an **TP18 ①** (Garage-Bucket für pgBackRest).
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
### TP43 — dw-Standort: interne BF-DNS-Namen über WG auflösbar machen ▸ ✅ **UMGESETZT 2026-09-11** — dw-FritzBox: Upstream `.36`+`.37`, DNS-Rebind-Ausnahme `bf.emsenhuber.net`, Fallback-Haken „öffentliche NS bei Unreachbarkeit" **gesetzt** (Ideal-Variante: `.37`-Redundanz bleibt, BF-down → public). (verworfene 420-Historie am Ende dieses Abschnitts)
|
||||
|
||||
**Live-Auslöser (2026-09-11):** Christoph am dw-Standort, WG-Tunnel zu BF up, kann `portainer.bf.emsenhuber.net`
|
||||
nicht erreichen. Direkte IP `https://10.40.20.126:9443` geht ⇒ **reines DNS-, kein Routing-Problem.** Der
|
||||
dw-Client nutzt die FritzBox (`10.95.10.1`) als Resolver; die kennt die interne Zone `bf.emsenhuber.net`
|
||||
(Split-Horizon `.36/.37 → 10.40.20.40` Caddy) nicht.
|
||||
|
||||
**Korrektur gegenüber dem verworfenen Scope:** Der ursprüngliche Fall (`420.teilzeitladen.xyz`) ist ein
|
||||
**öffentlicher** CF-Worker und war nie das Problem — der ist via TP41/WARP + CF Access gelöst. Das echte,
|
||||
offene Problem sind **interne** BF-Namen (`*.bf.emsenhuber.net`) über den WG-Tunnel.
|
||||
|
||||
**Live verifiziert (2026-09-11, `dig @10.40.20.36` über den Tunnel):** `portainer.bf.emsenhuber.net
|
||||
→ 10.40.20.40` (Caddy), `macmini.bf.emsenhuber.net → 10.40.20.167` — alle internen bf-Namen landen
|
||||
in `10.40.0.0/16`, über WG erreichbar. `ds-fm`/`gateway-fm.emsenhuber.net → 188.114.96.10/.97.10`
|
||||
= **Cloudflare-Anycast** (public), **nie `10.101.0.x`**. ⇒ **Der fm-Einwand (10.101.x intern ohne
|
||||
Pfad von dw) trifft für `.36/.37` nicht zu** — fm läuft über den public `fm.emsenhuber.net`-Tunnel,
|
||||
nicht über interne Records. (WG-Topologie TP10: dw-Peer AllowedIPs BF-seitig = `10.40.0.0/16`, dw
|
||||
routet **nicht** nach `10.101.0.0/24`.)
|
||||
|
||||
**Constraint am dw:** die 24/7-Geräte `10.95.10.246/.247` sind **Cudy-APs (kein DNS-Host)**; die
|
||||
FritzBox kann **kein Per-Zone-Forwarding** (nur einen globalen Upstream) **und per DHCP nur EINE
|
||||
DNS-IP ausliefern** (⇒ „mehrere NS an die Clients" scheidet aus). Ein echter conditional forwarder
|
||||
(dnsmasq `server=/bf.emsenhuber.net/.36`) bräuchte einen Zusatz-Dauerläufer — abgelehnt.
|
||||
|
||||
**Entscheidung (Christoph, 2026-09-11): FB-Upstream + Rebind-Ausnahme.** Clients bekommen per DHCP
|
||||
`10.95.10.1` (die FB selbst, Default); die **FB forwardet an die BF-Resolver**: *DNS-Server → „Andere
|
||||
DNSv4-Server"* Bevorzugt **`10.40.20.36`**, Alternativ **`10.40.20.37`** (beide BF, beide
|
||||
Voll-Resolver → Redundanz bleibt). Sauberer als der zwischenzeitliche DHCP-Multi-Gedanke: die FB ist
|
||||
der **einzige** Client-Resolver und `.36` löst **intern und public** auf → alles geht zuerst an `.36`,
|
||||
public wird nur als Unreachable-Fallback konsultiert, **nie „zuerst"** → kein NXDOMAIN-Leak im
|
||||
Normalbetrieb.
|
||||
|
||||
🔴 **DNS-Rebind-Schutz-Ausnahme `bf.emsenhuber.net`** (*Heimnetz → Netzwerk → Netzwerkeinstellungen →
|
||||
DNS-Rebind-Schutz*) ist **zwingend**: sonst filtert die FB die Privat-IP-Antworten (`10.40.x`) als
|
||||
Rebind-Angriff weg → bf-Namen liefern nichts, obwohl `.36` korrekt antwortet. Die Ausnahme ist ein
|
||||
reines Namens-Whitelist (keine IP).
|
||||
|
||||
**BF-down-Fallback (Verzweigung am FRITZ!OS-Stand):** Christoph erinnert ein Setting „öffentliche NS
|
||||
verwenden, wenn die primären nicht erreichbar sind". Vorhanden → aktivieren, Upstream bleibt
|
||||
`.36`+`.37`, BF-down geht auf public. Fehlt → Alternativ-Slot statt `.37` auf **public `9.9.9.9`**
|
||||
(kostet `.37`-Redundanz); dann zusätzlich prüfen, dass die FB **strikt primär** fragt (nicht
|
||||
round-robbt), sonst NXDOMAIN-Leak für `bf.*` bei BF-up.
|
||||
|
||||
- **BF-up:** FB → `.36` → interne `bf.*` (→ `.40`, dank Rebind-Ausnahme durchgereicht) **und** public.
|
||||
- **BF-down:** `.36`/`.37` unreachable → public-Fallback → public lebt, `bf.*` = NXDOMAIN (erwartet).
|
||||
|
||||
**Bewusst akzeptierter Tradeoff:** bei BF-up läuft Geli's **gesamter** Haushalt-DNS über Linz
|
||||
(`.36`/AdGuard-Filter) — vermeidbar nur mit conditional forwarder (Zusatz-HW, abgelehnt).
|
||||
|
||||
**On-site-Verifikationen (Christoph, am dw):** (1) Rebind-Ausnahme greift — `nslookup
|
||||
portainer.bf.emsenhuber.net` über die FB → stabil `10.40.20.40`; (2) BF-down-Fallback vorhanden
|
||||
(Setting) oder via public-Alternativ-Slot gesetzt; (3) nur falls BF+public gemischt: FB fragt strikt
|
||||
primär. Rückfall pro Gerät: `/etc/hosts` `10.40.20.40 <name>` oder WARP `fallback_domains
|
||||
bf.emsenhuber.net → [.36,.37]` (TP41-Präzedenz).
|
||||
|
||||
**Sofort-Workaround (läuft unabhängig):** `https://10.40.20.126:9443` direkt bzw.
|
||||
`/etc/hosts`-Zeile `10.40.20.40 portainer.bf.emsenhuber.net`.
|
||||
|
||||
**Abhängigkeiten:** WG-Route dw→`10.40.0.0/16` (steht). Grenzt an TP42 (interner Namensraum
|
||||
`bf.emsenhuber.net`) und TP10 (Multi-Site-VPN). **Umsetzung = eigene On-site-Session** (FritzBox-DHCP
|
||||
ist Christophs manueller Schritt, kein Tool-Zugriff).
|
||||
|
||||
---
|
||||
|
||||
**Historie — verworfener 420-Scope (angelegt 2026-09-01, verworfen 2026-09-11):**
|
||||
|
||||
**Auslöser (2026-09-01, TP41-Follow-up):** Geli soll `420.teilzeitladen.xyz` am dw-Standort erreichen.
|
||||
Split-Horizon am dw scheitert an der **FritzBox** (`10.95.10.1`): kein Per-Host-A-Override im Standard
|
||||
(nur DNS-Rebind-Ausnahmen ohne IP). Christoph: *„keine Chance im FritzBox-Standard? … lieber ein TP als
|
||||
uns verfranzen. Geli kommt rein, das zählt."* — Diese Prämisse fiel weg: `420.teilzeitladen.xyz` ist ein
|
||||
public CF-Worker hinter CF Access (löst auf CF-Anycast), kein BF-Origin ⇒ dafür braucht es kein
|
||||
Split-Horizon; Zugang via TP41-**WARP** gelöst (Geli 2026-09-10 via Android). Der Override-Bedarf für
|
||||
**interne** Namen blieb dabei übersehen — deshalb reopened, s.o.
|
||||
|
||||
727
docs/tp16.3-bf-public-ap-connector-runbook.md
Normal file
727
docs/tp16.3-bf-public-ap-connector-runbook.md
Normal file
@@ -0,0 +1,727 @@
|
||||
# TP16.3 / TP31 Schritt 5 — Runbook: `bf-public`-Connector auf ap1 / ap2 / **ap3**, CNAME-Flip, Abbau
|
||||
|
||||
> **§1–§3 AUSGEFÜHRT 2026-08-31.** Drei Connectoren laufen, `bf-public` healthy/12.
|
||||
> §2.2, §3.4 und §3.5 sind unten **korrigiert** — die ursprüngliche Fassung war an drei
|
||||
> Stellen falsch (Flash-Budget, `docker save`-Format, `envs`-Parametername).
|
||||
> ✅ **§5 (Flip) AUSGEFÜHRT 2026-09-01** — alle vier Namen auf `bf-public`.
|
||||
> Offen bleibt nur **§6 (Abbau)**.
|
||||
> **Löst [`tp31-schritt5-runbook.md`](tp31-schritt5-runbook.md) ab** (Stand 08-27). Jenes Dokument
|
||||
> kennt ap3 nicht, unterstellt einen Registry-Pull (geht bei `fetch: no` nicht) und enthält **eine
|
||||
> nachweislich falsche Freigabe-Behauptung** (§8 Falle 2). Es bleibt als Historie liegen, ist aber
|
||||
> **nicht mehr auszuführen**.
|
||||
|
||||
**Charakter:** Vor-Ort-Session. Der `device-mode`-Wechsel verlangt an **jedem** der drei APs eine
|
||||
**physische** Bestätigung — ap1 + ap3 in **Technik UG**, ap2 in **Technik OG**.
|
||||
|
||||
---
|
||||
|
||||
## §0 Ist-Stand (live gelesen 2026-08-30, ~20:45)
|
||||
|
||||
### Die drei APs — **sie sind NICHT gleich**
|
||||
|
||||
| AP | IP | Modell | Arch | ROS **live** | Flash frei | RAM frei | `device-mode` | `container` | `fetch` |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| **ap1** | 10.40.99.11 | hAP ax² (`C52iG`) | arm64 | **7.24.1** | 95 MB / 128 | 712 MB | `home` | ❌ `no` | ❌ `no` |
|
||||
| **ap2** | 10.40.99.12 | hAP ax² (`C52iG`) | arm64 | **7.24.1** | 95 MB / 128 | 699 MB | `home` | ❌ `no` | ❌ `no` |
|
||||
| **ap3** | 10.40.99.13 | **cAP ax** (`cAPGi`) | arm64 | **7.24.1** | 96 MB / 128 | 689 MB | **`basic`** | ❌ `no` | ✅ `yes` |
|
||||
|
||||
*(Versionsspalte am **2026-08-31** nachgelesen: Christoph hat alle fünf MikroTik auf **7.24.1** gehoben,
|
||||
RouterBOOT mitgezogen. Bis 08-30 liefen ap1/ap2 auf 7.24 — daher stand hier vorher eine Zwei-Dateien-Regel.)*
|
||||
|
||||
✅ **Seit dem Upgrade auf 7.24.1 (2026-08-31) reicht EINE `.npk` für alle drei APs** — alle sind `arm64`
|
||||
und alle auf derselben Version. Die frühere Zwei-Dateien-Regel war **rein versionsbedingt**, nicht
|
||||
modellbedingt: `cAP ax` und `hAP ax²` teilen sich die `arm64`-Pakete.
|
||||
🔴 **Die Regel dahinter gilt weiter:** ein `container.npk` **muss exakt zur RouterOS-Version passen** —
|
||||
sonst bleibt es nach dem Reboot deaktiviert. Wer künftig einen AP einzeln hebt, hat wieder zwei Dateien.
|
||||
|
||||
🟡 **Ein Unterschied bleibt:**
|
||||
- **ap3 steht auf `device-mode=basic`**, nicht `home` — dort sind `fetch`/`scheduler` bereits erlaubt.
|
||||
Das ändert am `container`-Flag nichts (auch dort `no`, auch dort physische Bestätigung), macht ap3
|
||||
aber zum einzigen AP, der theoretisch aus der Registry ziehen könnte. **Wir nutzen das bewusst
|
||||
nicht** — gleicher `.tar`-Weg auf allen dreien, damit alle drei dasselbe Image fahren.
|
||||
|
||||
*(Auf ap3 lief zum Lesezeitpunkt 4 h Uptime — frisch in Betrieb. Uplink laut Registry `core ether21`.)*
|
||||
|
||||
### Cloudflare
|
||||
|
||||
| Tunnel | ID | Status | Connectoren |
|
||||
|---|---|---|---|
|
||||
| **bf-public** | `48d3b0b6-7233-4781-a76a-1de4a5e957ce` | **inactive** | **0** ← Ziel dieser Session |
|
||||
| bf-mm | `7a322261-380a-447b-97d2-8ebce99f5ed1` | healthy | 8 |
|
||||
| bf-nas | `220c9958-401b-4111-9451-f3db09bba2d5` | healthy | 8 |
|
||||
| bf-pve | `f7fdf3a6-b67d-4567-93b1-b0f273794d09` | healthy | 8 |
|
||||
| `fm.emsenhuber.net` | `b697d124-…` | healthy | 4 | 🚫 **Standort FM — nicht anfassen** |
|
||||
| `terpene-db` | `b83b68f0-…` | healthy | 4 | 🚫 **anderes Projekt — nicht anfassen** |
|
||||
|
||||
**Heutige Wege der vier öffentlichen Namen** (alle noch **an Caddy vorbei**, direkt aufs Backend):
|
||||
|
||||
| Name | CNAME → Tunnel | Ingress-Ziel |
|
||||
|---|---|---|
|
||||
| `n8n` | bf-mm | `http://10.40.20.167:5678` |
|
||||
| `gitea` | bf-nas | `http://10.40.20.157:3000` |
|
||||
| `vw` | bf-nas | `http://10.40.20.127` |
|
||||
| `hass` | bf-pve | `http://10.40.20.105:8123` |
|
||||
|
||||
**`bf-public` hat bereits alle vier Ingress-Regeln** → `http://10.40.20.40:80` (Caddy) + Catch-all 404.
|
||||
⚠️ Genau dieses `:80` ist Blocker A, siehe §1.1.
|
||||
|
||||
### Caddy (`caddy-bf1`, LXC 130, `10.40.20.40`) — gemessen
|
||||
|
||||
| Name | `:80` | `:443` (SNI korrekt) |
|
||||
|---|---|---|
|
||||
| `vw` / `hass` / `n8n` / `gitea` | **308 → `https://…`** | **200** |
|
||||
|
||||
### Die sechs Container, die am Ende weg müssen — alle drei Hosts verifiziert
|
||||
|
||||
| Host | Zugang | Container |
|
||||
|---|---|---|
|
||||
| LXC 400 (pve) | `ssh root@10.40.20.100` → `pct exec 400 -- docker` | `cloudflared-bfmm`, `cloudflared-bfnas` |
|
||||
| macmini | `ssh macmini` | `cloudflared-bfpve`, `cloudflared-bfnas` |
|
||||
| NAS DS923 | Portainer `endpointId=14` | `cloudflared-bfpve`, `cloudflared-bfmm` |
|
||||
|
||||
🚫 **`terpene-cloudflared` auf LXC 400 bleibt** (Tunnel `terpene-db`, anderes Projekt). Steht im
|
||||
`docker ps` **direkt neben** den beiden zu löschenden — beim Löschen den Namen lesen, nicht die Zeile zählen.
|
||||
|
||||
### Rollback-Material (2026-08-30 **neu angelegt**, es gab es vorher nicht)
|
||||
|
||||
```
|
||||
docs/cf-backup/bf-public-ingress-20260830-vor-tp16.3-schnitt.json
|
||||
docs/cf-backup/bf-mm-ingress-20260830-vor-tp16.3-schnitt.json
|
||||
docs/cf-backup/bf-nas-ingress-20260830-vor-tp16.3-schnitt.json
|
||||
docs/cf-backup/bf-pve-ingress-20260830-vor-tp16.3-schnitt.json
|
||||
docs/cf-backup/cnames-tunnel-20260830-vor-tp16.3-schnitt.json # inkl. Record-IDs für den Flip-Rollback
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §1 Drei Blocker — ✅ **ALLE ERLEDIGT 2026-08-31 (remote)**
|
||||
|
||||
> ✅ **Nichts davon ist vor Ort noch zu tun.** Abschnitt bleibt als Nachweis stehen; die Fixes sind
|
||||
> gemessen, nicht nur abgesetzt. **Vor Ort startet die Arbeit bei §2/§3.**
|
||||
>
|
||||
> | Blocker | Stand | Nachweis |
|
||||
> |---|---|---|
|
||||
> | **A** Redirect-Schleife (`:80`) | ✅ behoben | Ingress zeigt auf `https://10.40.20.40:443`, `originServerName` je Regel gesetzt |
|
||||
> | **B** Freigabe `vlan99 → vlan20:443` | ✅ behoben | Regel via Nautobot GC deployt, Plan `Completed`, am Gerät verifiziert, **135/135 compliant, 0 Drifts** |
|
||||
> | **C** `ROUTER_AP3_PASS` | ✅ behoben | in `~/.secrets/credentials.env` (`chmod 600`), REST-Auth gegen ap3 = **HTTP 200** |
|
||||
|
||||
### 1.1 ✅ Blocker A — `bf-public` zeigte auf `:80`, und Caddy antwortet dort mit 308
|
||||
|
||||
> **Erledigt 2026-08-31.** Ingress zurückgelesen: alle vier Namen → `https://10.40.20.40:443`,
|
||||
> `SNI` = der jeweilige Hostname. Der `PUT` unten ist der ausgeführte Stand, nicht mehr eine Aufgabe.
|
||||
|
||||
Gemessen: `curl -H "Host: vw.emsenhuber.net" http://10.40.20.40/` → **`308` → `Location: https://vw.emsenhuber.net/`**.
|
||||
|
||||
Der Weg wäre also: Browser → CF → Tunnel → Caddy `:80` → **308 zurück auf denselben öffentlichen
|
||||
Namen** → CF → Tunnel → Caddy `:80` → … ⇒ **`ERR_TOO_MANY_REDIRECTS`**, für alle vier Namen.
|
||||
|
||||
Das fällt heute niemandem auf, weil die drei Alttunnel **an Caddy vorbei** direkt aufs Backend gehen
|
||||
(§0) — die Schleife entsteht **erst** mit dem Umstieg auf Caddy als Origin.
|
||||
|
||||
**Fix:** Origin auf `https://10.40.20.40:443` mit **`originServerName` je Regel** (Caddy hält für alle
|
||||
vier Namen gültige LE-Zertifikate ⇒ **kein** `noTLSVerify` nötig, die Kette bleibt geprüft):
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
TID=48d3b0b6-7233-4781-a76a-1de4a5e957ce
|
||||
curl -s -X PUT -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" \
|
||||
"https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/cfd_tunnel/$TID/configurations" \
|
||||
-d "{\"config\":{\"ingress\":[
|
||||
{\"hostname\":\"vw.emsenhuber.net\",\"service\":\"https://10.40.20.40:443\",\"originRequest\":{\"originServerName\":\"vw.emsenhuber.net\"}},
|
||||
{\"hostname\":\"hass.emsenhuber.net\",\"service\":\"https://10.40.20.40:443\",\"originRequest\":{\"originServerName\":\"hass.emsenhuber.net\"}},
|
||||
{\"hostname\":\"n8n.emsenhuber.net\",\"service\":\"https://10.40.20.40:443\",\"originRequest\":{\"originServerName\":\"n8n.emsenhuber.net\"}},
|
||||
{\"hostname\":\"gitea.emsenhuber.net\",\"service\":\"https://10.40.20.40:443\",\"originRequest\":{\"originServerName\":\"gitea.emsenhuber.net\"}},
|
||||
{\"service\":\"http_status:404\"}]}}" | jq -r ".success"'
|
||||
```
|
||||
|
||||
**Abnahme:** `.success == true`, danach Ingress zurücklesen und die vier `https://…:443` sehen.
|
||||
|
||||
### 1.2 ✅ Blocker B — die Firewall liess MGMT → Caddy **nicht** durch
|
||||
|
||||
> **Erledigt 2026-08-31 über Nautobot Golden Config** (`gc-manual-plan.py --device crs326-core --deploy`,
|
||||
> Change-ID `TP16.3-BlockerB`, Plan `23e5b667-…` **Completed**), **nicht** per Direkt-Write — `ip-firewall-filter`
|
||||
> steht unter Drift-Kontrolle (TP26). Backup vorher: `core-pre-tp16.3-blockerB-20260831.backup` (TP22-Regel 3).
|
||||
> Danach `ingest-core-firewall.py --apply` (Re-Baseline) + `--refresh-compliance` ⇒ **135/135, 0 Drifts.**
|
||||
> **Position verifiziert:** die Regel sitzt direkt **vor** `TP5: log-only` und `TP5: deny-by-default`.
|
||||
> **Funktional verifiziert:** `/tool fetch` von ap3 auf `https://10.40.20.40` erreicht Caddy und bekommt
|
||||
> einen **TLS-Alert von Caddy selbst** — ein Alert kann nur vom Server kommen, das Paket ist also da.
|
||||
> Der Alert ist die **SNI-Abweisung** (Gegenprobe: ohne SNI `000`, mit korrektem SNI `200`) und genau
|
||||
> der Grund, warum `originServerName` in §1.1 gesetzt ist. **Kein Fehler, sondern der Beweis.**
|
||||
|
||||
Die `forward`-Kette des Core wurde vollständig gelesen (36 Regeln, Nr. 35 = `TP5: deny-by-default`).
|
||||
**Es gibt keine Regel `vlan99 → vlan20` für 80/443.** Die einzige Regel in dieser Richtung ist
|
||||
|
||||
```
|
||||
26 TP5-E2: MGMT->INFRA api-rueckweg
|
||||
chain=forward accept protocol=tcp in-interface=vlan99 out-interface=vlan20 src-port=8728
|
||||
```
|
||||
|
||||
— ein **Rückweg** der RouterOS-API, `src-port`, nicht `dst-port`. Sie trägt den Connector nicht.
|
||||
|
||||
🔴 **Der Vorgänger-Runbook behauptet in §0 wörtlich, „Regel 27 `MGMT→INFRA TCP` deckt `vlan99→vlan20:80`
|
||||
bereits ab ✅". Das ist falsch** — Regel 27 ist `IOT->INFRA http-rueckweg` (`in-interface=vlan30`).
|
||||
Ohne die Regel unten läuft der Connector in Regel 34 (`TP5-WOULD-DROP`, Log) und Regel 35 (Drop).
|
||||
|
||||
**Fix** (vor die Log-Regel setzen, nicht ans Ende):
|
||||
|
||||
```
|
||||
/ip firewall filter add chain=forward action=accept protocol=tcp \
|
||||
in-interface=vlan99 out-interface=vlan20 dst-address=10.40.20.40 dst-port=443 \
|
||||
comment="TP31: AP-cloudflared -> caddy-bf1" \
|
||||
place-before=[find comment~"TP5: log-only"]
|
||||
```
|
||||
|
||||
Über MikroMCP: `plan_changes` mit `dryRun:true`, dann `apply_plan`.
|
||||
|
||||
**Was NICHT gebraucht wird:**
|
||||
- **Egress zu Cloudflare** (QUIC udp/7844): Regel 13 `TP5-E2: LAN->WAN` (`out-interface-list=WAN`,
|
||||
ohne `in-interface`-Einschränkung) deckt das ab. ✅
|
||||
- **DNS für den Container**: Regeln 30–33 erlauben `LAN → 10.40.20.36/.37:53` aus **jedem** VLAN. ✅
|
||||
⇒ im Container `dns=10.40.20.36` setzen.
|
||||
|
||||
⚠️ **Damit die Regel greift, muss der Container-Verkehr auch wirklich als `vlan99` ankommen** — das
|
||||
`veth`-Netz `172.17.0.0/24` ist dem Core unbekannt und hätte keinen Rückweg. Deshalb ist das
|
||||
`masquerade` in §3.4 **nicht optional**, sondern die Voraussetzung dieser Regel.
|
||||
|
||||
### 1.3 ✅ Blocker C — `ROUTER_AP3_PASS` fehlte in `~/.secrets/credentials.env`
|
||||
|
||||
> **Erledigt 2026-08-31.** `ROUTER_AP3_USER`/`_PASS` nachgetragen, Datei `chmod 600`,
|
||||
> Sicherung `~/.secrets/credentials.env.bak-20260831`. Funktionsbeweis: REST-Auth gegen ap3 = **HTTP 200**.
|
||||
|
||||
Vorhanden sind `ROUTER_AP1_PASS`, `ROUTER_AP2_PASS`, `CRS326_CORE_PASS`, `CRS326_BRANCH_PASS`.
|
||||
Das **ap3-Passwort steht nur in `~/.claude.json`** (MCP-Env) — gegen die globale Konvention
|
||||
(`~/.secrets` ist der Credential-Store) **und** ein Problem für §3.2: der Reboot-Weg liest
|
||||
`SSHPASS` aus `~/.secrets`.
|
||||
|
||||
```bash
|
||||
# Wert aus ~/.claude.json übernehmen und ergänzen — Wert dabei NICHT auf stdout bringen:
|
||||
printf 'ROUTER_AP3_USER=admin\nROUTER_AP3_PASS=%s\n' "$(python3 -c "
|
||||
import json;print(json.load(open('$HOME/.claude.json'))['mcpServers']['mikromcp']['env']['ROUTER_AP3_PASS'])")" \
|
||||
>> ~/.secrets/credentials.env
|
||||
chmod 600 ~/.secrets/credentials.env
|
||||
grep -c '^ROUTER_AP3_PASS=' ~/.secrets/credentials.env # muss 1 sein
|
||||
```
|
||||
|
||||
⚠️ **`~/.secrets/credentials.env` ist kein sauberes `KEY=VALUE`-File** — ab Zeile ~69 stehen rohe
|
||||
WireGuard-Zeilen (`Endpoint:`, `AllowedIPs:`, `PersistentKeepalive:`). In **zsh** bricht
|
||||
`source` daran ab und lässt die Variablen **leer**, ohne Fehler. Alle Snippets hier laufen deshalb
|
||||
in `bash -c '…'`. **Wer das übersieht, jagt einen „ungültigen Token", der in Wahrheit ein leerer ist.**
|
||||
|
||||
---
|
||||
|
||||
## §2 Vorbereitung am Schreibtisch (vor der Fahrt, mit Internet)
|
||||
|
||||
### 2.1 Die `container.npk` holen — **eine Datei für alle drei APs**
|
||||
|
||||
```bash
|
||||
mkdir -p ~/tp16.3 && cd ~/tp16.3
|
||||
curl -fLO https://download.mikrotik.com/routeros/7.24.1/all_packages-arm64-7.24.1.zip
|
||||
unzip -o -j all_packages-arm64-7.24.1.zip 'container-7.24.1-arm64.npk'
|
||||
ls -la container-7.24.1-arm64.npk
|
||||
```
|
||||
*(URL am 2026-08-30 mit `HTTP 200` verifiziert.)*
|
||||
|
||||
⚠️ **Vor dem Upload gegenprüfen, dass das Gerät wirklich auf 7.24.1 steht** (`/system resource print`).
|
||||
Stimmt die Version nicht, ist die Datei die falsche — und das merkt man erst nach dem Reboot.
|
||||
|
||||
### 2.2 cloudflared als `.tar` bauen — 🔴 **KORRIGIERT 2026-08-31, die alte Fassung funktioniert nicht**
|
||||
|
||||
Zwei Gründe, warum `docker save` des offiziellen Images hier scheitert:
|
||||
|
||||
1. **Es passt nicht ins Flash.** Entpackt misst `cloudflare/cloudflared:2026.6.1`
|
||||
**72.926.208 B = 69,5 MiB** (`docker export | wc -c`), nicht die früher hier genannten 28 MB —
|
||||
das ist die *komprimierte* Archivgrösse. RouterOS braucht beim Import **Tar und entpacktes Abbild
|
||||
gleichzeitig**: 26,2 + 69,5 = **95,7 MiB gegen ~90 MiB frei**. ⚠️ **`docker image inspect .Size`
|
||||
lügt hier** (meldet 27.463.950); `docker history` summiert korrekt auf ~70 MB.
|
||||
2. **Das Format stimmt nicht.** Seit Docker 25 (containerd-Image-Store) schreibt `docker save` ein
|
||||
**OCI-Layout** (`blobs/sha256/`, gzip-Layer). RouterOS will docker-v1 und meldet
|
||||
**`no config found in manifest`** — klingt nach kaputtem Image, ist aber das Format.
|
||||
|
||||
**Stattdessen: Minimal-Image aus dem Binary bauen.** Das Binary im offiziellen Image ist
|
||||
**statisch gelinkt** und 36,8 MB gross; die restlichen ~33 MB sind distroless-Debian, das
|
||||
cloudflared nicht braucht.
|
||||
|
||||
```bash
|
||||
# Binary + CA-Bundle aus dem gepinnten Upstream-Image ziehen
|
||||
ssh macmini 'docker pull --platform linux/arm64 \
|
||||
cloudflare/cloudflared@sha256:6d91c121b803126f7a5344005d17a9324788fc09d305b6e2560ec6040a7ae283 \
|
||||
&& docker tag cloudflare/cloudflared@sha256:6d91c121b803126f7a5344005d17a9324788fc09d305b6e2560ec6040a7ae283 cfd:2026.6.1'
|
||||
ssh macmini 'C=$(docker create cfd:2026.6.1); \
|
||||
docker cp "$C":/usr/local/bin/cloudflared /tmp/cfd-bin; \
|
||||
docker cp "$C":/etc/ssl/certs/ca-certificates.crt /tmp/cfd-ca.crt; docker rm -f "$C"'
|
||||
scp macmini:/tmp/cfd-bin ~/tp16.3/cloudflared-linux-arm64
|
||||
scp macmini:/tmp/cfd-ca.crt ~/tp16.3/ca-certificates.crt
|
||||
|
||||
# docker-v1-Archiv direkt bauen (kein Docker-Umweg -> Format haengt nicht am Image-Store)
|
||||
python3 tools/build-cfd-image.py ~/tp16.3/cloudflared-linux-arm64 \
|
||||
~/tp16.3/ca-certificates.crt ~/tp16.3/cfd-min-arm64.tar
|
||||
```
|
||||
|
||||
**Ergebnis: 35,3 MiB Archiv, 35,3 MiB entpackt, Spitzenbedarf 70,6 MiB** — passt mit ~20 MiB Reserve,
|
||||
nach dem Löschen des Tars bleiben **54–55 MiB** frei.
|
||||
|
||||
🔑 **Der Pin ist die Binary-SHA256 `e93824f677eb2f072b0a42b7ad8b57e1ed76c6aed51b13ed805a6064a82d424e`.**
|
||||
cloudflared gibt sie beim Start selbst aus (`Version 2026.6.1 (Checksum e93824f6…)`) — damit ist im
|
||||
Log nachweisbar, dass alle drei APs dasselbe Binary fahren.
|
||||
|
||||
⚠️ **Gegenprobe vor dem Ausrollen:** `docker load -i` + `docker run --rm <tag> version` auf dem macmini.
|
||||
Ein Formatfehler fällt dort in Sekunden auf, auf dem AP erst nach einem 35-MiB-Upload.
|
||||
|
||||
### 2.3 Tunnel-Token bereitlegen
|
||||
|
||||
Der Token liegt bereits als `BF_PUBLIC_TUNNEL_TOKEN` in `~/.secrets/credentials.env`. Frisch ziehen
|
||||
(z. B. nach Token-Rotation) — **Ausgabe nie in eine Kommandozeile oder ins Transkript**:
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
TID=48d3b0b6-7233-4781-a76a-1de4a5e957ce
|
||||
T=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
|
||||
"https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/cfd_tunnel/$TID/token" | jq -r .result)
|
||||
echo "Token-Länge: ${#T}" # nur die Länge, nie der Wert
|
||||
printf "%s" "$T" > ~/tp16.3/bf-public.token; chmod 600 ~/tp16.3/bf-public.token'
|
||||
```
|
||||
|
||||
### 2.4 Backups je AP
|
||||
|
||||
```bash
|
||||
# je AP, über MikroMCP oder SSH:
|
||||
/system backup save name=vor-tp16.3-ap1 # bzw. -ap2 / -ap3
|
||||
/export file=vor-tp16.3-ap1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §3 Vor Ort — **je AP einzeln, komplett durchziehen, dann der nächste**
|
||||
|
||||
> **Reihenfolge: ap3 → ap2 → ap1.**
|
||||
> ap3 zuerst, weil dort am wenigsten hängt (frisch in Betrieb, 4 h Uptime) — wenn der Ablauf
|
||||
> irgendwo klemmt, klemmt er am unkritischsten Gerät. **ap1 zuletzt**, weil an ihm die
|
||||
> `crs326-core`-Seite des WLAN hängt.
|
||||
>
|
||||
> ⚠️ **Jeder Schritt hier trennt kurzzeitig das WLAN dieses APs** (zwei Reboots). Die CAPs holen
|
||||
> sich ihre Config nach dem Boot vom Manager (`crs326-core`) per **L2-Discovery auf `vlan99`** —
|
||||
> das kommt von selbst zurück, braucht aber ~1–2 min. **Nicht ungeduldig nachprovisionieren.**
|
||||
|
||||
### 3.1 `.npk` hochladen
|
||||
|
||||
| AP | Datei |
|
||||
|---|---|
|
||||
| ap1 (`.99.11`) | `container-7.24.1-arm64.npk` |
|
||||
| ap2 (`.99.12`) | `container-7.24.1-arm64.npk` |
|
||||
| ap3 (`.99.13`) | `container-7.24.1-arm64.npk` |
|
||||
|
||||
✅ **Seit 2026-08-31 dieselbe Datei überall** (alle drei `arm64` + 7.24.1).
|
||||
|
||||
```bash
|
||||
cd ~/tp16.3
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
SSHPASS="$ROUTER_AP3_PASS" sshpass -e scp -O container-7.24.1-arm64.npk admin@10.40.99.13:'
|
||||
```
|
||||
|
||||
🔴 **Niemals `sshpass -p`** — das schreibt das Passwort in die Kommandozeile und damit in `ps` und
|
||||
jeden argv-Trace. **Genau so ist am 2026-08-22 das Core-Passwort in ein Transkript geraten.**
|
||||
`-e` hält es in der Umgebung des Kindprozesses.
|
||||
|
||||
Gegenprobe vor dem Reboot — **die Datei muss wirklich liegen**, sonst rebootet man umsonst:
|
||||
```
|
||||
/file print where name~"container"
|
||||
```
|
||||
|
||||
### 3.2 Reboot (installiert das Paket)
|
||||
|
||||
🔴 **Der Reboot geht NICHT über MikroMCP.** Das `reboot`-Tool sendet einen `delay`-Parameter, den die
|
||||
REST-API auf ROS 7.24 nicht kennt (`unknown parameter delay`); `run_command` ist für `/system reboot*`
|
||||
per Deny-Policy gesperrt. Der Weg ist SSH:
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
SSHPASS="$ROUTER_AP3_PASS" sshpass -e ssh -o StrictHostKeyChecking=accept-new \
|
||||
admin@10.40.99.13 "/system reboot"'
|
||||
```
|
||||
|
||||
**Abnahme nach ~90 s:**
|
||||
```
|
||||
/system package print
|
||||
# muss jetzt DREI Pakete zeigen: routeros, wifi-qcom, container — alle gleiche Version
|
||||
```
|
||||
⚠️ **Steht `container` da mit abweichender Version oder `disabled=yes`, war es die falsche `.npk`.**
|
||||
Dann: Datei löschen, richtige hochladen, erneut rebooten. Nicht weitermachen.
|
||||
|
||||
### 3.3 `device-mode` — **der physische Schritt**
|
||||
|
||||
🔴 **Reihenfolge ist Pflicht: erst der Paket-Reboot (§3.2), dann `device-mode`.**
|
||||
Der Bestätigungs-Boot **installiert keine Pakete** — er verbraucht eine wartende `.npk`, ohne sie zu
|
||||
installieren. Am 2026-08-31 wurde auf ap1 versucht, beides in einem Stromzyklus zu erledigen (um einen
|
||||
Gang zu sparen): danach stand `container: yes`, die Datei war weg und `/system package print` zeigte
|
||||
**zwei** Pakete. Nachholen ging per SSH-Reboot, aber die Abkürzung spart nichts.
|
||||
|
||||
|
||||
```
|
||||
/system device-mode update container=yes
|
||||
```
|
||||
|
||||
Die Session **bricht danach ab** und RouterOS wartet auf eine Bestätigung **am Gerät** mit einer
|
||||
Frist (typisch **5 Minuten**, die Konsole nennt die genaue Deadline). Bestätigt wird durch:
|
||||
|
||||
**Weg A — Kaltstart (empfohlen, eindeutig):**
|
||||
> **Stecker ziehen, ~5 Sekunden warten, wieder einstecken.**
|
||||
|
||||
🔴 **Wichtig: die APs hängen NICHT an PoE aus den Switches** — beide CRS326 haben nachweislich gar
|
||||
kein PoE-Menü (`bad command name poe`). Es gibt also **keinen** Weg, das aus der Ferne zu tun; der
|
||||
Strom kommt vom jeweiligen Netzteil bzw. Injektor am AP.
|
||||
|
||||
**Weg B — Taster:**
|
||||
> **Reset-Knopf am laufenden Gerät kurz drücken und loslassen.** Am hAP ax² sitzt er an der
|
||||
> Unterseite, am cAP ax unter der Abdeckung an der Rückseite.
|
||||
|
||||
⚠️ **Weg B nur am LAUFENDEN Gerät und nur kurz.** Den Reset-Knopf **während des Bootens** gedrückt zu
|
||||
halten ist etwas völlig anderes — das setzt die Konfiguration zurück bzw. geht nach Netinstall.
|
||||
Wer unsicher ist, nimmt **Weg A**; ein Kaltstart kann nicht versehentlich zum Werksreset werden.
|
||||
|
||||
Verstreicht die Frist ohne Bestätigung, passiert **nichts** — die Änderung verfällt, das Gerät bleibt
|
||||
wie es war. Dann einfach neu absetzen.
|
||||
|
||||
**Abnahme:**
|
||||
```
|
||||
/system device-mode print
|
||||
# container: yes
|
||||
```
|
||||
|
||||
### 3.4 Container-Netz anlegen
|
||||
|
||||
```
|
||||
/interface veth add name=veth-cf address=172.17.0.2/24 gateway=172.17.0.1
|
||||
/ip address add address=172.17.0.1/24 interface=veth-cf
|
||||
/ip firewall nat add chain=srcnat action=masquerade src-address=172.17.0.0/24 \
|
||||
comment="TP31: cloudflared egress"
|
||||
```
|
||||
|
||||
Das `masquerade` ist **Pflicht**, nicht Kosmetik — siehe §1.2: ohne es kommen die Pakete mit
|
||||
`172.17.0.2` am Core an, wo weder Route noch Firewall-Regel sie kennt.
|
||||
|
||||
✅ **Seit 2026-08-31 stehen diese drei Zeilen im SOLL** (AP-Template Block `[7]`, Werte aus dem
|
||||
ConfigContext `ap-common` → `ap.container`). Wer sie hier direkt setzt, erzeugt daher **keine
|
||||
Drift mehr** — aber auch keinen Bedarf: bei einem neuen AP rendert Golden Config sie mit.
|
||||
|
||||
### 3.5 Image importieren und Container bauen
|
||||
|
||||
```bash
|
||||
# .tar hochladen (~28 MB)
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
SSHPASS="$ROUTER_AP3_PASS" sshpass -e scp -O ~/tp16.3/cloudflared-arm64.tar admin@10.40.99.13:'
|
||||
```
|
||||
|
||||
Auf dem AP:
|
||||
```
|
||||
/container config set tmpdir=tmp
|
||||
/container add file=cloudflared-arm64.tar interface=veth-cf root-dir=cf \
|
||||
dns=10.40.20.36 logging=yes start-on-boot=yes \
|
||||
cmd="tunnel --no-autoupdate run --token=<TOKEN>"
|
||||
```
|
||||
|
||||
🔑 **Token-Handling.** 🔴 **Die Eigenschaft heisst auf ROS 7.24.1 `list=`, NICHT `name=`** — mit
|
||||
`name=` antwortet das Gerät `bad parameter name` bzw. die REST-API `unknown parameter name`.
|
||||
(Das MikroMCP-Tool `manage_container_env` benutzt `name=` und ist damit hier unbrauchbar.)
|
||||
|
||||
Der Token darf weder in eine Kommandozeile (→ `ps`) noch ins Sitzungstranskript. Deshalb per Datei:
|
||||
|
||||
```bash
|
||||
T=$(cat ~/tp16.3/bf-public.token)
|
||||
TMP=$(mktemp /tmp/cfdenv.XXXXXX.rsc); chmod 600 "$TMP"
|
||||
{ printf '/container/envs/add list=cfd key=TUNNEL_TOKEN value="%s"\n' "$T"
|
||||
printf '/container/envs/add list=cfd key=TUNNEL_TRANSPORT_PROTOCOL value="quic"\n'; } > "$TMP"
|
||||
SSHPASS="$PW" sshpass -e scp -O "$TMP" admin@<ip>:cfdenv.rsc && rm -f "$TMP"
|
||||
```
|
||||
Auf dem AP: `/import file=cfdenv.rsc`, danach **`/file/remove [find name="cfdenv.rsc"]`** — die Datei
|
||||
enthält den Token im Klartext. Gegenprobe ohne Wert-Ausgabe:
|
||||
```
|
||||
:foreach e in=[/container/envs/find] do={:put ([/container/envs/get $e list] . " / " . \
|
||||
[/container/envs/get $e key] . " / len=" . [:len [/container/envs/get $e value]])}
|
||||
```
|
||||
⚠️ **Niemals `/container/envs/print`** — das gibt den Token aus.
|
||||
|
||||
Starten und aufräumen:
|
||||
```
|
||||
/container start [find root-dir=cf]
|
||||
/container print # status: running
|
||||
/file remove [find name~"cloudflared-arm64.tar"] # ~28 MB Flash zurückholen
|
||||
```
|
||||
|
||||
⚠️ **Platzrechnung (korrigiert 2026-08-31, gemessen):** ~90 MiB frei − 35,3 MiB `.tar`
|
||||
− 35,3 MiB entpacktes Abbild ≈ **20 MiB** in der Spitze, nach dem Löschen des Tars **54–55 MiB** frei.
|
||||
🔴 **Mit dem offiziellen Image wären es 95,7 MiB Bedarf gegen 90 MiB frei — es passt schlicht nicht.**
|
||||
Auch mit dem Minimal-Image gilt weiter: **ein Container pro AP**, kein zweiter.
|
||||
|
||||
### 3.6 Abnahme **auf diesem AP**
|
||||
|
||||
```
|
||||
/log print where message~"cloudflared" or message~"tunnel"
|
||||
# erwartet: "Registered tunnel connection" (mehrfach, je CF-Edge)
|
||||
```
|
||||
|
||||
Und **die Strecke zu Caddy separat prüfen** — sie ist der Teil, den Blocker B betraf:
|
||||
```
|
||||
/tool fetch url="https://10.40.20.40/" check-certificate=no output=none
|
||||
```
|
||||
*(Auf ap1/ap2 ist `fetch` per `device-mode=home` gesperrt — dort stattdessen aus dem Container heraus
|
||||
oder über den Drop-Log gegenprüfen, siehe §8.)*
|
||||
|
||||
**Der Drop-Log ist das erste Diagnosewerkzeug, nicht das letzte:**
|
||||
`10.40.20.18:514`, Dateien auf dem Docker-LXC unter `/opt/tp5-syslog/log/`, Präfix `TP5-WOULD-DROP`.
|
||||
Taucht dort `10.40.99.13 → 10.40.20.40:443` auf, fehlt die Regel aus §1.2.
|
||||
|
||||
### 3.7 Erst wenn dieser AP sauber ist: nächster AP
|
||||
|
||||
---
|
||||
|
||||
## §4 Abnahme des Tunnels (nach allen drei APs)
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
|
||||
"https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/cfd_tunnel/48d3b0b6-7233-4781-a76a-1de4a5e957ce" \
|
||||
| jq "{status:.result.status, conns:(.result.connections|length)}"'
|
||||
```
|
||||
|
||||
**Kriterium: `status: "healthy"`, `conns` > 0** (erfahrungsgemäß 4 CF-Edge-Verbindungen je Connector,
|
||||
bei drei APs also Richtung 12).
|
||||
|
||||
🔴 **`healthy` heißt „der Connector redet mit Cloudflare" — nicht „das Origin antwortet".** Der Beweis
|
||||
für die Strecke bis Caddy ist §5.1, nicht diese Zahl. Genau diese Verwechslung hat beim
|
||||
`grafana`-Fall monatelang einen toten Dienst gesund aussehen lassen.
|
||||
|
||||
---
|
||||
|
||||
## §5 CNAME-Flip — ✅ **AUSGEFÜHRT 2026-09-01** (einzeln, mit Abnahme dazwischen)
|
||||
|
||||
**Reihenfolge: `n8n` → `gitea` → `hass` → `vw`** (steigende Kritikalität; `vw` zuletzt).
|
||||
Zone-ID `1b5bc02fdf61b6b989afde543f3f4134`.
|
||||
|
||||
### 5.1 Vorab: Testname statt Produktivname
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
Z=1b5bc02fdf61b6b989afde543f3f4134
|
||||
curl -s -X POST -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" \
|
||||
"https://api.cloudflare.com/client/v4/zones/$Z/dns_records" \
|
||||
-d "{\"type\":\"CNAME\",\"name\":\"test-tp163\",\"content\":\"48d3b0b6-7233-4781-a76a-1de4a5e957ce.cfargotunnel.com\",\"proxied\":true}" | jq -r .success'
|
||||
```
|
||||
Dazu **eine Ingress-Regel** für `test-tp163.emsenhuber.net` → `https://10.40.20.40:443` mit
|
||||
`originServerName: vw.emsenhuber.net` in `bf-public` ergänzen. Dann **von außerhalb des LAN, ohne
|
||||
WARP** aufrufen.
|
||||
|
||||
🔑 **Das Erfolgskriterium ist praeziser, als es hier bis 2026-08-31 stand — und die frühere Fassung
|
||||
war zweideutig.** Gemessen am 2026-08-31 gegen `10.40.20.40`:
|
||||
|
||||
| Antwort | Bedeutung |
|
||||
|---|---|
|
||||
| Access-Login, danach **`200` mit LEEREM Body** und Header **`server: Caddy`** | ✅ **Strecke bewiesen.** Caddy hat geantwortet; es gibt für `test-tp163` nur kein Site-Block, und genau so antwortet Caddy auf einen unbekannten Host. |
|
||||
| **`404`** | ❌ Die Ingress-Regel greift nicht — das ist der **Catch-all** von `bf-public` (`http_status:404`). |
|
||||
| **`ERR_TOO_MANY_REDIRECTS`** | ❌ Blocker A ist zurück (Ingress auf `:80` oder `originServerName` fehlt). Sofort abbrechen. |
|
||||
|
||||
⚠️ **Ohne diese Tabelle liest man das leere 200 als „kaputt" und das 404 als „Caddy sagt nichts" —
|
||||
beide Male falsch herum.** Der zweite, unabhängige Beweis ist immer das Caddy-Log (§5.3).
|
||||
|
||||
⇒ Erst wenn das steht, wird ein Produktivname angefasst. Danach Testname + Testregel wieder entfernen.
|
||||
|
||||
### 5.2 Flip je Name
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
Z=1b5bc02fdf61b6b989afde543f3f4134
|
||||
N=n8n # danach: gitea, hass, vw
|
||||
ID=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
|
||||
"https://api.cloudflare.com/client/v4/zones/$Z/dns_records?name=$N.emsenhuber.net" | jq -r ".result[0].id")
|
||||
curl -s -X PATCH -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" \
|
||||
"https://api.cloudflare.com/client/v4/zones/$Z/dns_records/$ID" \
|
||||
-d "{\"content\":\"48d3b0b6-7233-4781-a76a-1de4a5e957ce.cfargotunnel.com\",\"proxied\":true}" | jq -r .success'
|
||||
```
|
||||
|
||||
### 5.3 Abnahme je Name — **von außerhalb des LAN, WARP AUS**
|
||||
|
||||
- [ ] Aufruf über Mobilfunk (oder anderer Standort) → Access-Login → **200**
|
||||
- [ ] **Kein** `ERR_TOO_MANY_REDIRECTS` (das wäre Blocker A)
|
||||
- [ ] 15 min beobachten, kein 530/1033
|
||||
|
||||
🔴 **KORRIGIERT 2026-09-01 — der frühere Punkt „Caddy sieht den Request:
|
||||
`journalctl -u caddy -n 20`" funktioniert NICHT.** Im `Caddyfile` steht keine `log`-Direktive; im
|
||||
Journal landen nur `info`/`warn`. Ein **erfolgreicher** Request hinterlässt dort **nichts**, und die
|
||||
leere Ausgabe liest sich wie „kam nie an". *(Dass der öffentliche Reverse Proxy überhaupt keine
|
||||
Requests protokolliert, ist eine eigene Lücke — gehört zu TP31/TP34.)*
|
||||
|
||||
**Was stattdessen funktioniert — und 2026-09-01 auch benutzt wurde:**
|
||||
|
||||
| Werkzeug | Beweist |
|
||||
|---|---|
|
||||
| `curl --resolve <name>:443:188.114.96.10` | Erzwingt den **öffentlichen** Weg. 🔴 **Pflicht**, denn der Haus-Resolver liefert für alle vier Namen direkt `10.40.20.40` (Split-Horizon) — ein Test von zuhause sieht Cloudflare **nie**. |
|
||||
| Verbindungstabelle am Core (`/ip firewall connection`) | Zeigt `10.40.99.x → 10.40.20.40` = ein AP-Connector redet mit Caddy. **Der Zähler der Blocker-B-Regel taugt dafür NICHT**: `cloudflared` hält die Origin-Verbindung offen, es entstehen kaum neue — der Zähler steht still, obwohl alles läuft. |
|
||||
| Antwort-Fingerabdruck | z.B. `i_like_gitea`-Cookie = echte Gitea-Antwort, nicht CF/Caddy. |
|
||||
| WebSocket-Handshake **mit `--http1.1`** | `101 Switching Protocols` = der Companion-App-Pfad steht. ⚠️ Über HTTP/2 gibt es keinen klassischen Upgrade — ein `400` ist dann der eigene Testfehler, nicht der Dienst. |
|
||||
|
||||
⚠️ **Access antwortet je nach Standort verschieden, beides gesund:** `n8n` liefert aus dem Haus
|
||||
**200** (die `bf4`-Policy trägt die WAN-IP), von außen **302** zum Login. `hass`/`vw`/`gitea` stehen
|
||||
auf **`bypass`** (App `hass, vw, gitea`, alle drei in `self_hosted_domains`) — dort kommt **nie** ein
|
||||
Login. Ein Service-Token für die Wildcard-App gibt es nicht (**TP14.4**), deshalb ist `n8n` von außen
|
||||
**nicht** bis zum Origin prüfbar — das musste der User im Browser bestätigen.
|
||||
|
||||
🔴 **WARP muss aus sein.** Mit aktivem WARP läuft der Test über den Mesh und beweist den öffentlichen
|
||||
Weg **nicht** — dieselbe Klasse Fehldiagnose wie beim ICMP-Fall 2026-08-13.
|
||||
|
||||
**Namensspezifisch:**
|
||||
- **`gitea`** — Access gilt **nur der Web-UI**, Git-/API-Pfade laufen daran vorbei. **Vor** dem Flip
|
||||
einen Push von außen testen, **nach** dem Flip denselben Push wiederholen.
|
||||
- **`hass`** — die Companion-App kann kein Access-Login. Nach dem Flip App auf dem Handy **über
|
||||
Mobilfunk** prüfen, nicht nur den Browser.
|
||||
- **`vw`** — Bitwarden läuft auf **Access-Bypass**. **Vor** dem Flip prüfen, dass die Bypass-Policy
|
||||
für `vw.emsenhuber.net` steht; sonst sperrt der Flip alle Bitwarden-Clients aus.
|
||||
|
||||
---
|
||||
|
||||
## §6 Abbau — ✅ **AUSGEFÜHRT 2026-09-01** (7-Tage-Frist vom User aufgehoben)
|
||||
|
||||
> ✅ **Durch.** 7 Container entfernt (inkl. `terpene-cloudflared`, weil `420.teilzeitladen.xyz` nun
|
||||
> über Caddy/CF läuft — vor der Tunnel-Löschung mit echtem Origin-Inhalt belegt), 4 Tunnel gelöscht
|
||||
> (`bf-mm`/`bf-nas`/`bf-pve`/`terpene-db`). Übrig: nur `bf-public` + `fm`. Reihenfolge Container→Tunnel
|
||||
> eingehalten. Der Rest dieses Abschnitts bleibt als Referenz stehen.
|
||||
|
||||
### (Original-Anleitung, Referenz)
|
||||
|
||||
> Die drei Alttunnel sind die Rückfallebene. Solange sie stehen, ist jeder Flip eine
|
||||
> Ein-Feld-Änderung zurück. **Nicht am selben Abend abbauen.**
|
||||
|
||||
### 6.1 Erst die Container stoppen, dann die Tunnel löschen
|
||||
|
||||
Umgekehrt genommen läuft man in 530er von Connectoren, die auf einen gelöschten Tunnel zeigen.
|
||||
|
||||
```bash
|
||||
# LXC 400 auf pve — terpene-cloudflared NICHT anfassen
|
||||
ssh root@10.40.20.100 'pct exec 400 -- docker rm -f cloudflared-bfmm cloudflared-bfnas'
|
||||
ssh root@10.40.20.100 'pct exec 400 -- docker ps --format "{{.Names}}"' # terpene-cloudflared muss bleiben
|
||||
|
||||
# macmini
|
||||
ssh macmini 'docker rm -f cloudflared-bfpve cloudflared-bfnas && docker ps --format "{{.Names}}"'
|
||||
```
|
||||
|
||||
NAS (DS923, Portainer `endpointId=14`, Key aus `mcp/portainer/.env`):
|
||||
```bash
|
||||
bash -c 'set -a; . ~/dev/bf-infra/mcp/portainer/.env; set +a
|
||||
K="${PORTAINER_API_KEY:-$PORTAINER_TOKEN}"; U="${PORTAINER_URL:-https://10.40.20.126:9443}"
|
||||
for c in cloudflared-bfpve cloudflared-bfmm; do
|
||||
ID=$(curl -sk -H "X-API-Key: $K" "$U/api/endpoints/14/docker/containers/json?all=true" \
|
||||
| jq -r ".[]|select(.Names[0]==\"/$c\")|.Id")
|
||||
curl -sk -X DELETE -H "X-API-Key: $K" "$U/api/endpoints/14/docker/containers/$ID?force=true"
|
||||
echo "removed $c"
|
||||
done'
|
||||
```
|
||||
⚠️ Sind es **Stacks** statt einzelner Container, kommen sie sonst beim nächsten Stack-Deploy zurück —
|
||||
dann den Stack-Eintrag entfernen, nicht nur den Container.
|
||||
|
||||
### 6.2 Dann die drei Tunnel löschen
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
for T in 7a322261-380a-447b-97d2-8ebce99f5ed1 220c9958-401b-4111-9451-f3db09bba2d5 f7fdf3a6-b67d-4567-93b1-b0f273794d09; do
|
||||
curl -s -X DELETE -H "Authorization: Bearer $CF_API_TOKEN" \
|
||||
"https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/cfd_tunnel/$T" | jq -r "{id:\"$T\",ok:.success}"
|
||||
done'
|
||||
```
|
||||
|
||||
🚫 **Nicht in dieser Schleife und nirgends sonst:** `b697d124-…` (`fm.emsenhuber.net`, Standort FM)
|
||||
und `b83b68f0-…` (`terpene-db`). **IDs vor dem Absetzen einzeln gegen §0 prüfen.**
|
||||
|
||||
### 6.3 Schlusskontrolle
|
||||
|
||||
```bash
|
||||
bash -c 'set -a; . ~/.secrets/credentials.env; set +a
|
||||
curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
|
||||
"https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/cfd_tunnel?is_deleted=false" \
|
||||
| jq -r ".result[]|\"\(.name)\t\(.status)\tconns=\(.connections|length)\""'
|
||||
```
|
||||
**Soll:** `bf-public healthy`, `fm.emsenhuber.net healthy`, `terpene-db healthy` — sonst nichts.
|
||||
|
||||
---
|
||||
|
||||
## §7 Rollback
|
||||
|
||||
| Lage | Rückweg |
|
||||
|---|---|
|
||||
| Ein Name kaputt nach Flip | CNAME zurück auf die alte Tunnel-ID — Werte in `cnames-tunnel-20260830-…json` (inkl. Record-ID) |
|
||||
| `bf-public`-Ingress kaputt | `PUT …/configurations` mit `bf-public-ingress-20260830-…json` |
|
||||
| Container auf einem AP stört | `/container stop` + `/container remove`, WLAN läuft davon unabhängig |
|
||||
| AP-Config verkorkst | `/system backup load name=vor-tp16.3-apX` |
|
||||
| Firewall-Regel unerwünscht | `/ip firewall filter remove [find comment~"TP31: AP-cloudflared"]` |
|
||||
|
||||
**`device-mode=container:yes` ist nicht Teil des Rollbacks.** Zurückdrehen ginge nur mit erneutem
|
||||
physischem Gang. Es schadet nicht — ohne laufenden Container ist es ein gesetztes Flag, sonst nichts.
|
||||
|
||||
---
|
||||
|
||||
## §8 Fallen
|
||||
|
||||
1. **`container.npk` ist versionsgebunden.** Seit 08-31 sind alle drei APs auf 7.24.1 ⇒ **eine** Datei.
|
||||
Weicht ein Gerät später ab, braucht es wieder seine eigene. Falsche Datei ⇒ Paket bleibt nach dem
|
||||
Reboot **inaktiv, ohne Fehler**. **Nach jedem Reboot `/system package print` lesen**, nicht annehmen.
|
||||
2. **Die Freigabe `vlan99 → vlan20:443` existiert nicht** — entgegen der Behauptung im
|
||||
Vorgänger-Runbook. Ohne §1.2 landet der Connector im `TP5-WOULD-DROP`-Log. **Erst dort nachsehen.**
|
||||
3. **Caddy antwortet auf `:80` mit 308.** Ein Ingress auf `:80` erzeugt eine Redirect-Schleife —
|
||||
und zwar **erst** beim Umstieg auf Caddy, weil die Altwege am Proxy vorbeigehen.
|
||||
4. **`healthy` ≠ „Dienst erreichbar".** Der Tunnelstatus sagt nichts über das Origin; die
|
||||
Wildcard-Access-App `*.emsenhuber.net` liefert für **jeden** Namen ein sauberes 302. Ein toter
|
||||
Dienst sieht so monatelang gesund aus (der `grafana`-Fall).
|
||||
5. **Kein `sshpass -p`.** Nur `-e` mit `SSHPASS` aus der Umgebung.
|
||||
6. **`~/.secrets/credentials.env` in zsh sourcen schlägt still fehl** (rohe WireGuard-Zeilen ab ~Z. 69)
|
||||
— Variablen bleiben **leer**, die API meldet einen „ungültigen Token". Immer `bash -c`.
|
||||
7. **`terpene-cloudflared` steht direkt neben den zu löschenden Containern.** Namen lesen.
|
||||
8. **Ein Container pro AP, keiner mehr.** Nach dem Import bleiben ~39 MB. Caddy oder AGH gehören
|
||||
nicht dazu (die eine Config ändert sich ständig, die andere schreibt dauernd auf NAND).
|
||||
9. **Reboot nie über MikroMCP** (`unknown parameter delay`), sondern per SSH.
|
||||
10. **WLAN-Abnahme ist eine frische DHCP-Lease je SSID, nicht die Registration-Table.**
|
||||
⚠️ Ergänzung 08-31: `media`/`untrusted`/`guest` haben im Normalbetrieb **null** Clients — dort ist
|
||||
gar kein Lease-Nachweis zu holen. Das ist kein Fehler, aber auch kein Beleg; nicht als „grün" buchen.
|
||||
11. 🔴 **Das offizielle `cloudflared`-Image passt nicht ins Flash** (69,5 MiB entpackt gegen ~90 MiB
|
||||
frei, Tar kommt obendrauf). Minimal-Image bauen, s. §2.2. **Flash-Budgets mit `docker export`
|
||||
messen, nie mit `docker image inspect .Size`.**
|
||||
12. 🔴 **`docker save` liefert seit Docker 25 OCI statt docker-v1** → `no config found in manifest`.
|
||||
13. 🔴 **`/container/envs` nimmt `list=`, nicht `name=`.**
|
||||
14. 🔴 **Der `device-mode`-Bestätigungs-Boot installiert keine Pakete** — Reihenfolge s. §3.3.
|
||||
15. ✅ **ERLEDIGT 2026-08-31 — §3.4 kollidierte mit der GC-Governance:** `ip address` und
|
||||
`ip firewall nat` stehen unter Drift-Kontrolle, direkt gesetzt ergab das **zwei `extra`-Drifts
|
||||
je AP**. Sie sind jetzt **ins Soll gehoben** (AP-Template Block `[7]` + ConfigContext
|
||||
`ap.container`), **nicht** als Transaktion geführt: ein Dauerzustand gehört ins Template.
|
||||
Dazu kam die **28. ComplianceRule `interface-veth`** — vorher war das veth das tragende Stück
|
||||
**ohne jede Überwachung**. 🔴 **Falle darin:** der veth-Export trägt zwei gerätevergebene MACs;
|
||||
ohne Normalisierung (`ConfigReplace` `60-`/`61-veth-*`) erzeugt die Regel Dauer-Drift auf allen
|
||||
drei APs. Stand danach: **139/140**, übrig nur die offene TP25-Transaktion.
|
||||
16. 🔴 **Ein Golden-Config-Job meldet `SUCCESS` und kann trotzdem halb durchgelaufen sein.**
|
||||
Am 2026-08-31 fehlte nach dem ersten Compliance-Lauf genau **ein** Eintrag
|
||||
(`crs326-core`/`interface-veth`), Job-Status `SUCCESS`, im Job-Log dagegen
|
||||
`RENDER COMPLIANCE TASK GROUP failed: Broken pipe`. **Abnahme ist deshalb nicht die
|
||||
Konformitätsquote, sondern die ANZAHL der Einträge = Regeln × Geräte.** 139 statt 140 sieht
|
||||
aus wie „die neue Regel greift nicht" und ist ein halb gelaufener Job. Zweiter Lauf reichte.
|
||||
17. 🟡 **`A - AVAILABLE` in `/system package print` ist ein Download-Katalog**, kein Paket auf dem
|
||||
Gerät — `enable` würde einen Internet-Fetch auslösen (auf ap1/ap2 gesperrt). `.npk` bleibt der Weg.
|
||||
18. 🟡 **MikroMCPs `export_config` exportiert unvollständig** (301 B statt 6,2 KiB). Für Backups
|
||||
`/export file=…` per SSH verwenden. Nach zwei
|
||||
Reboots je AP lohnt der Blick — die Tabelle zeigte beim CAPsMAN-Ausfall 14 h lang zufriedene
|
||||
Clients ohne Adresse.
|
||||
|
||||
---
|
||||
|
||||
## §9 Ehrliche Einschränkung — was diese Session **nicht** kauft
|
||||
|
||||
Solange Caddy **nur** auf `caddy-bf1` (LXC 130, pve) läuft, ist das Origin aller drei Connectoren
|
||||
**derselbe Rechner**. Drei Connectoren auf drei APs kaufen damit **Hardware-Diversität am Eingang,
|
||||
aber keine Verfügbarkeit**: fällt pve aus, sind alle vier öffentlichen Dienste weg — mit drei
|
||||
Connectoren genauso vollständig wie mit einem.
|
||||
|
||||
**Der Gewinn ist real, aber begrenzt:** kein Docker-Host mehr im öffentlichen Pfad (die APs sind
|
||||
eigene Maschinen ⇒ die macvlan/ipvlan-Blindheit kann dort prinzipiell nicht auftreten), sechs
|
||||
Container werden drei, und die Host→Origin-Zuordnung lebt nur noch im `caddy/Caddyfile`.
|
||||
|
||||
**Der echte Verfügbarkeitsgewinn kommt erst mit `caddy-bf2` (LXC 131)** und einer zweiten
|
||||
Ingress-Regel. ⚠️ Für `vw` gilt dabei die TP20.1-Bremse: zwei Caddys an verschiedenen Standorten
|
||||
würden die Hälfte der **Schreib**zugriffe auf einen read-only Standby schicken — das #1033-Muster,
|
||||
diesmal mit Datenverlust. **Automatisches Ingress-Failover erst, wenn der DB-Teil es trägt.**
|
||||
|
||||
Bis dahin ist die Reserve die manuelle: derselbe Connector kann über eine zusätzliche Ingress-Regel
|
||||
**direkt** auf ein kritisches Backend zeigen, an Caddy vorbei.
|
||||
134
docs/tp16.3-paragraph5-session-handoff-prompt.md
Normal file
134
docs/tp16.3-paragraph5-session-handoff-prompt.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Übergabeprompt — TP16.3 §5: CNAME-Flip auf `bf-public`
|
||||
|
||||
> **Zum Einfügen in eine frische Session.** Erstellt 2026-08-31, direkt nach §2/§3.
|
||||
> Live-Stand am 2026-08-31 gegengeprüft: 12 Connectoren, drei Container `running`,
|
||||
> Caddy mit SNI 200 / ohne SNI 000.
|
||||
> Alles unterhalb der Linie ist der Prompt.
|
||||
|
||||
---
|
||||
|
||||
TP16.3 / TP31 Schritt 5 — **§5 CNAME-Flip** (Repo `~/dev/bf-infra`).
|
||||
|
||||
Aufgabe: **§5 des Runbooks** `docs/tp16.3-bf-public-ap-connector-runbook.md` ausführen — die vier
|
||||
öffentlichen Namen von den Alttunneln auf `bf-public` umhängen. **§6 (Abbau) gehört NICHT dazu**,
|
||||
frühestens 7 Tage nach dem Flip.
|
||||
|
||||
## PFLICHTLEKTÜRE ZUERST, in dieser Reihenfolge
|
||||
|
||||
1. `docs/handoff-20260831-tp16.3-paragraph2-3-durch.md` — Ergebnis und Funde der Vorsession
|
||||
2. `docs/tp16.3-bf-public-ap-connector-runbook.md` **§5** (und §7 Rollback)
|
||||
3. `docs/teilprojekte.md` (Quick-Index + Ist-Stand + TP16.3-Abschnitt)
|
||||
|
||||
## REPO-STAND
|
||||
|
||||
Alles liegt auf **`main`** (`e474e5e`, Gitea `admin/bf-infra`) — Haupt-Checkout, Remote und der
|
||||
Arbeitsbranch der Vorsession sind identisch. **Von `main` aus starten**, nichts mehr mergen.
|
||||
Die Vorsession lief im Worktree `claude/stoic-khayyam-09b644`; der ist erledigt.
|
||||
|
||||
## AUSGANGSLAGE — nicht nochmal machen
|
||||
|
||||
- `bf-public` ist **healthy mit 12 Connectoren** (ap1/ap2/ap3, je ein `cloudflared 2026.6.1`,
|
||||
Container `running`, `start-on-boot=yes`). Tunnel-ID `48d3b0b6-7233-4781-a76a-1de4a5e957ce`.
|
||||
- Ingress steht auf `https://10.40.20.40:443` mit `originServerName` je Regel (Blocker A behoben).
|
||||
- Firewall-Freigabe `vlan99 → vlan20:443` auf `crs326-core` liegt und ist verifiziert (Blocker B).
|
||||
- Caddy antwortet **mit korrektem SNI 200, ohne SNI 000** — gemessen, das ist gesundes Verhalten.
|
||||
- Rollback-Material: `docs/cf-backup/` — Ingress-Configs, CNAMEs **inklusive Record-IDs**, und für
|
||||
drei Tunnel zusätzlich der ältere Stand als `*-vor-hostname-schnitt.json`.
|
||||
|
||||
## 🔴 ZUERST ENTSCHEIDEN, BEVOR EIN NAME GEFLIPPT WIRD
|
||||
|
||||
**Compliance steht auf 128/135.** Sechs `extra`-Drifts, zwei je AP: `ip-address`
|
||||
(`172.17.0.1/24 interface=veth-cf`) und `ip-firewall-nat` (`masquerade`, Kommentar
|
||||
`TP31: cloudflared egress`). Sie sind **inhaltlich richtig** — ohne sie läuft kein Container —, aber
|
||||
sie stehen nicht im Soll, weil Runbook §3.4 Direkt-Writes vorschreibt für Features, die unter
|
||||
Golden-Config-Kontrolle stehen.
|
||||
|
||||
Der saubere Weg ist, sie ins **Soll** zu heben (AP-Template bzw. ConfigContext `ap-common`).
|
||||
🔑 **Bewusst KEINE Transaktion:** `gc-transaktion.py` ist für **befristete Versuche** da (so wie
|
||||
`TP25-fund-e-ft-over-ds`). Das `veth`/`masquerade` soll **dauerhaft** gelten — Dauerzustand gehört
|
||||
ins Template, nicht in eine Transaktion mit Ablaufdatum.
|
||||
🔴 **Kein Re-Baseline** (macht die Drift-Erkennung wertlos), **kein Rückbau** (killt die Tunnel).
|
||||
⚠️ Dabei mitentscheiden, ob `/interface veth` überhaupt erfasst sein soll — dafür existiert heute
|
||||
keine ComplianceRule, deshalb erzeugt `veth` auch keine Drift.
|
||||
|
||||
Mit ungeklärter Drift in den Produktivpfad zu gehen ist die eine Sache, die diese Session
|
||||
**nicht** tun sollte. Christoph entscheidet, nicht die Session.
|
||||
|
||||
🔴 **Die siebte Drift ist KEINE Drift im Sinne eines Versehens:** `crs326-core` / `wifi-security`
|
||||
(`ft-over-ds=no`) ist **TP25 Fund E, Hebel 1** — am 2026-08-31 um 08:09 bewusst gesetzt und als
|
||||
**offene Transaktion `TP25-fund-e-ft-over-ds`** geführt (Scope `wifi-security`, Ablauf 2026-09-03).
|
||||
Sie gehört einer anderen, laufenden Session; **grün machen würde deren Versuch unsichtbar machen.**
|
||||
⚠️ **Merkregel:** vor jeder Drift-Bewertung `python3 nautobot/gc-transaktion.py status` lesen.
|
||||
Drift aus einem laufenden Versuch sieht identisch aus wie ein Versehen — genau dafür gibt es das
|
||||
Werkzeug. (Diese Zeile behauptete zuerst, die Drift käme vom 7.24.1-Upgrade. Falsch: der Core wurde
|
||||
erst um 14:36 gehoben, sechseinhalb Stunden nach dem Hebel.)*
|
||||
|
||||
## REIHENFOLGE
|
||||
|
||||
**Erst `test-tp163` (§5.1), dann `n8n` → `gitea` → `hass` → `vw`** — steigende Kritikalität, `vw`
|
||||
zuletzt. Nach **jedem** Namen die Abnahme aus §5.3, erst dann der nächste.
|
||||
|
||||
## WICHTIGSTE FALLEN
|
||||
|
||||
- 🔴 **`healthy` beweist nichts über das Origin.** Der Tunnelstatus sagt nur, dass der Connector mit
|
||||
Cloudflare redet. Die Wildcard-Access-App `*.emsenhuber.net` liefert für **jeden** Namen ein
|
||||
sauberes 302 — ein toter Dienst sieht so monatelang gesund aus (der `grafana`-Fall). Der einzige
|
||||
Streckenbeweis ist §5.1 gegen einen Testnamen.
|
||||
- 🔴 **WARP muss AUS sein.** Mit aktivem WARP läuft der Test über den Mesh und beweist den
|
||||
öffentlichen Weg nicht — dieselbe Fehldiagnose-Klasse wie der ICMP-Fall 2026-08-13. Testen von
|
||||
außerhalb des LAN, über Mobilfunk.
|
||||
- 🔴 **`vw` = Bitwarden läuft auf Access-Bypass.** **Vor** dem Flip prüfen, dass die Bypass-Policy
|
||||
für `vw.emsenhuber.net` steht — sonst sperrt der Flip alle Bitwarden-Clients aus.
|
||||
- 🔴 **`gitea`: Access gilt nur der Web-UI**, Git-/API-Pfade laufen daran vorbei. Push von außen
|
||||
**vor** und **nach** dem Flip testen, nicht nur die UI.
|
||||
- 🔴 **`hass`: die Companion-App kann kein Access-Login.** Nach dem Flip die App auf dem Handy über
|
||||
Mobilfunk prüfen, nicht nur den Browser.
|
||||
- ⚠️ **`ERR_TOO_MANY_REDIRECTS` nach einem Flip = Blocker A ist zurück** (Ingress auf `:80` statt
|
||||
`:443`, oder `originServerName` fehlt). Sofort zurückflippen, nicht debuggen während der Name tot ist.
|
||||
- ⚠️ **`~/.secrets/credentials.env` lässt sich in zsh nicht sourcen** (rohe WireGuard-Zeilen ab
|
||||
~Zeile 69) — Variablen bleiben still leer, das sieht aus wie ein ungültiger Token. **Immer `bash -c`.**
|
||||
- 🔴 **Maskierung: Muster auf den Schlüsselnamen ankern, nie auf ein Trennzeichen.**
|
||||
`grep -n "TOKEN" datei | sed 's/:.*TOKEN/…/'` maskiert **nicht** — `grep -n` stellt `<zeile>:`
|
||||
voran, und das matcht das Muster. So sind in der Vorsession zwei Nautobot-Tokens ins Transkript
|
||||
geraten. Sicher ist nur `sed -E 's/(TOKEN|PASSWORD|SECRET|KEY|PASS)=.*/\1=<redacted>/'`.
|
||||
|
||||
## GOVERNANCE
|
||||
|
||||
- Config-Änderungen an MikroTik-Geräten **ausschließlich** über Nautobot Golden Config
|
||||
(`nautobot/gc-manual-plan.py`), nicht per Direkt-Write. Nautobot: **`http://10.40.20.30:8080`**
|
||||
(Port 8080, **nicht** 80 — der Runbook-Stand nannte lange nur den Host), Token in
|
||||
`docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored, nur im Haupt-Checkout).
|
||||
- Cloudflare-Änderungen sind **outward-facing**: DNS-Flip und Ingress-Edits vor der Ausführung mit
|
||||
Christoph bestätigen, einer nach dem anderen.
|
||||
- **MCP-Lifecycle aktiv melden**, falls sich daran etwas ändert.
|
||||
|
||||
## OFFENE PUNKTE, DIE NICHT IN DIESE SESSION GEHÖREN
|
||||
|
||||
1. **Rotation zweier Nautobot-Tokens** (`NAUTOBOT_SUPERUSER_API_TOKEN`, `NAUTOBOT_GITEA_TOKEN`) —
|
||||
in der Vorsession ins Transkript geraten, als verbrannt zu behandeln. Gehört zu **TP30**.
|
||||
✅ **Von Christoph am 2026-08-31 ausdrücklich vertagt** („kommt später dran") — nicht von selbst
|
||||
anfangen, aber auch nicht vergessen: bis zur Rotation ist der Nautobot-Superuser-Token kompromittiert.
|
||||
2. **`crs326-core` / `wifi-security` / `ft-over-ds`** — offene Transaktion `TP25-fund-e-ft-over-ds`
|
||||
einer laufenden TP25-Session. **Nicht anfassen, nicht grün machen**, Ablauf 2026-09-03.
|
||||
3. **`mcp/mikromcp/config/routers.yaml`** meldet `rosVersion: "7.24"` für alle fünf, live ist
|
||||
`7.24.1` — kosmetisch, gehört auf `main`.
|
||||
4. **§6 Abbau** (sechs Container, drei Alttunnel) — frühestens 7 Tage nach dem Flip.
|
||||
🚫 `terpene-cloudflared` (LXC 400) und `fm.emsenhuber.net` bleiben, sie stehen im `docker ps`
|
||||
direkt neben den zu löschenden. **Namen lesen, nicht Zeilen zählen.**
|
||||
|
||||
## ABNAHME DIESER SESSION
|
||||
|
||||
- [ ] Entscheidung zu den sechs Drifts getroffen und umgesetzt (Compliance erklärt oder bereinigt)
|
||||
- [ ] `test-tp163` von außerhalb des LAN ohne WARP: Access-Login, **keine** Redirect-Schleife
|
||||
- [ ] Testname **und** Testregel danach wieder entfernt
|
||||
- [ ] Alle vier Namen geflippt, je einzeln mit 15 min Beobachtung, kein 530/1033
|
||||
- [ ] `gitea`-Push von außen funktioniert nach dem Flip
|
||||
- [ ] `hass`-Companion-App über Mobilfunk funktioniert nach dem Flip
|
||||
- [ ] `vw` Bitwarden-Clients funktionieren nach dem Flip
|
||||
- [ ] Caddy-Log zeigt die Requests (`ssh root@10.40.20.100 'pct exec 130 -- journalctl -u caddy -n 20'`)
|
||||
|
||||
## ARBEITSWEISE
|
||||
|
||||
Bestandsaufnahme vor Plan. Eine große Fragenrunde statt vieler kleiner. Bei Abweichungen zwischen
|
||||
Doku und Live-Stand: **Drift melden, nicht stillschweigend korrigieren.** Vor jedem Flip den
|
||||
Rollback-Weg (§7, Record-IDs in `docs/cf-backup/cnames-tunnel-*.json`) parat haben.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user