Compare commits
109 Commits
433e600f83
...
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 | |||
| 0680ccabc8 | |||
| d5b3ce37ff | |||
| 452ea53576 | |||
| 6f8ba8c8b5 | |||
| a0a650eb48 | |||
| badf715f5a | |||
| 40ffab1de8 | |||
| 810126c01b | |||
| 175486221b | |||
| b697ffc6fa | |||
| ed005fff2e | |||
| 65a61f7fb6 | |||
| 1006f91e6a | |||
| f7d26db7a6 | |||
| 70a983eaa3 | |||
| bc0bf316e1 | |||
| c82fb45f7f | |||
| 709cc626bb | |||
| fd05286e4b | |||
| dd12ab505b | |||
| 803a28772f | |||
| 39ba5da6b0 | |||
| bd1ba5ed13 | |||
| f1a8a4a3e7 | |||
| b9176914e2 | |||
| 733d911c03 | |||
| b8fd42b3fd | |||
| 3562e19e47 | |||
| c25888acd9 | |||
| b4cd417e8d | |||
| 55b3453d41 | |||
| d06d505bc3 | |||
| 8c1876c1d6 |
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,12 +1,19 @@
|
||||
.DS_Store
|
||||
.secrets
|
||||
|
||||
# Per-Projekt-MCP-Configs: können Tokens/URLs enthalten, projekt-spezifisch, nicht ins Repo
|
||||
.mcp.json
|
||||
|
||||
|
||||
# Python bytecode
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# NAS-VLAN20-Migration: Compose-Files/Inspects enthalten Live-Secrets → nicht committen
|
||||
docs/nas-vlan20/stacks/
|
||||
# 🔴 OHNE Schraegstrich: mit `stacks/` greift die Regel nur auf ein echtes Verzeichnis. In einem
|
||||
# git-worktree liegt hier ein SYMLINK auf den Haupt-Checkout (die Datei ist gitignored und
|
||||
# existiert deshalb nur dort) — und der war damit nicht ignoriert. Gefunden 2026-08-31.
|
||||
docs/nas-vlan20/stacks
|
||||
docs/nas-vlan20/inspect_*.json
|
||||
|
||||
# RouterOS-Config-Exports/Backups enthalten Live-Secrets (WiFi-Passphrasen etc.) → nicht committen
|
||||
@@ -15,3 +22,7 @@ routeros/ap1-wg-hub.privkey
|
||||
routeros/tp15-core-cutover-intended.rsc
|
||||
docs/tp6-marker/.current-run
|
||||
caddy/caddy.env
|
||||
|
||||
# Config-Backups, die Sessions vor destruktiven Edits anlegen (2026-08-30)
|
||||
*.bak-*
|
||||
docs/macmini-vlan20/stacks
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"gitea-mcp": {
|
||||
"type": "http",
|
||||
"url": "https://gitea-mcp.emsenhuber.net/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
219
CLAUDE.md
219
CLAUDE.md
@@ -6,20 +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. 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, **lokal, kein Gitea-Remote** (Working-Copy). Verloren bei Festplattencrash.
|
||||
- **`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`.
|
||||
|
||||
@@ -27,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 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.
|
||||
|
||||
---
|
||||
|
||||
@@ -57,10 +98,11 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
|
||||
|---|---|---|
|
||||
| ~~ALLNET Core-Switch (sw1)~~ | — | ❌ **außer Betrieb (2026-08-08)** — durch `crs326-core` (L3-Router + Core-Switch, Technik UG) ersetzt; physisch abgelöst. (Telnet-Runner `switch/` = nur noch historisch.) |
|
||||
| ~~Omada Access-Switch (sw2)~~ | — | ❌ **abgebaut 2026-07-23** (TP15 Branch-Tausch) — durch `crs326-branch` in Technik OG ersetzt, physisch entfernt |
|
||||
| **crs326-branch** (CRS326, Technik OG) | **10.40.99.2** (VLAN99) · Bootstrap Rev4 2026-08-08 | RouterOS **7.24** · `admin`/`~/.secrets` (`CRS326_BRANCH_*`) · REST `http://10.40.99.2/rest` · MikroMCP `crs326-branch` ✅ **live** (2026-08-16 verifiziert) · **TP15 ✅: ersetzt sw2** (L2-Switch), volle Portbelegung (ether1 Uplink-Trunk, 2/8 NAS, 3 Drucker, 4 Dock, 5/6 Sonos, 7 macmini, 24 ap2) · sw-id RGZJ-UK0T, MAC 04:F4:1C:B4:15:58 |
|
||||
| **crs326-core** (CRS326, Technik UG) | **10.40.99.1** (VLAN99-SVI = L3-GW; same-subnet-Fallback `10.40.10.1`) · Identity `crs326-core` | RouterOS **7.24** · `admin`/`~/.secrets` (`CRS326_CORE_*`) · MikroMCP routerId `crs326-core` ✅ **live** (2026-08-16 verifiziert) · **TP15/TP21.1 ✅ 2026-08-08: PRODUKTIVER L3-Router** (ersetzt ap1) — Routing/DHCP (7 Server + 54 Leases)/DNS (**DoH zum CF-Gateway mit `verify-doh-cert=yes`**, TP23 Stufe 1 ✅ 2026-08-18; `servers=1.1.1.1` nur noch Bootstrap) · **NTP-Server für den Standort**/NAT/WG-Hub (fm+dw live); WAN `vlan100`=Liwest `90.146.33.177` · sw-id 4W04-URHT, MAC 04:F4:1C:B4:17:76 |
|
||||
| hAP ax² #1 (ap1) | **10.40.99.11** (VLAN99) · Identity `ap1` | RouterOS **7.24** · `admin`/`~/.secrets` (`ROUTER_AP1_*`) · REST `http://10.40.99.11/rest` · MikroMCP `ap1` ✅ live · **TP28 ✅ 2026-08-17: reiner CAP** (Manager = `crs326-core`, `cap enabled=yes`, `discovery-interfaces=vlan99`) — Uplink `ether1` (PoE-Port, `poe-out=off`) an crs326-core `ether15`; SSIDs/Kanäle kommen vom Manager, ch36/ch1 · MAC D0:EA:11:4D:40:E0 · Config-Referenz `routeros/.secrets/ap1-prov-base.rsc` |
|
||||
| hAP ax² #2 (ap2) | **10.40.99.12** (VLAN99) · Identity `ap2` | RouterOS **7.24** · `admin`/`~/.secrets` (`ROUTER_AP2_*`) · REST `http://10.40.99.12/rest` · MikroMCP `ap2` · **TP28 ✅ 2026-08-17: reiner CAP** — Uplink `ether1` (PoE) an crs326-branch `ether24`; ch44/ch11 (TP25: ch149 war unter ETSI leistungsbegrenzt) · MAC D0:EA:11:4D:40:3A · Config `routeros/.secrets/ap2-prov-base.rsc` |
|
||||
| **crs326-branch** (CRS326, Technik OG) | **10.40.99.2** (VLAN99) · Bootstrap Rev4 2026-08-08 | RouterOS **7.24.1** · `admin`/`~/.secrets` (`CRS326_BRANCH_*`) · REST `http://10.40.99.2/rest` · MikroMCP `crs326-branch` ✅ **live** (2026-08-16 verifiziert) · **TP15 ✅: ersetzt sw2** (L2-Switch), volle Portbelegung (ether1 Uplink-Trunk, 2/8 NAS, 3 Drucker, 4 Dock, 5/6 Sonos, 7 macmini, 24 ap2) · sw-id RGZJ-UK0T, MAC 04:F4:1C:B4:15:58 |
|
||||
| **crs326-core** (CRS326, Technik UG) | **10.40.99.1** (VLAN99-SVI = L3-GW; same-subnet-Fallback `10.40.10.1`) · Identity `crs326-core` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`CRS326_CORE_*`) · MikroMCP routerId `crs326-core` ✅ **live** (2026-08-16 verifiziert) · **TP15/TP21.1 ✅ 2026-08-08: PRODUKTIVER L3-Router** (ersetzt ap1) — Routing/DHCP (7 Server + 54 Leases)/DNS (**DoH zum CF-Gateway mit `verify-doh-cert=yes`**, TP23 Stufe 1 ✅ 2026-08-18; `servers=1.1.1.1` nur noch Bootstrap) · **NTP-Server für den Standort**/NAT/WG-Hub (fm+dw live); WAN `vlan100`=Liwest `90.146.33.177` · sw-id 4W04-URHT, MAC 04:F4:1C:B4:17:76 |
|
||||
| hAP ax² #1 (ap1) | **10.40.99.11** (VLAN99) · Identity `ap1` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`ROUTER_AP1_*`) · REST `http://10.40.99.11/rest` · MikroMCP `ap1` ✅ live · **TP28 ✅ 2026-08-17: reiner CAP** (Manager = `crs326-core`) · 🔴 **FUNKSTILL seit 2026-08-30**: keine Provisioning-Regel am Manager, weil ap3 daneben steht und denselben Kanal 5180 fährt. Gerät bleibt erreichbar. Beim Umzug ans Sideboard → `5260/Ce` (Band B, DFS) und Uplink auf `core ether3` — Uplink `ether1` (PoE-Port, `poe-out=off`) an crs326-core `ether15`; SSIDs/Kanäle kommen vom Manager, ch36/ch1 · MAC D0:EA:11:4D:40:E0 · Config-Referenz `routeros/.secrets/ap1-prov-base.rsc` |
|
||||
| hAP ax² #2 (ap2) | **10.40.99.12** (VLAN99) · Identity `ap2` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`ROUTER_AP2_*`) · REST `http://10.40.99.12/rest` · MikroMCP `ap2` · **TP28 ✅ 2026-08-17: reiner CAP** — Uplink `ether1` (PoE) an crs326-branch `ether24`; ch44/ch11 (TP25: ch149 war unter ETSI leistungsbegrenzt) · MAC D0:EA:11:4D:40:3A · Config `routeros/.secrets/ap2-prov-base.rsc` |
|
||||
| **cAP ax (ap3)** | **10.40.99.13** (VLAN99) · Identity `ap3` | ✅ **LIVE seit 2026-08-30** (TP28-Nachtrag) · `cAPGi-5HaxD2HaxD`, RouterOS **7.24.1** + RouterBOOT 7.24.1 (**seit 2026-08-31 ist die ganze Flotte auf 7.24.1**, TP27-Angleichung erledigt) · reiner CAP, Manager `crs326-core` · Uplink `ether1` → **core `ether21`** (Trunk) · Kanäle **`5180/ax/Ce/I`** (5 GHz) + **`2437/ax`** (ch6) nach TP25-Plan · 🔴 **nur 2 Ethernet-Ports** (`ether1` PoE-in, `ether2` PoE-out, **kein** Bridge-Port) → `ap.extra_ports=[]` · `device-mode=basic` (scheduler/fetch/romon **erlaubt**, anders als ap1/ap2) · Dateien `routeros/tp28-ap3-phase{1,2}-*.rsc` + `-service-accounts.rsc` + `-werksreste.rsc` |
|
||||
| **🔑 Einheitliches Admin-PW (2026-08-08)** | alle 4 MikroTik (core/branch/ap1/ap2) | user `admin`, gleiches PW (`~/.secrets/credentials.env` → `ROUTER_*_PASS`/`CRS326_*_PASS`; „Überlebensversicherung", User-Vorgabe). Werks-Defaults ap1/ap2 damit obsolet. |
|
||||
| NAS (nas-bf, DS923) | 10.40.20.10 | SSH `adm.christoph@10.40.20.10` (kein PW nötig) · Docker (Portainer endpointId=14) |
|
||||
| platform-pg (LXC 105, pve) | 10.40.20.20 | SSH via pve (`pct exec 105 --`) · **TP20 ✅ 2026-07-16: PG16, DB `nautobot`, Creds `postgres/.secrets`** |
|
||||
@@ -80,7 +122,12 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
|
||||
Reads immer safe; Writes mit `dryRun:true` previewen, dann `apply_plan`. **Passwort setzen via `manage_user set-password`** (`/user set*` ist per Deny-Policy blockiert). ⚠️ **Reboot geht auf ROS 7.24 gar nicht ueber MikroMCP:** das `reboot`-Tool sendet `delay`, die REST-API kennt den Parameter nicht (`unknown parameter delay`), und `run_command` ist fuer `/system reboot*` gesperrt — Weg ist `SSHPASS="$PW" sshpass -e ssh admin@<ip> "/system reboot"` (PW aus `~/.secrets`, im Output
|
||||
maskieren). 🔴 **Niemals `sshpass -p`** — das schreibt das Passwort in die Kommandozeile, wo es in
|
||||
`ps` und jedem argv-Trace steht; **genau so ist am 2026-08-22 das Core-Passwort in ein
|
||||
Sitzungstranskript geraten** und musste rotiert werden. `-e` hält es in der Umgebung des Kindprozesses. `bridge/vlan/set` nur auf `[find … and !dynamic]`.
|
||||
Sitzungstranskript geraten** und musste rotiert werden. `-e` hält es in der Umgebung des Kindprozesses.
|
||||
✅ **Alle sechs Skripte im Repo sind am 2026-08-31 umgestellt** (`nautobot/gc-transaktion.py`,
|
||||
`routeros/import-core-rsc.py` und die vier inzwischen nach
|
||||
`routeros/archiv-tp15-cutover/` archivierten Cutover-Skripte) — gemessen
|
||||
mit `ps`-Stichproben plus Negativkontrolle, nicht nur gelesen. **Neue Skripte erben die Regel nicht
|
||||
von selbst**: wer einen sshpass-Aufruf schreibt, baut `env=dict(os.environ, SSHPASS=pw)` mit ein. `bridge/vlan/set` nur auf `[find … and !dynamic]`.
|
||||
🔴 **Zweiter Leak-Weg, gleiche Klasse: `list_wifi_interfaces` gibt `security.passphrase` ALLER
|
||||
Profile im Klartext zurück** — am 2026-08-24 hat ein Read, der nur die `cap-wifiN`-Zuordnung finden
|
||||
sollte, damit **fünf WLAN-PSKs** (`main`/`iot`/`media`/`untrusted`/`guest`) in ein Transkript
|
||||
@@ -103,6 +150,81 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
|
||||
|
||||
## Kritische Gotchas
|
||||
- 📜 **~~ALLNET-Gotchas (1 Telnet-VTY, `save` nicht vergessen)~~ — gegenstandslos seit 2026-08-08** (Gerät ausgebaut). Nur noch historisch relevant, s. `switch/README.md`.
|
||||
- 📝 **WLAN-Logs sind seit 2026-08-30 persistent — und der Topic heißt `wireless`, nicht `wifi`.**
|
||||
Auch auf dem neuen `wifi-qcom`-Stack tragen Roaming-/Connect-Events `wireless;info` bzw.
|
||||
`wireless,debug`. Ein geratenes `topics=wifi` wäre wirkungslos geblieben. Zwei Regeln auf dem
|
||||
**Core** (nicht auf den CAPs — unter CAPsMAN führt der Manager die Events) schicken `wireless`
|
||||
und `caps` in denselben Kollektor wie TP5 (`10.40.20.18:514`, Tagesdateien unter
|
||||
`/opt/tp5-syslog/log/10.40.20.1/`). ⚠️ **RouterOS UND-verknüpft Topics innerhalb EINER Regel**
|
||||
(`topics=info,!firewall` = info UND NICHT firewall) — `topics=wireless,caps` hätte **nichts**
|
||||
gematcht, es braucht zwei Regeln. Vorher lief alles nur in einen ~75-Zeilen-Ringpuffer, der von
|
||||
einer Stunde Arbeit überschrieben war; ein seit Wochen gemeldetes Client-Problem war deshalb
|
||||
**rückwirkend nicht diagnostizierbar**. `/system logging` steht jetzt unter der 27. ComplianceRule
|
||||
`system-logging` — vorher unter keiner. **Merkregel: bevor man ein sporadisches Problem sucht,
|
||||
erst prüfen, ob es überhaupt irgendwo mitgeschrieben wird.**
|
||||
- 🧮 **Ein Log-Burst über VIELE MACs ist Infrastruktur, über EINE MAC ein Client** (Fund 2026-08-31).
|
||||
Am 31.08. sahen 13 × `caps,info … joined`, 4 × `activity timeout` und zwei Massenbursts
|
||||
`association rejected, no cached PMK` (74 Zeilen, **38 verschiedene MACs**) wie eine CAPWAP-
|
||||
Instabilität aus, die das ganze Netz trifft. Es waren die **Reboots des TP27-Upgrades**. Jedes
|
||||
Ereignis fiel auf einen Neustart. 🔴 **Vor jeder Client-Diagnose erst `grep " caps,"` und
|
||||
`/system resource get uptime` lesen** — sonst sucht man einen Gerätefehler, der ein geplanter
|
||||
Reboot war. Der Umkehrschluss gilt auch: 93 von 93 `reauthenticating` von **einer** MAC auf
|
||||
**einer** SSID sind ein echter Client-/SSID-Befund.
|
||||
- 🗺️ **Die `cap-wifiN`-Karte verschiebt sich bei JEDEM CAP-Rejoin, nicht nur beim Provisionieren.**
|
||||
Am 2026-08-31 wanderte sie zweimal an einem Tag (08:09 Re-Provisionierung, 14:36 Core-Reboot);
|
||||
eine im Handoff festgehaltene Tabelle war nach sechs Stunden falsch. ⇒ **Interface-Namen in
|
||||
Logzeilen sind ohne einen zeitnahen Karten-Snapshot NICHT zuschreibbar.** Vor jeder Auswertung
|
||||
`/interface wifi radio print terse proplist=cap,radio-mac,interface` am Manager lesen — und wenn
|
||||
zwischen Ereignis und Auswertung ein Rejoin liegt, die Zuordnung als **unbekannt** behandeln
|
||||
statt zu raten.
|
||||
- 🔑 **CAPsMAN verteilt KEINE Login-Passwörter — nur WLAN-PSKs.** Zwei verschiedene Dinge heißen
|
||||
„Passwort": die **WPA-Passphrase** (`/interface wifi security`) liegt am Manager und wird an die
|
||||
CAPs verteilt ✅; der **Geräte-Login** (`/user`) ist eine **lokale Benutzer-DB auf jedem Gerät** ❌.
|
||||
Beleg: ap1 trägt `admin`, `ha`, `nautobot` lokal, mit gerätelokalen `last-logged-in`-Zeitstempeln.
|
||||
Das einheitliche Admin-PW ist eine **von Hand angewendete Konvention**, keine Automatik — und
|
||||
logisch kann es nicht anders sein: ein Gerät *wird* erst zum CAP, nachdem sich jemand eingeloggt hat.
|
||||
- 🔴 **Ein neuer CAP braucht `configuration.manager=capsman` auf JEDEM Master-Radio.**
|
||||
`/interface wifi cap set enabled=yes` allein reicht nicht — ohne das Feld bietet der CAP seine
|
||||
Radios dem Manager gar nicht erst an. **Symptom (2026-08-30, ap3):** `remote-cap print` zeigt
|
||||
`state=Ok`, aber `/interface wifi radio print` am Manager listet für dieses Gerät **nichts**, und
|
||||
weil die Provisioning-Regel dann nicht matcht, sucht man den Fehler in der `radio-mac`. Im
|
||||
Werkszustand ist das Feld leer (= `local`).
|
||||
- 🔌 **Werks-MikroTik am Trunk: `ether1` ist WAN, und das sieht aus wie ein Netzproblem.** Beim
|
||||
cAP ax (und den hAPs) steht `ether1` per defconf in der Interface-Liste `WAN`. Folge: Discovery
|
||||
aus (**kein MNDP → in `/ip neighbor` unsichtbar**), Input-TCP verworfen (22/80/8291/8728 **zu**),
|
||||
**ICMP aber erlaubt** — es *pingt*, was sich wie „erreichbar" liest. Kein Registry-Eintrag und
|
||||
kein MikroMCP hilft, denn Port 80 ist zu. **Der Weg rein ist die LAN-Seite** (`ether2` oder das
|
||||
Werks-WLAN); dort `/interface list member remove [find where interface=ether1]` — das ist der Fix.
|
||||
- 🔀 **`pvid` ist INGRESS, `tagged`/`untagged` ist EGRESS.** Ein Port mit `pvid=99`, der in der
|
||||
*tagged*-Liste von VLAN99 steht, nimmt untagged an und antwortet **getaggt**. Symptom
|
||||
(2026-08-30): ein DHCP-Lease hing ewig auf `offered` und ARP auf `failed` — der DISCOVER kam an,
|
||||
der ACK nie. Für ein Werksgerät gehört der Port **untagged** in die VLAN-Zeile.
|
||||
- 🕳️ **Ein neues Gerät ohne `secrets_group` erzeugt eine LÜCKE, keine Fehlermeldung.** Ohne
|
||||
Secrets Group scheitert der Golden-Config-**Backup**-Job still; die *intended* config wird
|
||||
trotzdem sauber gerendert, aber ohne Backup entstehen **keine Compliance-Einträge** — und die
|
||||
Gesamtzahl bleibt unauffällig (bei uns 104/104), weil ein Gerät ohne Ergebnisse auch keine Drift
|
||||
meldet. 🔴 **Merkregel: eine gleichbleibende Compliance-Zahl nach dem Hinzufügen eines Geräts ist
|
||||
ein BEFUND, kein Erfolg.** Erst `130/130` bewies, dass ap3 wirklich geprüft wird. Zweite
|
||||
Voraussetzung: die dedizierten Service-Accounts `nautobot`/`ha` (TP-PWD) existieren auf einem
|
||||
Werksgerät nicht.
|
||||
- 🔢 **Firewall-Regelnummern aus `print where` sind Handles, keine Positionen.** Nach einem
|
||||
`place-before` zeigte `/ip firewall filter print terse where comment~"..."` die Nummer **60**,
|
||||
während `drop` auf **59** stand — die Regel lag trotzdem davor. Beweis ist der **Zähler**: eine
|
||||
Regel hinter dem `drop` kann nicht zählen. Wer nach der Zahl geht statt nach `print stats`,
|
||||
„repariert" eine funktionierende Regel kaputt.
|
||||
- 🔌 **`crs326-core` hat KEIN PoE-out** (`/interface ethernet poe` existiert dort gar nicht,
|
||||
CRS326-24G-2S+). Ein AP an einem Core-Port braucht eigene Stromversorgung. Der **cAP ax** bringt
|
||||
dafür **Netzteil UND Gigabit-PoE-Injector im Karton** mit (Produktseite, 2026-08-30) — die
|
||||
TP25-Notiz „kein Netzteil im Lieferumfang üblich" gilt für dieses Modell **nicht**. Symptom, wenn
|
||||
man das übersieht: der Core-Port steht auf `no-link` und man sucht den Fehler im VLAN-Tagging.
|
||||
- 🧩 **Die AP-Flotte ist seit ap3 heterogen — Literal-Listen im GC-Template sind dadurch gefährlich
|
||||
geworden.** Der AP-Zweig hatte `ether3/ether4/ether5` als Bridge-Ports **hartkodiert**; das war die
|
||||
stille Annahme *„AP == hAP ax² mit 5 Ports"*. Der **cAP ax hat zwei**. Seit 2026-08-30 kommt die
|
||||
Liste aus **`ap.extra_ports`** (ConfigContext `ap-common`, Default = hAP-ax²-Bestand; ap3
|
||||
überschreibt sie per `local_config_context_data` mit `[]`). ⚠️ **Nautobot merged Dicts tief, Listen
|
||||
ERSETZEND** — für diesen Fall genau richtig, bei `zones`/`radios` wäre es eine Falle.
|
||||
Merkregel: **bevor ein zweites Modell derselben Rolle dazukommt, die Literal-Blöcke im Template
|
||||
daraufhin lesen, welche Zeile eigentlich „Gerätetyp" meint und nicht „Rolle".**
|
||||
- 🔵 **Container auf MikroTik — korrigiert 2026-08-25, die alte Pauschalregel war nie nachgemessen.**
|
||||
Es hiess hier „hAP ax² hat 128 MB Flash, kein USB → Container NICHT auf dem Router". Live gelesen:
|
||||
**ap1/ap2 sind `arm64` mit 95 MB FREIEM Flash und 690 MB freiem RAM** — das reicht für **einen**
|
||||
@@ -117,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).
|
||||
@@ -193,6 +350,39 @@ Verhaltensregeln für nachfolgende AI-Sessions — kleiner, klarer, weniger Drif
|
||||
- **MCPs brauchen Host-Verifikation** vor Edit. Wenn der MCP verändert/editiert wird: vorher per Live-Read (nc/ps/curl) prüfen, ob der Host noch antwortet. Beispiel: 2026-08-27 — `shelly-mcp` zeigte auf `10.40.20.30:3030`, aber kein Host antwortet. Konfig auf `enabled=false`, dokumentieren statt hart fehlschlagen zu lassen. **(Stand 2026-08-28: shelly-mcp wird auf DS923 `10.40.20.180` deployt — `BUILD.md` liegt bereit.)**
|
||||
- **Mac mini ist n8n-Host, nicht zentraler MCP-Host** (User-Direktive 2026-08-28): MCP-Dienste gehören auf die **DS923** (`nas-bf`, Portainer Endpoint 14) — nicht auf die User-Workstation. Aktuell laufen gitea-mcp + n8n-mcp **noch** auf dem macmini (historisch), gehören **bei Gelegenheit** auf die DS923 umgezogen.
|
||||
- **Tote MCP-Skripte → ins Projekt-Repo, nicht global.** Wenn ein MCP nur für ein Projekt relevant ist (`cannaleo` für terpene, `terpene-pg` für terpene): gehört in `~/dev/<projekt>/mcp.json` + Skript im Projekt-Repo. Globale `~/.claude.json`/`~/.config/opencode/opencode.jsonc` = nur projekt-übergreifende Tools.
|
||||
- **opencode-Skills: Default-Pfad kopieren, NICHT symlinken** (TP35 Schicht 6, 2026-08-28). Claude-Skill in `~/.claude/skills/<name>/SKILL.md` ist die Quelle; für opencode gehört er nach `~/.config/opencode/skills/<name>/SKILL.md` (`cp`, nicht `ln -s`). Begründung: opencode scannt diesen Pfad als Default — **kein** `skills.paths`-Eintrag in `~/.config/opencode/opencode.jsonc` nötig, das wäre redundant. Symlink wurde in der Inventur-Session testweise angelegt, hat Christophs "opencode = eigene Pfade"-Direktive verletzt und wurde wieder entfernt. Schema-Referenz: <https://opencode.ai/config.json> → `Config.skills.paths`. **Lehre aus dem Fall:** opencode-CLI-Verhalten nicht raten, Doku lesen — und ein "load-bearing"-Detail (Default-Scan-Pfad) zuerst verifizieren, bevor man ihn umgeht.
|
||||
- **Skills sind IMMER global, niemals pro Projekt** (Christoph-Direktive 2026-08-28). `projektstatus` und alle übrigen Skills liegen **ausschließlich** unter `~/.claude/skills/` und `~/.config/opencode/skills/`. **Kein** Repo-lokaler Skill unter `.opencode/skill/` oder `.claude/skill/`. Begründung: keine Redundanz, keine Drift zwischen Skill-Versionen, eine Quelle pro Skill. **Merkregel:** wer einen Skill „überschreiben" will, editiert **die globale Datei** oder schreibt einen zweiten Skill mit anderem Namen — niemals ein Repo-Override.
|
||||
- **Kommentar in Code ≠ Verhalten.** `mcp/shelly/.env` trug den Kommentar "gitignored, NICHT committen" — es gab aber **kein** `mcp/shelly/.gitignore`. Der Kommentar war Wunsch, nicht Wirklichkeit. `routeros/cloudflared/credentials.json` (Cloudflare-Tunnel-PrivateKey base64) lag ungegittoret im Working Tree. **Merkregel:** Behauptungen in Kommentaren/Konfig-Kommentaren durch `git check-ignore -v <datei>` (oder `git status`) verifizieren, bevor man darauf vertraut. **Lessons-Block erweitert 2026-08-28 nach `commit`-Session.**
|
||||
- **opencode-TUI: führendes Leerzeichen vor `/command` manchmal nötig** (Beobachtung 2026-08-28, Skill „projektstatus" getestet; **identifiziert als bekannter Bug**). Symptom: Tippen von `/projektstatus` führt nicht zum Skill, ` /projektstatus` (führendes Leerzeichen) schon. Doku <https://opencode.ai/docs/commands> zeigt den Aufruf ohne Space. **Verifiziert:** Issue **anomalyco/opencode#27528** „ACP: prompt starting with '/' is silently dropped if command name is not recognized" — Status **Not planned (skipped)**, closed 2026-07-14. Maintainer haben es also gesehen und nicht gefixt. **Konsequenz:** Workaround (führendes Leerzeichen) ist der offizielle Pfad; Skill selbst ist nicht kaputt. Vor jedem neuen opencode-Build prüfen, ob das Verhalten weg ist.
|
||||
- **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:**
|
||||
|
||||
@@ -201,3 +391,4 @@ Verhaltensregeln für nachfolgende AI-Sessions — kleiner, klarer, weniger Drif
|
||||
3. Habe ich **eine** Fragenrunde mit allen offenen Annahmen gestellt?
|
||||
4. Habe ich für jeden Edit **deine** Bestätigung eingeholt (nicht nur für den Plan-Output)?
|
||||
5. **MCP-Änderung?** Vorher Live-Check (Port/Prozess), aktiv melden, Garbage-Collector-Pflicht.
|
||||
6. **Output-Länge.** Christoph hat sich heute (2026-08-28) wiederholt in langen Outputs verirrt. **Merkregel:** eine Antwort pro Edit-Vorschlag, eine Zeile pro Bestätigung, keine Wiederholung dessen, was im Diff steht. Keine Frage-Runden, wenn keine echte Annahme kollidiert. Erklärungstexte unter 6 Zeilen, sofern nicht ausdrücklich verlangt.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -52,14 +52,16 @@ def caddy_sites():
|
||||
sites, site = {}, None
|
||||
with open(os.path.join(HERE, "Caddyfile"), encoding="utf-8") as fh:
|
||||
for line in fh:
|
||||
m = re.match(r"^([a-z0-9.-]+\.%s)\s*\{" % re.escape(ZONE), line)
|
||||
# Block-Header: ein oder mehrere Hostnamen (kommagetrennt) vor "{"
|
||||
m = re.match(r"^([a-z0-9.-]+(?:\s*,\s*[a-z0-9.-]+)*\.%s)\s*\{" % re.escape(ZONE), line)
|
||||
if m:
|
||||
site = m.group(1)
|
||||
continue
|
||||
if site:
|
||||
m2 = re.search(r"reverse_proxy\s+(\S+)", line)
|
||||
if m2:
|
||||
sites[site] = m2.group(1)
|
||||
for host in site.split(","):
|
||||
sites[host.strip()] = m2.group(1)
|
||||
site = None
|
||||
return sites
|
||||
|
||||
@@ -94,16 +96,20 @@ def main():
|
||||
|
||||
drift = []
|
||||
|
||||
# 1) Ingress gegen Caddyfile
|
||||
# 1) Ingress gegen Caddyfile.
|
||||
# Zielbild (TP31): CF-Ingress zeigt auf Caddy (10.40.20.40), Caddy aufs Origin.
|
||||
# Zeigt CF direkt auf ein Origin (nicht Caddy), ist das die alte Architektur = Drift.
|
||||
for host, (tun, svc) in sorted(ingress.items()):
|
||||
if svc.startswith("ssh://"):
|
||||
continue
|
||||
if host not in caddy:
|
||||
drift.append(f"NUR-CF {host:<32} {tun}: {svc} (in Caddy nicht vorhanden)")
|
||||
elif caddy[host] != svc:
|
||||
drift.append(f"ABWEICHEND {host:<32} CF={svc} Caddy={caddy[host]}")
|
||||
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.
|
||||
for host, svc in sorted(caddy.items()):
|
||||
if host not in ingress:
|
||||
if host not in ingress and not host.endswith(".bf." + ZONE):
|
||||
drift.append(f"NUR-CADDY {host:<32} {svc} (kein CF-Ingress — intern oder bewusst)")
|
||||
|
||||
# 2) CNAMEs, die auf einen Tunnel zeigen, aber keine Ingress-Regel mehr haben
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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,23 @@
|
||||
{
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result": {
|
||||
"tunnel_id": "220c9958-401b-4111-9451-f3db09bba2d5",
|
||||
"version": 4,
|
||||
"config": {
|
||||
"ingress": [
|
||||
{"service": "http://10.40.20.157:3000", "hostname": "gitea.emsenhuber.net"},
|
||||
{"service": "http://10.40.20.109:3000", "hostname": "grafana.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-24T08:28:18.806844Z"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
File diff suppressed because one or more lines are too long
@@ -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.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
## TL;DR
|
||||
|
||||
- `bf-infra` ist **aktiver Fork** von `bf-network-r6`; aktiv gepflegt, **kein Gitea-Remote** → Backup-Lücke.
|
||||
- 🔴 **Korrektur 2026-08-30 (Befund steht, Schlussfolgerung überholt):** das Remote existiert inzwischen — `origin` = `https://gitea.emsenhuber.net/admin/bf-infra.git`, `origin/main` = `b917691` (2026-08-28). Der Satz oben war am 08-27 zutreffend und ist **bewusst erhalten**; er darf aber nicht mehr als Ist gelesen werden. Die Backup-Lücke schließt ein `git push`, kein neues Repo.
|
||||
- `admin/bf-network-r6` (Gitea) = historischer Master, letzte aktive Commits 2026-08-25 → auf read-only stellen (deine Aktion).
|
||||
- `admin/bf-golden-config` (Gitea) = Bot-Master (Nautobot BACKUP/GENERATE 2×/Tag) → kein lokaler Mirror.
|
||||
- `admin/blaueblueten-n8n` (Gitea) = Master für terpene-Repo, aktiv.
|
||||
|
||||
146
docs/handoff-20260828-portainer-bump-und-mcp.md
Normal file
146
docs/handoff-20260828-portainer-bump-und-mcp.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Handoff 2026-08-28 — Portainer 2.40 → 2.42.0 Bump + portainer-mcp (uvx, projektebene)
|
||||
|
||||
> **Vorgeschichte:** Direktive vom 2026-08-28 (User): "wenn du künftig das ganze containermanagement machst,
|
||||
> brauchst du einen MCP für Portainer". Vorgänger-Direktive vom 2026-08-28 selbst (gestern Session):
|
||||
> ⛔ NICHT installieren. → **revidiert** in derselben Diskussion, weil die wiederholten curl-Aufrufe
|
||||
> in der Inventur-Session gezeigt haben, dass ein MCP-Layer hier operativ hilft.
|
||||
|
||||
## Was diese Session geliefert hat
|
||||
|
||||
### 1. Portainer-Server 2.40.0 → 2.42.0 (auf pve LXC 400, Container `portainer`)
|
||||
|
||||
**Vorab-Korrektur (war falsch im Handoff 2026-08-28):** README schrieb 2.42.6 als Ziel,
|
||||
PyPI hat ein 2.42.6-Wheel, aber Docker-Hub hat **nur 2.42.0** als letzten 2.42.x-Tag
|
||||
für `portainer/portainer-ce`. Bump-Ziel deshalb **2.42.0** statt 2.42.6.
|
||||
|
||||
**Ablauf:**
|
||||
1. Pre-Upgrade-Snapshot:
|
||||
- `docker commit portainer portainer/portainer-ce:2.40.0-preupgrade-20260828` (186 MB)
|
||||
- Settings+Endpoints+Stacks-JSON-Dump (40 KB, 31 Stacks, 4 Endpoints)
|
||||
- Volume `/var/lib/docker/volumes/portainer_data/_data` ist **persistent**, bleibt
|
||||
beim Image-Swap unangetastet.
|
||||
- Runflags aus `docker inspect` ins Runbook übernommen.
|
||||
2. `docker pull portainer/portainer-ce:2.42.0`
|
||||
3. `docker stop portainer && docker rm portainer && docker run -d` mit identischen Flags.
|
||||
4. Post-Upgrade-Verifikation:
|
||||
- HTTP 200 auf `/`, TLS self-signed OK
|
||||
- `api/status` → `Version: 2.42.0`, **gleiche InstanceID** wie vorher
|
||||
- **API-Token weiter gültig** (`api/settings` → 200), kein Re-Auth
|
||||
- Alle 4 Endpoints + 31 Stacks abrufbar
|
||||
|
||||
**Sicherheitsabstände für den Bump:**
|
||||
- Container läuft, alle Endpoints erreichbar (status=1)
|
||||
- Edge-Agents auf den 4 Hosts (DS923, macmini, nas-fm, pve) sind **eigene Container**,
|
||||
Portainer-Container-Restart berührt sie nicht.
|
||||
|
||||
### 2. portainer-mcp — installiert als projektspezifischer uvx-stdio
|
||||
|
||||
**Quelle:** `mcp-portainer` von PyPI (offiziell, von Portainer, generiert aus OpenAPI-Spec).
|
||||
Wegen "Match minor to minor"-Policy (PyPI/README) war der Bump **Pflicht**, sonst kein offizieller MCP.
|
||||
|
||||
**Installation:**
|
||||
- `uvx --from "mcp-portainer~=2.42.0" mcp-portainer` — Wheel lokal aufgelöst, 193 Tools
|
||||
- `bf-infra/.mcp.json` (gitignored):
|
||||
```jsonc
|
||||
{
|
||||
"mcpServers": {
|
||||
"portainer": {
|
||||
"command": "uvx",
|
||||
"args": ["--from", "mcp-portainer~=2.42.0", "mcp-portainer"],
|
||||
"env": {
|
||||
"PORTAINER_URL": "https://10.40.20.126:9443",
|
||||
"PORTAINER_API_KEY": "${env:PORTAINER_API_KEY}",
|
||||
"PORTAINER_TLS_VERIFY": "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- Token via `~/.secrets/exports.zsh` (`PORTAINER_API_KEY`) — kein Klartext im Repo
|
||||
- **`PORTAINER_TLS_VERIFY=0`** weil self-signed Cert auf pve-LXC
|
||||
- **Nur projektebene**, **kein** Eintrag in `~/.claude.json` oder `~/.config/opencode/opencode.jsonc`
|
||||
- **`.mcp.json` aus Repo entfernt** (`git rm --cached`) — `mcp/INVENTORY.md` zeigt das
|
||||
|
||||
**Tool-Gate:** jeder erste Read in einer Session erfordert `get_guidance()` (vom Server
|
||||
erzwungen). Erst danach funktionieren `EndpointList`, `StackList`, `StackInspect` etc.
|
||||
|
||||
### 3. Abnahme (drei Calls gegen die echte API)
|
||||
|
||||
```
|
||||
EndpointList mit select-Projektion:
|
||||
[ { "Id":2, "Name":"pve", "Type":1, "Status":1 },
|
||||
{ "Id":14, "Name":"nas-bf (ds923+)", "Type":2, "Status":1 },
|
||||
{ "Id":20, "Name":"macmini", "Type":2, "Status":1 },
|
||||
{ "Id":21, "Name":"nas-fm (ds415+)", "Type":2, "Status":1 } ]
|
||||
|
||||
StackList (plattformweit, mit select):
|
||||
31 Stacks (pve=4, DS923=20, macmini=4, nas-fm=3)
|
||||
|
||||
StackInspect(202) mit select:
|
||||
{ "id":202, "name":"pve-mcp", "endpointId":14, "status":1,
|
||||
"entryPoint":"docker-compose.yml", "projectPath":"/data/compose/202" }
|
||||
```
|
||||
|
||||
**MCP ersetzt jetzt:** `curl "$PORTAINER_URL/api/..."` aus Bash. Vorher 4-5 Aufrufe pro
|
||||
Inventur-/Deploy-Schritt; jetzt ein Tool-Call mit `select`-JMESPath-Projektion.
|
||||
|
||||
### 4. Bestands-Update (`mcp/INVENTORY.md`)
|
||||
|
||||
- Zeile `portainer-mcp`: ⛔ → 🟢, mit Stand 2026-08-28, 193 Tools, Tool-Gate vermerkt
|
||||
- Header ergänzt: "MCP-Hosts künftig nur WARP/lokal" (User-Direktive)
|
||||
- `mcp/portainer/README.md`: **überholt** (steht noch auf "Portainer-Bump zuerst" — jetzt erledigt)
|
||||
→ TODO für eigene Session: README auf neuen Stand bringen.
|
||||
|
||||
## Lehren aus dieser Session
|
||||
|
||||
### Versions-Korrektur
|
||||
**PyPI ≠ Docker-Hub für dieselbe Software.** PyPI `mcp-portainer` hatte 2.42.0-2.42.6 als Wheels
|
||||
(alle 6 Patch-Versionen), aber das Docker-Image `portainer/portainer-ce:2.42.x` stoppte
|
||||
bei 2.42.0 — vermutlich weil Portainer die Docker-Patch-Serie anders versioniert. **Vor jedem
|
||||
Versions-Claim den jeweils anderen Pfad gegenprüfen.**
|
||||
|
||||
### Werkzeug-Namen lernen
|
||||
`list_endpoints` war geraten. Tatsächlich heißt das Tool `EndpointList` (PascalCase),
|
||||
und es braucht zwingend `get_guidance()` vor dem ersten Read. **Bei unbekanntem MCP zuerst
|
||||
`tools/list` und ein einzelner Probe-Call, dann den echten Read.** Sonst verschwendet man
|
||||
drei Tool-Calls an Authentifizierungsfehler wie ich es hier gemacht habe.
|
||||
|
||||
### uvx-stdio vs Container-MCP
|
||||
Für ein **einzelnes Projekt** mit Performance-Bedenken ist uvx-stdio klar besser als Container:
|
||||
- kein zusätzlicher Host (DS923-Belastung entfällt)
|
||||
- keine macvlan-IP nötig (kein neuer Port-Range-Konflikt)
|
||||
- Tool-Calls direkt aus dem Claude/opencode-Prozess, kein Round-Trip
|
||||
- **Nachteil:** Token im Memory des Claude-Prozesses lebt so lange wie die Session.
|
||||
Bei Container-Lösung wäre der Token nur im MCP-Container. → Sicherheitsbedenken
|
||||
gegen Performance — die Direktive des Users ist hier explizit "Performance > Security
|
||||
weil LAN-only".
|
||||
|
||||
### `git rm --cached` für gitignored-Configs
|
||||
Eine bereits getrackte Datei (hier `.mcp.json` aus Commit 3426366) wird durch
|
||||
nachträgliches `.gitignore`-Pattern **nicht** ausgegraut — `git rm --cached` ist nötig,
|
||||
sonst bleibt sie im Index. Beim nächsten Commit verschwindet sie sauber.
|
||||
|
||||
## Commit-Plan (für die nächste Session oder als Quick-Commit)
|
||||
|
||||
```
|
||||
git add .gitignore mcp/INVENTORY.md docs/portainer-upgrade-20260828/
|
||||
git commit -m "Portainer 2.40 → 2.42.0 Bump + portainer-mcp (uvx projektebene)
|
||||
|
||||
- Portainer-Server: 2.40.0 → 2.42.0 auf pve LXC 400, Pre-Upgrade-Snapshot
|
||||
(docker commit :2.40.0-preupgrade-20260828 + JSON-Dump 31 Stacks/4 Endpoints)
|
||||
- .mcp.json aus Repo (war aus Commit 3426366 getrackt, jetzt gitignored)
|
||||
- mcp/INVENTORY.md: portainer-mcp ⛔→🟢, Header um MCP-WARP-Direktive ergänzt
|
||||
- docs/portainer-upgrade-20260828/: Rollback-Runbook + Pre-Upgrade-State.json
|
||||
|
||||
Hinweis: PyPI hat mcp-portainer bis 2.42.6, Docker-Hub nur bis 2.42.0 —
|
||||
README im mcp/portainer/ ist auf 2.42.6 formuliert und sollte angepasst werden.
|
||||
```
|
||||
|
||||
## TODO (offene Punkte, NICHT Teil dieser Session)
|
||||
|
||||
1. **`mcp/portainer/README.md`** ist überholt (steht noch auf 2.42.6-Bump, jetzt erledigt).
|
||||
Eigene 5-Minuten-Session, README auf den neuen Stand bringen.
|
||||
2. **Cleanup nach 7 Tagen Bump-Stabilität:** `docker rmi portainer/portainer-ce:2.40.0-preupgrade-20260828`
|
||||
3. **Shelly-mcp-Deployment** (das war Session B vor dem Portainer-Thema): shelly-mcp-Image ist gebaut,
|
||||
Stack-YML liegt auf DS923, Stack-Deploy steht aus. **Sofort zurück zu Session B**, weil die
|
||||
`.mcp.json` jetzt **auch** das shelly-mcp-Deployment erleichtert (kein wiederholtes curl-Poren).
|
||||
82
docs/handoff-20260828-session-a-projektstatus.md
Normal file
82
docs/handoff-20260828-session-a-projektstatus.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Handoff 2026-08-28 — Session A (TP35 Schicht 6: /projektstatus-Skill für opencode)
|
||||
|
||||
> **Bezug:** Handoff 2026-08-28 Bestand + Performance (`handoff-20260828-mcp-bestand-und-performance.md`)
|
||||
> → diese Session A (eine von drei Folge-Sessions aus dem obigen Handoff).
|
||||
> Diese Datei: **was in Session A passiert ist**, **was bleibt**, **Einstieg für Session B (shelly-mcp-Deploy)**.
|
||||
|
||||
## TL;DR
|
||||
- **`/projektstatus`-Skill läuft jetzt in opencode.** Kopie (`cp`, kein `ln -s`) nach `~/.config/opencode/skills/projektstatus/SKILL.md`.
|
||||
- **Kein** `skills.paths`-Eintrag in `~/.config/opencode/opencode.jsonc` nötig — opencode scannt den Default-Pfad.
|
||||
- **Lehre** im CLAUDE.md-Lessons-Block: Default-Pfad kopieren, nicht symlinken, keine `skills.paths`-Konfiguration.
|
||||
- **Doku nachgezogen:** TP35 Schicht 6 als ✅, Quick-Index ⏳ (Rest offen), Ist-Stand-Block auf 2026-08-28 mit MCP-Bestand-Korrektur.
|
||||
|
||||
## Was war (Drift → Befund → Entscheid)
|
||||
|
||||
### Drift
|
||||
- Im gestrigen Handoff (`handoff-20260828-mcp-bestand-und-performance.md`) stand, der testweise angelegte Symlink `~/.config/opencode/skills/projektstatus → ~/.claude/skills/projektstatus/` sei wieder entfernt worden. Wahr: das Verzeichnis `~/.config/opencode/skills/` existierte danach **nicht** mehr, opencode fand den Skill nicht.
|
||||
- Christoph-Direktive (verbatim aus CLAUDE.md-Lessons): "opencode ist die neue Umgebung, soll eigene Skill-Pfade haben, keine Symlinks". Frage: **wohin genau?** war offen.
|
||||
|
||||
### Befund (verifiziert, nicht geraten)
|
||||
- opencode-Schema aus `https://opencode.ai/config.json` (gefetched und gelesen): `skills.paths: string[]` ist der dokumentierte Multi-Pfad-Loader.
|
||||
- **Globale Default-Pfade** lauten `~/.config/opencode/skill/<name>/SKILL.md` und `~/.config/opencode/skills/<name>/SKILL.md` (beide Singular/Plural) — und zusätzlich scannt opencode `~/.claude/skills/<name>/SKILL.md` und `~/.agents/skills/<name>/SKILL.md` als **externe** Skills (auto-loaded).
|
||||
- Die Lehrstelle gestern war ein Holzweg: Symlink-Workaround für etwas, wofür das Schema einen eingebauten Default-Pfad hat.
|
||||
|
||||
### Entscheid
|
||||
- **Kopie** der `SKILL.md` nach `~/.config/opencode/skills/projektstatus/` — keine Konfigurationsänderung an `opencode.jsonc`.
|
||||
- Begründung: hält die Welten sauber getrennt (zwei Pflegeorte für spätere Drift-Reparaturen), nutzt den opencode-Default-Pfad ohne Sonderlock, vermeidet die gestern explizit abgelehnte Symlink-Lösung.
|
||||
|
||||
### Verifikation
|
||||
- `cp` lief, `diff -q ~/.claude/skills/projektstatus/SKILL.md ~/.config/opencode/skills/projektstatus/SKILL.md` → **byte-identisch** (kein Output = identisch).
|
||||
- Berechtigungen symmetrisch zur Quelle (`-rw-r--r--`).
|
||||
- `opencode.jsonc` ist **unverändert** (kein Backup nötig, kein Diff).
|
||||
- **Was die nächste Sitzung bestätigen muss:** opencode neu starten, `/projektstatus` triggern, den Baum lesen — der eigentliche Funktionsbeweis steht noch aus.
|
||||
|
||||
## Was sich geändert hat (in dieser Session, im Repo)
|
||||
|
||||
| Datei | Änderung |
|
||||
|---|---|
|
||||
| `CLAUDE.md` (Lessons) | Zwei neue Einträge: (a) "opencode-Skills: Default-Pfad kopieren, NICHT symlinken" mit Schema-Referenz; (b) "Kommentar in Code ≠ Verhalten" als Generalisierung des credentials.json/.env-gitignore-Funds aus dem Commit-Schritt. |
|
||||
| `docs/teilprojekte.md` Quick-Index Z. 208 | TP35: `🔜 → ⏳` (Schicht 6 ✅, Rest offen). |
|
||||
| `docs/teilprojekte.md` TP35-Block Z. 1747 | Schicht 6 als ✅ markiert, Datum 2026-08-28, Befund-Block. |
|
||||
| `docs/teilprojekte.md` Ist-Stand Z. 28 | Datum auf 2026-08-28, neue Bullet-Zeile MCP-Bestand-Korrektur. |
|
||||
|
||||
**Was bewusst NICHT geändert wurde:**
|
||||
- `opencode.jsonc` — der Pfad ist Default-Scan, kein Eintrag nötig.
|
||||
- `~/.claude/skills/projektstatus/` — die Quelle, bleibt unverändert.
|
||||
- `docs/handoff-20260828-mcp-bestand-und-performance.md` — gestern abgeschlossen, nicht überschrieben.
|
||||
|
||||
## Sicherheitsfund (nicht-Session-A-Arbeit, aber heute aufgetaucht)
|
||||
|
||||
Beim `commit`/`push` der untracked Session-B-Vorbereitung:
|
||||
- `routeros/cloudflared/credentials.json` (Tunnel-PrivateKey base64) lag ungegittoret im Working Tree.
|
||||
- `mcp/shelly/.env` trug den Kommentar "gitignored, NICHT committen" — es gab aber **kein** `mcp/shelly/.gitignore`.
|
||||
- **Beide gefixt** in den Commits `27863c1` und `433e600` (siehe Lessons-Block).
|
||||
- Working Tree ist clean, kein Secret jemals in den Index geraten.
|
||||
|
||||
## Drei Folge-Sessions — was ist abgearbeitet, was steht
|
||||
|
||||
| Session | Status |
|
||||
|---|---|
|
||||
| **A** — `/projektstatus`-Skill global | ✅ erledigt (diese Datei) |
|
||||
| **B** — shelly-mcp-Container auf DS923 deployen (live, ssh) | 🔜 vorbereitet (Repo-Materialien committed `27863c1`, .env lokal) |
|
||||
| **C** — Caddyfile↔CF-Ingress-Drift-Probe + Backup-Guard | 🔜 unangetastet |
|
||||
|
||||
## Lehren für die nächste Session (B)
|
||||
|
||||
1. **Live-Sweep am 2026-08-28 hat 23 Shellys auf VLAN30 bestätigt** (`.30.202`–`.226` + `.233`). `SHELLY_SWEEP=10.40.30.180-250` in `~/.secrets/exports.zsh` ist die Range, in der die echten Geräte **alle** liegen — die zusätzlichen 50 IPs sind Reserve, kein toter Sweep-Bereich.
|
||||
2. **Container-Pfad** = DS923 (`10.40.20.10`), NICHT macmini. Macmini belasten wir nicht, das war Christoph-Direktive.
|
||||
3. **Container-Definition lebt NICHT in `docs/nas-vlan20/stacks/shelly-mcp.yml`** — der wurde gestern gelöscht (User-Direktive: kein MCP-Client für shelly-mcp). Deployment = direkt via Portainer-API, nicht als Stack.
|
||||
4. **DHCP-Reservierung** = `crs326-core` `dhcp-v20`, MAC nach erstem Boot per MikroMCP `manage_dhcp_lease make-static` festnageln.
|
||||
5. **WLAN-PSKs** in `SHELLY_IOT_PSK` / `SHELLY_DEVICE_PW` (aus `~/.secrets/credentials.env`) — **niemals** ins Repo oder in den Container-Image.
|
||||
|
||||
## Commit
|
||||
|
||||
- **Hash:** siehe `git log --oneline -1` nach diesem Handoff.
|
||||
- **Geänderte Dateien:** `CLAUDE.md`, `docs/teilprojekte.md`, neue Datei `docs/handoff-20260828-session-a-projektstatus.md`.
|
||||
- **Commit-Message (Vorschlag):** `TP35 Schicht 6: /projektstatus-Skill in opencode aktiviert + Doku nachgezogen`
|
||||
|
||||
## Stand
|
||||
- 2026-08-28, ~19:30
|
||||
- Diese Session = Skill-Pfad-Findung + Kopie + Lessons-Eintrag + TP35/Ist-Stand-Update + Handoff
|
||||
- Sessions B + C aus dem gestrigen Handoff unverändert
|
||||
- `~/.config/opencode/opencode.jsonc` ist unverändert (kein Backup)
|
||||
274
docs/handoff-20260828-terpene-mcp-migration-cf-tokens.md
Normal file
274
docs/handoff-20260828-terpene-mcp-migration-cf-tokens.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# Handoff 2026-08-28 (Abends) — terpene/blaueblueten-n8n-Schnittstelle + globale MCP-Migration
|
||||
|
||||
> **Zweck:** Christophs Kontext explodiert in der heutigen Session. Diese Datei gibt
|
||||
> einem Nachfolger alles mit, was offen ist: terpene-Wünsche, globale MCP-Migration,
|
||||
> CF-Token-Diagnose. **Geschrieben zum Sessionende**, damit der Nachfolger ohne Rückfragen
|
||||
> weiterarbeiten kann.
|
||||
>
|
||||
> **Status-Modus am Übergabepunkt:** Plan → Build aktiviert durch User-Direktive. **`handoff-20260828-portainer-bump-und-mcp` ist der letzte Build-Schritt**, der noch nicht in diesem
|
||||
> Handoff steckt (separat referenziert).
|
||||
>
|
||||
> **Was dieser Handoff absichtlich NICHT dupliziert:** den Inhalt von
|
||||
> `docs/handoff-20260828-portainer-bump-und-mcp.md` (Portainer-Bump + portainer-mcp).
|
||||
> Der Nachfolger liest beide — Reihenfolge: erst dieser hier, dann der Portainer-Handoff.
|
||||
|
||||
---
|
||||
|
||||
## 1. Sofort (nächste Session, kein Warten)
|
||||
|
||||
### 1.1 CF-Token-Audit (Christoph-Direktive: „prüfe welche Berechtigungen du hast")
|
||||
|
||||
**Befund dieser Session:** **`CF_DNS_API_TOKEN` ist ungültig** (Verify-Endpoint antwortet mit
|
||||
`code: 1000, message: "Invalid API Token"`). Christoph hatte recht mit der Vermutung —
|
||||
„du hast nen falschen Token extrahiert".
|
||||
|
||||
**Was der Nachfolger macht:**
|
||||
1. Im CF-Dashboard (<https://dash.cloudflare.com/profile/api-tokens>) prüfen,
|
||||
ob beide Tokens (`CF_API_TOKEN`, `CF_DNS_API_TOKEN`) noch **existieren**
|
||||
(Dash akzeptiert gelöschte Tokens stillschweigend, dann wirkt `verify` identisch
|
||||
zu nie-angelegt-gewesen).
|
||||
2. Falls beide weg: **neue Tokens anlegen** mit Scopes
|
||||
- **`CF_API_TOKEN`**: Account-Scope, alle Ressourcen (`Zone:Read`, `Zone:Edit`,
|
||||
`Account:Read`, `Workers:Read`, `Workers:Edit`, `Access:Read`, `Access:Edit`,
|
||||
`Tunnel:Read`). Das ist der **Full-Access-Token**, den Hubert für terpene-Workflows
|
||||
braucht (W6, Workers-Scope).
|
||||
- **`CF_DNS_API_TOKEN`**: `Zone:DNS:Edit`, **Scope auf `emsenhuber.net` und
|
||||
`teilzeitladen.xyz` beschränken** (nicht account-weit — Lehrgeld aus 2026-08-24).
|
||||
3. In `~/.secrets/credentials.env` schreiben, **nicht** ins Repo.
|
||||
4. Verify-Test im Nachgang (gleicher curl wie oben):
|
||||
```bash
|
||||
source ~/.secrets/credentials.env
|
||||
curl -sg "https://api.cloudflare.com/client/v4/user/tokens/verify" \
|
||||
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'
|
||||
# {"id":"...", "status":"active", "expires_on":"..."}
|
||||
```
|
||||
|
||||
### 1.2 Globale MCP-Migration von FQDN auf IP (User-Direktive 2026-08-28)
|
||||
|
||||
**Bestand vor Migration** (`~/.config/opencode/opencode.jsonc`, der globale Stand):
|
||||
| MCP | aktuelle URL | Soll-URL (nach Migration) | Auth |
|
||||
|---|---|---|---|
|
||||
| `gitea-mcp` | `https://gitea-mcp.emsenhuber.net/mcp` ❌ | `http://10.40.20.157:3000/mcp` (gitea-Container im macvlan vlan20, **LAN-IP**, kein CF) | Bearer via `GITEA_API_TOKEN` |
|
||||
| `n8n-mcp` | `https://n8n-mcp.emsenhuber.net/mcp` ❌ | `http://10.40.20.167:3001/mcp` (n8n-mcp-Container, macmini) — oder lokale IP. **Achtung:** `<n8n-mcp>.cf-tunnel-bf-mm` läuft über `bf-mm`-Tunnel, der Live ist. Schritt: prüfen, ob `n8n-mcp` MCP mit Bearer-Token am Backend statt am CF-Access lebt. | Bearer via `N8N_MCP_BEARER` |
|
||||
| `cloudflare` | `https://mcp.cloudflare.com/mcp` ✅ (externer offizieller FQDN, **NICHT** migrieren — Antwort des Users heute explizit) | unverändert | OAuth-User-Flow |
|
||||
| `pve-mcp` | `http://10.40.20.173:3000/mcp` ✅ | unverändert | keine (LAN-only) |
|
||||
| `home-assistant` | `http://10.40.20.105:9583/...` ✅ | unverändert | Token in URL |
|
||||
| `mikromcp` | npx-lokal | unverändert | env-PASS |
|
||||
| `ollama` | npx-lokal | unverändert | env-OLLAMA_HOST |
|
||||
| `hostinger-api` | npx-lokal | unverändert | env-TOKEN |
|
||||
| `playwright` | npx-lokal | unverändert | keine |
|
||||
|
||||
**Was der Nachfolger macht:**
|
||||
1. **Backup** der aktuellen `~/.config/opencode/opencode.jsonc` machen
|
||||
(`cp ... .bak-pre-mcp-ip-migration-20260828`).
|
||||
2. **Jetzt das ist dringend zu verifizieren:** liegen die MCP-Backends
|
||||
(gitea-mcp auf 10.40.20.157, n8n-mcp auf 10.40.20.167, oder 10.40.20.105 für HA)
|
||||
**tatsächlich** auf diesen IPs und antworten auf `/mcp`? **Bestandsaufnahme
|
||||
zuerst**, nicht raten:
|
||||
```bash
|
||||
nc -z -G 3 10.40.20.157 3000 # gitea
|
||||
nc -z -G 3 10.40.20.167 3001 # n8n-mcp
|
||||
# Antwort: "Connection to ... port ... [tcp] succeeded!" = gut.
|
||||
```
|
||||
Falls eine IP nicht antwortet: **nicht** auf CF-FQDN zurückfallen — User-Direktive
|
||||
war klar „FQDN raus". Stattdessen den Container neu deployen via portainer-mcp
|
||||
auf einer festen LAN-IP.
|
||||
3. **gitea-mcp** und **n8n-mcp** in `opencode.jsonc` umstellen:
|
||||
- `url` auf die LAN-IP.
|
||||
- `headers: {"Authorization": "Bearer {env:...}"}` — env-Werte aus
|
||||
`~/.secrets/exports.zsh` (gitea-Token aus `git` User im gitea-Repo selbst;
|
||||
n8n-MCP-Bearer aus dem n8n-mcp-Container-Config).
|
||||
4. **Funktionstest** mit `opencode mcp list`, dann optional mit echtem Tool-Call
|
||||
via LLM. Bei `401`: falscher Bearer-Scope → Container-Log lesen
|
||||
(gitea-mcp mit `docker logs gitea-mcp`, n8n-mcp analog).
|
||||
|
||||
**Achtung:** die projektspezifische `bf-infra/opencode.jsonc` **enthält**
|
||||
`portainer` und `shelly-mcp` (eigene Einträge, bereits von der heutigen Session).
|
||||
Der globale opencode.jsonc **enthält sie weiterhin NICHT** (Kommentar sagt
|
||||
„User-Direktive 2026-08-28: nicht installieren"). **Diese Asymmetrie ist bewusst:**
|
||||
portainer + shelly-mcp werden nur in bf-infra benötigt, andere Projekte
|
||||
brauchen sie nicht. **Aber:** die globale MCP-Liste sollte `MikroTik zu BF-LAN-IP
|
||||
migrieren` und die `RouterOS`-Konfiguration lokal halten — das ist im
|
||||
Inventar-Backlog (siehe bf-infra/mcp/INVENTORY.md).
|
||||
|
||||
### 1.3 terpene/blaueblueten-n8n — `.mcp.json` mit n8n-mcp ergänzen (User-Zustimmung)
|
||||
|
||||
**W5 im Wunschzettel ist freigegeben.** `blaueblueten-n8n/.mcp.json` existiert
|
||||
schon mit `gitea-mcp`. **Was rein soll:**
|
||||
```jsonc
|
||||
{
|
||||
"mcpServers": {
|
||||
"gitea-mcp": { "type": "http", "url": "http://10.40.20.157:3000/mcp" },
|
||||
"n8n-mcp": {
|
||||
"type": "http",
|
||||
"url": "http://10.40.20.167:3001/mcp",
|
||||
"headers": {"Authorization": "Bearer <N8N_MCP_BEARER>"}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- **Achtung Domain:** **420.teilzeitladen.xyz** (nicht `terpene.teilzeitladen.xyz`)
|
||||
ist die Live-Domain. Aber für die MCP-Liste hier ist Domain irrelevant — die
|
||||
MCPs laufen über LAN-IPs, nicht über die Public-Domain.
|
||||
- **Source-of-truth der Token:** `N8N_MCP_BEARER` aus `~/.secrets/exports.zsh`.
|
||||
Vor Eintrag erst verifizieren, dass es dort steht.
|
||||
|
||||
### 1.4 STATUS.md-Korrektur im terpene-Projekt (User-Direktive: **420.teilzeitladen.xyz** ist die echte Domain)
|
||||
|
||||
`STATUS.md` schreibt aktuell fälschlich `terpene.teilzeitladen.xyz` als Live-URL
|
||||
(Zeile 6, „v3 — 2026-07-27"). Korrektur:
|
||||
- Suchen/Ersetzen: `terpene.teilzeitladen.xyz` → `420.teilzeitladen.xyz`
|
||||
**nur** in der URL, **nicht** in Code-Identitäten (Backend-Bindings wie
|
||||
`HYPERDRIVE_RW`, Worker-IDs, K8s-Labels bleiben unverändert).
|
||||
- Im STATUS.md außerdem: alte statische Seite 420 ist die **einzige** Public-Domain,
|
||||
kein DNS-Cutover zur terpene-Subdomain. Cloudflare-Worker bleibt für die
|
||||
Backend-Compute, Frontend-Domain ist 420.
|
||||
|
||||
---
|
||||
|
||||
## 2. Offene Punkte (User-gated)
|
||||
|
||||
### 2.1 W1 terpene — pg_hba.conf (User-blocked)
|
||||
- **Status:** ⏸️ deferred. Christoph hat die Entscheidung.
|
||||
- **Was Hubert in terpene dafür bräuchte:** `pg_hba.conf`-Zeile
|
||||
`host terpene terpene_rw 10.40.10.0/24 scram-sha-256` + `pg_ctl reload`.
|
||||
- **Was der Nachfolger NICHT tut:** keine Änderung. Wartet auf Christoph.
|
||||
|
||||
### 2.2 W2 terpene — `420.teilzeitladen.xyz` aus LAN erreichbar (TP31-Schritt 5–6)
|
||||
- **Mechanik gelöst** durch 1.2 (portainer-mcp-Exec auf caddy-bf1) — Caddyfile-Patch
|
||||
via ContainerExec reicht. **DNS-Token-Problem bleibt** (W6), aber Caddyfile-Patch
|
||||
ist davon unabhängig.
|
||||
- **Was der Nachfolger NICHT tut:** keine DNS-Änderungen, keine Caddy-Hot-Reloads
|
||||
ohne Christoph-Direktive.
|
||||
|
||||
### 2.3 W3 terpene — Caddyfile-Patch ohne SSH
|
||||
- **Status:** ⏸️ deferred. Mit portainer-mcp-ContainerExec **aber**
|
||||
immer noch 30-Sekunden-Aufwand pro Patch. Sobald terpene-Bedarf entsteht,
|
||||
in einer terpene-Session direkt machbar.
|
||||
- **Was nicht im Weg steht:** portainer-mcp funktioniert (verifiziert heute).
|
||||
|
||||
### 2.4 W4 terpene — Caddy-Access-Logs lesbar
|
||||
- **Status:** ⏸️ deferred. Kein Workaround.
|
||||
|
||||
### 2.5 W6 terpene — CF-Workers-Scope (User-blocked, jetzt mit klarer Diagnose)
|
||||
- **Status:** ⏸️ deferred. **Aber:** der Befund 1.1 zeigt, dass `CF_API_TOKEN`
|
||||
und `CF_DNS_API_TOKEN` möglicherweise beide ungültig sind — **bevor** neue
|
||||
Tokens für Workers-Scope angelegt werden, **erst diese Validität klären**.
|
||||
- **Vermutung:** Christophs `~/.secrets/` enthält einen **alten, abgelaufenen** Token.
|
||||
Im CF-Dashboard nachsehen, ggf. neu anlegen.
|
||||
|
||||
### 2.6 W7 terpene — bf-public-Tunnel-Status
|
||||
- **Wo steht's:** `docs/teilprojekte.md` Quick-Index, TP31-Zeile: „Offen: Schritt 5–6
|
||||
(Tunnel `bf-public`, Abbau)".
|
||||
- **Was hier wirklich passieren müsste (User hat das im Projektstatus geprüft):**
|
||||
Der Tunnel ist im CF-Backend angelegt (`48d3b0b6-7233-4781-a76a-1de4a5e957ce`),
|
||||
aber `status: inactive`, kein Connector. **Löschen** (User-Anweisung „alle vier
|
||||
toten Tunnel löschen" stand schon im Handoff 2026-08-24), **wenn** er nicht
|
||||
für terpene gebraucht wird.
|
||||
- **Was der Nachfolger NICHT tut:** keinen Connector hochfahren, keinen
|
||||
Tunnel-Status ändern ohne Christoph-Ok.
|
||||
|
||||
---
|
||||
|
||||
## 3. Werkzeug/MCP-Stand am Übergabepunkt
|
||||
|
||||
### 3.1 Bereitgestellt heute
|
||||
- **portainer-mcp** in `bf-infra/opencode.jsonc` (uvx-stdio, 193 Tools)
|
||||
- **shelly-mcp** in `bf-infra/opencode.jsonc` (remote StreamableHTTP,
|
||||
`http://10.40.20.180:3030/mcp`)
|
||||
- **Portainer-Server 2.40 → 2.42.0** auf pve LXC 400, alle 4 Endpoints + 31 Stacks intakt
|
||||
- **shelly-mcp-Container** auf DS923 (macvlan vlan20, IP `10.40.20.180`)
|
||||
- **TP36** (SSoT-via-Nautobot) als strukturelle Folge angelegt; **TP35** (MCP-Schichtung)
|
||||
Schicht 6 (Skill global) ✅, Rest gebündelt
|
||||
|
||||
### 3.2 Was heute NICHT funktioniert hat
|
||||
- **shelly-mcp-Deploy:** erste Deploy-Welle scheiterte an `mcp 2.x`-Inkompatibilität
|
||||
(`MCPServer`-Umbenennung). Fix: `requirements.txt` `mcp[cli]>=1.0,<2`. **Commit `b8fd42b`.**
|
||||
- **Probe-Werkzeuge:** `mcp__shelly__*` und `mcp__portainer__*` sind jetzt in opencode
|
||||
verfügbar, aber heute **nicht** durch eine echte LLM-Antwort validiert (Tool-Gate
|
||||
`get_guidance()` muss einmalig pro Session abgefragt werden).
|
||||
- **Leak #2 in dieser Session:** `sed 's/SHELLY_DEVICE_PW=.*/=<set>/'` auf der Stack-YML
|
||||
hat den Wert **nicht** maskiert. Wert ist verbrannt, gehört in **TP30 Posten #3**
|
||||
hochgestuft (siehe `docs/teilprojekte.md` Abschnitt TP30). Lessons-Block in
|
||||
CLAUDE.md ergänzt (Sed-Replacement-Pattern zu wenig greedy).
|
||||
|
||||
### 3.3 Globale vs. projekt-spezifische MCP-Liste — aktuelle Asymmetrie
|
||||
- **global** (`~/.config/opencode/opencode.jsonc`): 11 MCPs, **enthält KEIN**
|
||||
portainer + shelly-mcp. Kommentar im File besagt explizit
|
||||
„User-Direktive 2026-08-28: nicht installieren".
|
||||
- **projekt bf-infra** (`bf-infra/opencode.jsonc`): 11 MCPs, **enthält** portainer
|
||||
+ shelly-mcp.
|
||||
- **projekt terpene/blaueblueten-n8n** (`blaueblueten-n8n/.mcp.json`): **1 MCP** aktuell
|
||||
(gitea-mcp), soll um n8n-mcp ergänzt werden (siehe 1.3).
|
||||
|
||||
---
|
||||
|
||||
## 4. Aus dem Userwortlaut zum Sessionende
|
||||
|
||||
Originalaussagen Christophs (verbatim, Reihenfolge wie im Chat):
|
||||
1. „420.teilzeitladen.xyz ist unsere domain. alle übrigen sind ungültig und falsch."
|
||||
2. „stelle n8n-mcp bitte global auf die passende IP um. gilt analog für alle übrigen
|
||||
mcps, die noch fqdn verwenden."
|
||||
3. „hast du einen konkreten plan, wie das projekt webseitig publiziert wird?
|
||||
stichwort caddy cloudflare."
|
||||
4. „prüfe welche berechtigungen du hast. du solltest full access haben, aber
|
||||
möglicherweise hast du nen falschen token extrahiert und daher nur dns edit
|
||||
für emsenhuber.net"
|
||||
5. „intern geht es gerne auch ohne bearer. dsa war ja mitunter der gedanke,
|
||||
weil es da immer probleme gab. warp löst es in einem zug."
|
||||
|
||||
**Aus 5.** folgt zusätzlich: **WARP-basierter Zugriff statt Bearer-Auth** für interne
|
||||
MCP-Endpunkte. Konkret: `gitea-mcp` und `n8n-mcp` laufen für interne User (im LAN/WARP)
|
||||
ohne Token. **Konsequenz für 1.2:** die `Authorization: Bearer` Header im
|
||||
`opencode.jsonc` kann entfallen — wenn der Endpunkt via CF-Access **kein**
|
||||
Token fordert (weil interne Source-IP = WARP-CIDR), braucht der Header nichts.
|
||||
|
||||
→ **Migrations-Reihenfolge für 1.2:**
|
||||
(a) Erst WARP-Policy testen (geht der Connector ohne Token mit WARP?). Wenn ja: Header leer.
|
||||
(b) Wenn nein: Bearer-Header mit Token aus `~/.secrets/`.
|
||||
|
||||
**Aus 3.** ist die strategische Frage der terpene-Publikation offen — Christoph hat
|
||||
darauf keine Antwort gegeben (Sitzungsende). Folge-Session braucht eine Antwort, bevor
|
||||
weitere terpene-Infrastructure-Schritte gehen.
|
||||
|
||||
---
|
||||
|
||||
## 5. Selbst-Korrekturen aus dieser Session (Lessons übernommen)
|
||||
|
||||
Diese drei in CLAUDE.md sind neu und der Nachfolger muss sie kennen:
|
||||
- **Wartungs-Token**: `~/.secrets/exports.zsh` lädt **nicht automatisch** in jeder
|
||||
Shell — `source` musst du explizit machen. Das `bash`-Tool in opencode macht das nicht.
|
||||
Vor CF-Calls, vor Portainer-Calls, vor Secret-Vergleichen: `source ~/.secrets/exports.zsh`.
|
||||
- **`sed 's/=.*/=<set>/'` maskiert NICHT**, wenn der Wert Slashes/Backslashes/Zeichen
|
||||
enthält → siehe CLAUDE.md, Lessons-Block.
|
||||
- **Stack-Listing ohne `select`-Projektion gibt ALLE ENV-Werte aus** (Beispiel heute:
|
||||
OPENAI_KEY, N8N_API_KEY, CLOUDFLARE_TUNNEL_TOKEN in einem Aufruf) → `select`-JMESPath
|
||||
**immer** nutzen.
|
||||
|
||||
---
|
||||
|
||||
## 6. Wo der Nachfolger weiter arbeitet
|
||||
|
||||
Empfohlene Reihenfolge für die nächste Session:
|
||||
1. **1.1 CF-Token-Audit** (höchste Blocker-Kraft — fast alles hängt daran).
|
||||
2. **1.2 Globale MCP-Migration** (gitea + n8n zuerst, weil terpene aktiv ist).
|
||||
3. **1.4 STATUS.md-Korrektur** im terpene-Projekt (1 Minute).
|
||||
4. **1.3 terpene-n8n-mcp** in `.mcp.json` (5 Minuten, sobald 1.2 durch ist).
|
||||
5. **Strategie-Frage 3** aus 4.: **Wie publizieren wir terpene.teilzeitladen.xyz?**
|
||||
Vorschlag für Christoph: Worker bleibt; `bf-public`-Tunnel ggf. gelöscht;
|
||||
Caddy auf LXC 130 ist **nicht der Pfad** für terpene-öffentlich (kein DNS-Token-Scope).
|
||||
|
||||
**Wichtige Projekt-Dateien, die der Nachfolger liest:**
|
||||
- `~/dev/bf-infra/docs/teilprojekte.md` — SSoT für alle TPs (Quick-Index Zeile 178–216).
|
||||
- `~/dev/bf-infra/CLAUDE.md` Lessons-Block — alle hier entstandenen Lehren.
|
||||
- `~/dev/bf-infra/opencode.jsonc` — projekt-spezifische MCP-Liste.
|
||||
- `~/dev/bf-infra/mcp/INVENTORY.md` — was läuft, was war, was soll nicht.
|
||||
- `~/dev/bf-infra/docs/handoff-20260828-portainer-bump-und-mcp.md` — Parallel-Handoff
|
||||
zum Portainer-Bump.
|
||||
- `~/dev/blaueblueten-n8n/docs/infra-wunschzettel.md` — Huberts Wunschzettel an Christoph.
|
||||
- `~/dev/blaueblueten-n8n/STATUS.md` — terpene-Live-Status (mit Domain-Korrektur-Bedarf).
|
||||
|
||||
---
|
||||
|
||||
**Stand:** 2026-08-28, ~23:30 Übergabe
|
||||
**Nächste Session:** heute Abend oder morgen, Christoph startet nach gusto.
|
||||
82
docs/handoff-20260830-ap3.md
Normal file
82
docs/handoff-20260830-ap3.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Handoff 2026-08-30 — ap3 (cAP ax) live, TP28 wieder geöffnet und durchgezogen
|
||||
|
||||
## Was jetzt gilt
|
||||
|
||||
**ap3 funkt.** MikroTik cAP ax (`cAPGi-5HaxD2HaxD`), `10.40.99.13/24` auf `vlan99`, Uplink
|
||||
`ether1` → **`crs326-core ether21`**, reiner CAP unter `crs326-core`. Kanäle **`5180/ax/Ce/I`**
|
||||
(5 GHz) und **`2437/ax`** (ch6) — am Gerät nachgemessen, nicht aus dem Plan abgeschrieben.
|
||||
|
||||
**ap1 ist funkstill.** Es steht bis zu seinem Umzug ans Sideboard direkt neben ap3 und würde auf
|
||||
5180 kollidieren. Es hat deshalb **keine Provisioning-Regel** am Manager; das Gerät bleibt
|
||||
erreichbar, die Objekte `ch-*-ap1`/`cfg-main-*-ap1` bleiben für den Umzug stehen.
|
||||
|
||||
**Compliance: 130/130, 0 Drifts über 5 Geräte.**
|
||||
|
||||
## Was noch offen ist
|
||||
|
||||
1. **TP25-Messrunde** — `bash docs/tp25-runde.sh ap3-bringup`, dann `docs/tp25-walk-messung.sh`
|
||||
für den Gehweg Technik UG ↔ OG. Braucht einen Rundgang mit dem Telefon.
|
||||
Leitfrage: **deckt ap3 allein ab, was ap1 abgedeckt hat, oder klafft bis zum Umzug eine Lücke?**
|
||||
2. **Passwort-Rotation (TP30)** — das gemeinsame MikroTik-Admin-PW ist in dieser Session
|
||||
verbrannt (ungefilterte Ausgabe des `mikromcp`-`env`-Blocks aus `~/.claude.json`). ap3 trägt es
|
||||
bereits, hängt also in der Rotation mit drin. Fehlen zusätzlich in `~/.secrets/exports.zsh`:
|
||||
`MCP_MIKROMCP_ROUTER_AP3_PASS`, `MCP_MIKROMCP_CRS326_CORE_PASS`, `MCP_MIKROMCP_CRS326_BRANCH_PASS`.
|
||||
3. **MikroMCP-Neustart** — Registry (jetzt `bf-infra`, mit ap3) wird nur beim Start gelesen.
|
||||
4. **Versions-Differenz** — ap3 läuft auf **7.24.1**, die anderen vier auf **7.24**. Bewusst:
|
||||
7.20.8 (Januar, long-term) wäre ein halbes Jahr Abstand zur `/interface wifi`-Implementierung
|
||||
des Managers gewesen. Die Angleichung der Flotte ist ein eigener TP27-Durchgang — der
|
||||
Core-Reboot ist ein Standort-Ausfall und damit Terminentscheidung.
|
||||
5. **Kabel `ap3 ether2` → `core ether22`** kann raus. Seit Phase 2 ist `ether2` kein Bridge-Port
|
||||
mehr, das Kabel ist inert.
|
||||
6. **Offene Frage aus TP22:** auf den APs deckt **keine ComplianceRule** `/interface wifi` ab.
|
||||
Genau dort sitzt `configuration.manager=capsman` — ein Feld, dessen Fehlen das WLAN eines APs
|
||||
still verhindert (s. unten). Ob dafür eine Regel sinnvoll ist, ist noch nicht entschieden.
|
||||
|
||||
## Die sechs Funde, die Zeit gekostet haben
|
||||
|
||||
1. **`ether1` ist am Werksgerät WAN.** Discovery aus (kein MNDP), Input-TCP verworfen
|
||||
(22/80/8291/8728 zu) — **aber ICMP erlaubt**. Es *pingt*, und das liest sich wie „erreichbar".
|
||||
MikroMCP hilft nicht: es ist ein HTTP-Client auf Port 80, und der ist zu. Gegenprobe, dass der
|
||||
Core nicht schuld war: Regel 44 `MAIN->MGMT` ist `action=accept` **ohne** Port-Einschränkung.
|
||||
2. **`pvid` ist Ingress, `tagged`/`untagged` ist Egress.** Ein DHCP-Lease hing ewig auf `offered`,
|
||||
ARP auf `failed`: `pvid=99` nahm den DISCOVER an, aber der Port stand in der *tagged*-Liste von
|
||||
VLAN99 — der ACK ging getaggt raus, ein Werksgerät versteht das nicht.
|
||||
3. **`cap enabled=yes` reicht nicht.** Jedes Master-Radio braucht zusätzlich
|
||||
`configuration.manager=capsman`, sonst bietet der CAP seine Radios dem Manager gar nicht an:
|
||||
`remote-cap print` zeigt `state=Ok`, `/interface wifi radio print` bleibt leer — und man sucht
|
||||
den Fehler in der `radio-mac`.
|
||||
4. **Ein neues Gerät ohne `secrets_group` erzeugt eine Lücke, keine Fehlermeldung.** Der Backup-Job
|
||||
scheitert still, die *intended* config wird trotzdem gerendert, und ohne Backup entstehen keine
|
||||
Compliance-Einträge. Die Zahl blieb bei **104/104** — unauffällig. 🔴 **Eine gleichbleibende
|
||||
Compliance-Zahl nach dem Hinzufügen eines Geräts ist ein Befund, kein Erfolg.** Zweite
|
||||
Voraussetzung: die Service-Accounts `nautobot`/`ha` gibt es auf einem Werksgerät nicht.
|
||||
5. **CAPsMAN verteilt keine Login-Passwörter.** Zentral sind die **WLAN-PSKs**; der Geräte-Login
|
||||
(`/user`) ist eine lokale DB pro Gerät. Das einheitliche Admin-PW ist eine von Hand angewendete
|
||||
Konvention.
|
||||
6. **Firewall-Regelnummern aus `print where` sind Handles, keine Positionen.** Nach `place-before`
|
||||
zeigte die TEMP-Regel **60** neben `drop` auf **59** — lag aber davor. Beweis ist der Zähler
|
||||
(`print stats`), nicht die Zahl.
|
||||
|
||||
## Zwei Korrekturen an bestehender Doku
|
||||
|
||||
- **Der Kanalplan war schon da.** TP25 hatte ihn am **2026-08-24** für genau dieses Gerät gerechnet
|
||||
(DFS vom User genehmigt). Ich hatte ihn zunächst neu erfunden und wäre bei ch1 statt **ch6**
|
||||
gelandet. Merkregel: den TP-Body lesen, nicht nur den Quick-Index.
|
||||
- **Der Port war `ether21`, nicht `ether22`.** Der Befund lag in den Daten: in der dynamischen
|
||||
`pvid`-VLAN1-Zeile stand `current-untagged=…,ether21`. Gegenprobe ist
|
||||
`/interface bridge host print where interface=etherN` — dort steht die MAC des Gegenübers.
|
||||
- **ap1 stand in Nautobot auf „Wohnzimmer Sideboard"**, physisch aber in **Technik UG**. Der
|
||||
Eintrag war der Ziel-Standort nach dem geplanten Umzug. Korrigiert.
|
||||
|
||||
## Dateien
|
||||
|
||||
| Datei | Zweck |
|
||||
|---|---|
|
||||
| `routeros/tp28-ap3-phase1-erreichbar.rsc` | über die LAN-Seite: `ether1` aus WAN, Mgmt auf `vlan99` |
|
||||
| `routeros/tp28-ap3-phase2-cap.rsc` | über `vlan99`: Werks-WLAN weg, CAP-Modus, `vlan-filtering=yes` |
|
||||
| `routeros/tp28-ap3-service-accounts.rsc` | `nautobot`/`ha` + Gruppen (sonst kein GC-Backup) |
|
||||
| `routeros/tp28-ap3-werksreste.rsc` | die drei Drifts aus dem ersten Compliance-Lauf |
|
||||
| `nautobot/ingest-ap3-device.py` | DeviceType, Device, 16 Interfaces, IP, SecretsGroup |
|
||||
|
||||
Alle vier `.rsc` tragen Platzhalter statt Secrets; die echten Dateien werden zur Laufzeit ins
|
||||
Scratchpad generiert und danach gelöscht.
|
||||
188
docs/handoff-20260831-fund-e-hebel1-gezogen.md
Normal file
188
docs/handoff-20260831-fund-e-hebel1-gezogen.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# Handoff 2026-08-31 — TP25 Fund E: Hebel 1 ist gezogen, die Uhr läuft
|
||||
|
||||
> Vorgänger: [`handoff-20260831-wlan-fund-e.md`](handoff-20260831-wlan-fund-e.md) (Befund + Messrezept).
|
||||
> **Dieses Dokument ist der Stand danach.** Es gibt genau eine offene Aufgabe: **messen und entscheiden.**
|
||||
|
||||
## Was am 2026-08-31 um 08:09 passiert ist
|
||||
|
||||
**Eine** Änderung, sonst nichts:
|
||||
|
||||
```
|
||||
/interface wifi security set [find name="sec-main"] ft-over-ds=no # vorher: yes
|
||||
/interface wifi capsman remote-cap provision [find]
|
||||
```
|
||||
|
||||
`ft=yes` bleibt — Fast Transition läuft weiter **over-the-air**, nur nicht mehr **over-the-DS**. Das
|
||||
nimmt exakt die Änderung vom 2026-08-17 zurück, mehr nicht. **Kein weiterer Funk-Parameter ist
|
||||
angefasst worden** (Stop-Bedingung: wer zwei Hebel zieht, weiß hinterher nichts).
|
||||
|
||||
## Abnahme — was tatsächlich geprüft wurde
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| Wirkt der Hebel? **am Manager, alle Master-VAPs** | `cap-wifi3/4/5/6` → `ft=true ft-over-ds=false`. `cap-wifi1/2` (= ap1) leer, weil ap1 funkstill ist. |
|
||||
| CAPs zurück? | alle drei `state=Ok` |
|
||||
| VAPs laufen? **am CAP gelesen**, nicht am Manager | ap2 und ap3: alle 9 Interfaces `running=yes` |
|
||||
| **Frische DHCP-Lease** (die vorgeschriebene Abnahme) | iPhone `F2:62:4C:E1:AF:09` nach 71 s wieder auf `dirtyvader-main`, `10.40.10.196`, **`auth-type=ft-wpa3-psk`**, −54 dBm |
|
||||
| Clients gesamt | 30 zurück |
|
||||
| Roaming funktioniert noch? | ja — Log zeigt um 08:13:20 ein sauberes `roamed to` zwischen zwei APs auf `main` |
|
||||
| Compliance | **134/135**, Diff **exakt** `ft-over-ds=yes → no`. **Kein Kollateral-Drift.** |
|
||||
|
||||
Geräte-Backup vor dem Eingriff: `pre-tp25-funde-ftoverds.backup` auf dem Core (08:07:58).
|
||||
|
||||
## 🔴 Warum Compliance auf 134/135 steht und das RICHTIG ist
|
||||
|
||||
Die Transaktion **`TP25-fund-e-ft-over-ds`** ist **offen** (Scope `wifi-security`, Ablauf
|
||||
**2026-09-03**). `gc-transaktion.py status` weist den einen Drift als **erwartet** aus — genau dafür
|
||||
gibt es das Werkzeug.
|
||||
|
||||
**Das Template wird bewusst NICHT vorher nachgezogen.** Wer es jetzt grün macht, macht den laufenden
|
||||
Versuch unsichtbar, und `status` kann ihn nicht mehr von einem Versehen unterscheiden. `gc-transaktion.py`
|
||||
erzwingt die richtige Reihenfolge ohnehin: es verweigert den Commit, solange der Scope driftet.
|
||||
**135/135 kommt beim Commit zurück** — nach der Messung, nicht davor.
|
||||
|
||||
## 🔴 Die `cap-wifiN`-Karte hat sich beim Re-Provisionieren VERSCHOBEN
|
||||
|
||||
Wer die Logs vom 31.08. auswertet und das übersieht, ordnet Ereignisse dem falschen AP zu:
|
||||
|
||||
| | vor 08:09 (Logzeilen 07:xx) | ab 08:09 |
|
||||
|---|---|---|
|
||||
| ap1 (funkstill) | — | `cap-wifi1` / `cap-wifi2` |
|
||||
| ap2 | `cap-wifi1` / `cap-wifi2` | `cap-wifi3` / `cap-wifi5` |
|
||||
| ap3 | `cap-wifi5` / `cap-wifi6` | `cap-wifi4` / `cap-wifi6` |
|
||||
|
||||
Gelesen mit `/interface wifi radio print` am Manager. Das ist dieselbe Instabilität, die
|
||||
[`tp25-walk-messung.sh`](tp25-walk-messung.sh) als `ap-map.txt` einfriert — hier von Hand.
|
||||
|
||||
## ⚠️ Korrektur am Befund vom Vormittag
|
||||
|
||||
Der Vorgänger-Handoff sagt, `main` unterscheide sich von den anderen fünf SSIDs in **genau einem**
|
||||
Attribut. **Live nachgelesen sind es zwei:**
|
||||
|
||||
```
|
||||
sec-main authentication-types=wpa3-psk ft=yes ft-over-ds=yes
|
||||
sec-infra … authentication-types=wpa2-psk,wpa3-psk ft=no
|
||||
```
|
||||
|
||||
`sec-main` ist **auch die einzige SSID ohne `wpa2-psk`**. Die Kontrollgruppe trennt FT und WPA3-only
|
||||
also **nicht** voneinander. Das ändert die Hebelreihenfolge nicht — die Hypothese nennt gerade die
|
||||
Kombination WPA3+FT — aber es ändert den Plan B:
|
||||
|
||||
⇒ **Wenn Hebel 1 und Hebel 2 (`ft=no`) beide nichts bewegen, ist der nächste Kandidat
|
||||
`authentication-types=wpa2-psk,wpa3-psk` auf `sec-main` — NICHT `signal-range`.**
|
||||
|
||||
## Die einzige offene Aufgabe: messen
|
||||
|
||||
```bash
|
||||
ssh root@10.40.20.100 "pct exec 400 -- sh -c 'cat /opt/tp5-syslog/log/10.40.20.1/2026-0*-*.log |
|
||||
grep reauthenticating | grep -oE \"([0-9A-F]{2}:){5}[0-9A-F]{2}\" | sort | uniq -c'"
|
||||
```
|
||||
|
||||
**Baseline: 93**, alle vom iPhone `F2:62:4C:E1:AF:09`, alle auf `dirtyvader-main`.
|
||||
Davon **79 am 31.08., sämtlich in Stunde 07**, der letzte um **07:34:43** — also **vor** dem Eingriff.
|
||||
Zwischen 08:00 und 08:15 kein einziges. **Das ist noch kein Ergebnis, nur der saubere Schnitt.**
|
||||
|
||||
Ein Gegencheck gehört dazu — er beweist, dass nicht einfach das Logging kaputt ist:
|
||||
|
||||
```bash
|
||||
ssh root@10.40.20.100 "pct exec 400 -- sh -c '
|
||||
grep wireless /opt/tp5-syslog/log/10.40.20.1/2026-09-01.log | wc -l;
|
||||
grep wireless /opt/tp5-syslog/log/10.40.20.1/2026-09-01.log | grep -oE \"\\(dirtyvader-[a-z]+\\)\" | sort | uniq -c'"
|
||||
```
|
||||
|
||||
### Die Entscheidung am 2026-09-01
|
||||
|
||||
| Messung | Schluss | Nächster Schritt |
|
||||
|---|---|---|
|
||||
| iPhone-`reauthenticating` **~0**, andere SSIDs unverändert | Hebel 1 hat gegriffen | Template `mikrotik_routeros.j2` Z. 220 auf `ft-over-ds=no` ziehen → `gc-transaktion.py commit --change-id TP25-fund-e-ft-over-ds` → Compliance zurück auf 135/135 |
|
||||
| Zahl **unverändert** | Hebel 1 hat **nicht** gegriffen | Rollback ODER stehen lassen und **Hebel 2 `ft=no`** als eigene Transaktion. Nicht beides gleichzeitig. |
|
||||
| Zahl runter, aber neue Ereignisse auf anderen SSIDs | Nebenwirkung | Rollback, dann neu bewerten |
|
||||
|
||||
Rollback-Weg (der Snapshot liegt bereit):
|
||||
`python3 nautobot/gc-transaktion.py rollback --change-id TP25-fund-e-ft-over-ds`
|
||||
— erzeugt einen **Vorschlag**, der gelesen werden will, und pusht bewusst nicht selbst.
|
||||
|
||||
## ✅ Nebenbefund erledigt: `sshpass -p` ist repo-weit weg (2026-08-31, zweiter Durchgang)
|
||||
|
||||
`sshpass -p <PW>` schreibt das Passwort in `argv`, wo es in `ps` und jedem argv-Trace steht — die
|
||||
Klasse, an der am 2026-08-22 das Core-Passwort verbrannt ist. **Alle sechs betroffenen Skripte laufen
|
||||
jetzt über `SSHPASS`-Env + `sshpass -e`:**
|
||||
|
||||
```
|
||||
nautobot/gc-transaktion.py (im ersten Durchgang, weil es laufen musste)
|
||||
routeros/import-core-rsc.py
|
||||
routeros/archiv-tp15-cutover/apply-core-cutover-l3.py ┐
|
||||
routeros/archiv-tp15-cutover/backup-core.py │ am selben Tag archiviert,
|
||||
routeros/archiv-tp15-cutover/restore-core.py │ s. unten -- aber VOR dem
|
||||
routeros/archiv-tp15-cutover/backup-ap1.py ┘ Verschieben noch gefixt
|
||||
```
|
||||
|
||||
**Warum Archiv-Code trotzdem gefixt wurde:** Archiv wird abgeschrieben. Wer sich dort ein
|
||||
sshpass-Muster holt, soll das richtige finden.
|
||||
|
||||
**Nachweis — gemessen, nicht gelesen:**
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| Alle 13 `subprocess.run`, die sshpass starten, tragen `env=` | ✓ per AST geprüft (ohne `env` wäre `SSHPASS` leer und alles kaputt) |
|
||||
| Signaturen passen zu den Aufrufen | ✓ per AST, Arity-Abgleich — `py_compile` findet so etwas **nicht** |
|
||||
| Echter Lauf des gepatchten Codes gegen den lebenden Core | ✓ `backup-core.py` importiert, IP zur Laufzeit auf `10.40.99.1`, Antwort `name: crs326-core`, rc=0 |
|
||||
| Passwort in `argv`? | **nein** |
|
||||
| Passwort in `ps` während der Verbindung? | **nein**, 40 Stichproben |
|
||||
| **Negativkontrolle** — Dummy-Wert über die alte `-p`-Form | **36 Treffer** ⇒ die Probe ist nicht blind, das „nein" oben hat Aussagekraft |
|
||||
|
||||
🔴 **Für TP30 ändert das nichts.** Der Weg ist zu, der Wert bleibt verbrannt — ein Passwort, das
|
||||
einmal in einem Transkript stand, wird nicht dadurch sauber, dass die Leitung dicht ist.
|
||||
Rotation von Posten #1 bleibt fällig.
|
||||
|
||||
⚠️ **Mitgefixt, weil es in umgebautem Code lag:** `apply-core-cutover-l3.py` griff in `run_silent`
|
||||
auf ein `pw` zu, das dort gar nicht existierte — **jeder Fehlerfall endete in einem `NameError`
|
||||
statt in der gedachten Meldung.**
|
||||
|
||||
### 🔴 Und dabei aufgefallen: die IPs in diesen fünf Skripten sind Schrott
|
||||
|
||||
Live geprüft am 2026-08-31, **bewusst NICHT stillschweigend geändert** — nur je ein lauter Header
|
||||
in die Datei:
|
||||
|
||||
| Skript | Ziel-IP | Realität |
|
||||
|---|---|---|
|
||||
| `import-core-rsc.py`, `apply-core-cutover-l3.py`, `backup-core.py` | `10.40.41.211` | **tot** — VLAN41 gibt es seit 2026-08-27 nicht mehr |
|
||||
| `restore-core.py` | `192.168.88.1` | **tot** — Werks-Temp-Pfad; dazu ein hartkodierter Backup-Dateiname vom 2026-08-06 |
|
||||
| `backup-ap1.py` | `10.40.10.1` | 🔴 **antwortet — ist aber der CORE** (VLAN10-SVI, tcp/22 offen). ap1 ist `10.40.99.11`. |
|
||||
|
||||
**`backup-ap1.py` ist der gefährliche:** er scheitert nicht, er sichert das **falsche Gerät** und legt
|
||||
die Datei als `ap1-pre-core-cutover-*.backup` ab. Wer dieses Backup später zurückspielt, spielt eine
|
||||
Core-Config auf einen AP.
|
||||
|
||||
✅ **Entschieden (Christoph, 2026-08-31): archiviert, nicht repariert.** Die vier liegen jetzt unter
|
||||
[`routeros/archiv-tp15-cutover/`](../routeros/archiv-tp15-cutover/README.md) mit README nach dem
|
||||
Muster von [`switch/`](../switch/README.md) — der Cutover ist am 2026-08-08 durchgezogen, die Skripte
|
||||
haben ihre Aufgabe erfüllt.
|
||||
|
||||
⚠️ **Die Pfad-Nebenwirkungen des Verschiebens sind absichtlich NICHT repariert** (`backup-core.py`
|
||||
schriebe jetzt ins Archivverzeichnis, `apply-core-cutover-l3.py` fände seine `.rsc` nicht mehr).
|
||||
Sie zu reparieren hieße, die Skripte wieder lauffähig zu machen — das ist gerade nicht die Absicht.
|
||||
|
||||
**`import-core-rsc.py` bleibt**, wo es ist: als einziges generisch nützlich. Sein Default-Host ist
|
||||
aber ebenfalls tot ⇒ **`--host` mitgeben**. (Und in `--host` steckt ein zweiter latenter Bug:
|
||||
`sys.argv[1]` wird als RSC-Pfad gelesen, bevor auf `--host` geprüft wird — die Option kann so, wie
|
||||
sie dokumentiert ist, nie greifen. **Nicht gefixt**, gehört zu einer eigenen Runde.)
|
||||
|
||||
**Entwarnung zum Snapshot:** `/export` auf ROS 7.24 gibt WLAN-Passphrasen **gar nicht** aus
|
||||
(0 Vorkommen im Vollexport, live geprüft). Die Transaktionsakte im Git ist sauber.
|
||||
|
||||
## 🔧 Zweiter Nebenbefund: Worktrees können `gc-*.py` nicht ohne Handgriff ausführen
|
||||
|
||||
`docs/nas-vlan20/stacks/210-nautobot.yml` ist gitignored und existiert deshalb **nur im
|
||||
Haupt-Checkout**. In einem Worktree scheitern `gc-transaktion.py` und `gc-configplan.py` am
|
||||
Nautobot-Token. Behelf in dieser Session war ein Symlink auf den Haupt-Checkout — **der gehört nicht
|
||||
committet**. Dauerhafte Antwort wäre `NAUTOBOT_TOKEN` aus `~/.secrets/exports.zsh` (gc-configplan
|
||||
liest die Variable bereits; gc-transaktion liest nur die Stack-Datei).
|
||||
|
||||
## Unverändert offen (nicht Teil dieser Session)
|
||||
|
||||
1. TP25-Messrunde mit Rundgang (`bash docs/tp25-runde.sh`) — ⚠️ **die `ap-map` neu einfrieren**, s.o.
|
||||
2. Passwort-Rotation TP30 (Admin-PW am 08-30 verbrannt; fehlende `MCP_MIKROMCP_*_PASS` in `exports.zsh`)
|
||||
3. MikroMCP-Neustart (Registry inkl. ap3 wird nur beim Start gelesen)
|
||||
4. ap1-Umzug ans Sideboard (`core ether3`, `5260/Ce`, Frequenz-**Liste** statt Einzelwert, `tx-power` vorher messen)
|
||||
5. Versions-Angleichung 7.24 → 7.24.1
|
||||
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
|
||||
162
docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md
Normal file
162
docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# Handoff 2026-08-31 nachmittags — TP27 durchgezogen, Hebel 1 gescheitert, Fund B entwarnt
|
||||
|
||||
> Vorgänger: [`handoff-20260831-fund-e-hebel1-gezogen.md`](handoff-20260831-fund-e-hebel1-gezogen.md)
|
||||
> (Eingriff + Abnahme). **Dieses Dokument ist der Stand danach** und löst ihn als aktuellen Zeiger ab.
|
||||
> Anlass war eine Nutzermeldung, nicht ein geplanter Messtermin.
|
||||
|
||||
## Ausgangspunkt: zwei erlebte Störungen mit Uhrzeit
|
||||
|
||||
Christoph hat zwei Vorfälle gemeldet und dazu — entscheidend — **Standort und Bewegung**:
|
||||
|
||||
| Zeit | Situation | Was er sah |
|
||||
|---|---|---|
|
||||
| **13:16** | Terrasse, Telefon in der Halterung, **unbewegt** | Telegram-Videocall bricht ab, „schwaches Signal", danach 5G |
|
||||
| **14:23** | Arbeitszimmer, kurz zuvor gewechselt, **unbewegt** am Schreibtisch | iPhone auf 5G, scannt dauernd, `-main` sichtbar, Verbinden schlägt fehl. **Behoben durch WLAN aus/ein.** |
|
||||
|
||||
Beide stehen im Kollektor, beide mit derselben Signatur — **Reauth-Schwall, dann ein Loch:**
|
||||
|
||||
```
|
||||
13:08:37–13:08:42 10 × reauthenticating 13:09:12 weg, −77
|
||||
→ 7 Minuten kein WLAN ← der Call-Abbruch
|
||||
14:17:47–14:18:07 4 × reauthenticating 14:18:29 weg, −72
|
||||
→ 5,5 Minuten kein WLAN ← „scannt, verbindet nicht"
|
||||
14:23:54 connected, −71 ← der WLAN-Toggle
|
||||
14:23:57–14:28:47 70 × reauthenticating auf dem anderen Radio
|
||||
```
|
||||
|
||||
**Der Toggle hat also nicht „reparariert", sondern eine Assoziation erzwungen** — das Hämmern lief
|
||||
danach auf dem zweiten Radio noch fünf Minuten weiter.
|
||||
|
||||
## 🔴 Ergebnis: Hebel 1 (`ft-over-ds=no`) hat NICHT gegriffen
|
||||
|
||||
Der Hebel wurde um **08:09** gezogen. Beide Vorfälle liegen **danach**.
|
||||
|
||||
| Fenster | `reauthenticating` |
|
||||
|---|---|
|
||||
| 07:00–08:00 (**vor** dem Hebel) | **79** |
|
||||
| 14:00–15:00 (**nach** dem Hebel) | **70** |
|
||||
| gesamt nach 08:09 bis 14:36 | **124** |
|
||||
|
||||
Vergleichbare Tagesstunden, praktisch unveränderte Rate, dazu zwei erlebte Ausfälle. Das
|
||||
Erfolgskriterium des Vorgänger-Handoffs lautete „geht auf ~0 zurück" — **nicht eingetreten.**
|
||||
|
||||
⚠️ **Gewertet wird bewusst nur das Fenster 08:09–14:36** (6,5 h auf unveränderter Firmware).
|
||||
Ab 14:36 kommt eine zweite Variable dazu, s. u. — Christoph-Entscheid 2026-08-31: „Vormittag als
|
||||
Ergebnis werten". Das ist keine 24-h-Messung, aber für ein **Negativ**-Ergebnis mit zwei erlebten
|
||||
Ausfällen belastbar.
|
||||
|
||||
## ✅ TP27 ist durchgezogen — die Flotte steht komplett auf 7.24.1
|
||||
|
||||
Von Christoph selbst, über WebFig vom MacBook (`10.40.10.82`), rollierend über den Tag:
|
||||
|
||||
| Gerät | Version | Reboot ca. |
|
||||
|---|---|---|
|
||||
| ap3 | 7.24.1 | gestern (kam schon so) |
|
||||
| ap2 | 7.24.1 | **08:56** |
|
||||
| crs326-core | 7.24.1 | **14:36** |
|
||||
| ap1 | 7.24.1 | **14:50** |
|
||||
| crs326-branch | 7.24.1 | **14:52** |
|
||||
|
||||
Die Doku-Zeile „Flotte auf 7.24, ap3 auf 7.24.1 — Differenz bewusst" ist damit **überholt**;
|
||||
die Angleichung, die als eigener TP27-Durchgang vorgemerkt war, ist erledigt.
|
||||
|
||||
**Zustand nach dem Upgrade, live geprüft (15:1x):**
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| CAPs | 3 × `state=Ok`, alle 7.24.1 |
|
||||
| Provisionierung | 4 Regeln (ap2 5G/2,4G, ap3 5G/2,4G) unverändert; ap1 bewusst ohne |
|
||||
| VAPs am CAP gelesen | ap2: 9 × `running=yes` |
|
||||
| Clients | 30 |
|
||||
| Transaktion überlebt? | `sec-main`: `ft=yes ft-over-ds=no` ✓ |
|
||||
| Core-Ressourcen | 435 MiB frei, CPU 8 % |
|
||||
|
||||
## ✅ Fund B (vermeintliche CAPWAP-Instabilität) ist ENTWARNT
|
||||
|
||||
Beim Nachsehen fielen 13 × `joined`, 4 × `activity timeout`, 3 × `connection interrupted` auf —
|
||||
das sah nach einem Manager-CAP-Problem aus, das alle Clients trifft. **Es war das Upgrade.**
|
||||
Jedes Ereignis fällt auf einen Reboot aus der Tabelle oben. Die Massenbursts
|
||||
`association rejected, no cached PMK` (74 Zeilen, 38 verschiedene MACs, um 08:08 und 14:33)
|
||||
sind Re-Provisionierungen, kein Defekt.
|
||||
|
||||
🔴 **Merkregel daraus:** ein Burst über **viele** MACs ist ein Infrastruktur-Ereignis, ein Burst über
|
||||
**eine** MAC ein Client-Ereignis. Vor jeder Client-Diagnose erst `grep " caps,"` und `uptime` lesen —
|
||||
sonst sucht man einen Gerätefehler, der ein geplanter Reboot war.
|
||||
|
||||
## Neue Beobachtungen, die in der Auswertung morgen gebraucht werden
|
||||
|
||||
**1. Die Logzeile `association rejected, no cached PMK` ist neu** — 157 × am 31.08., **null** am
|
||||
30.08. Sie benennt die PMK-Caching-Achse ausdrücklich. Der überwiegende Teil sind Reboot-Folgen
|
||||
(s. o.), aber nicht alle.
|
||||
|
||||
**2. Die `cap-wifiN`-Karte hat sich seit 08:09 ERNEUT verschoben.** Die Tabelle im Vorgänger-Handoff
|
||||
ist bereits wieder falsch:
|
||||
|
||||
| | Handoff-Stand 08:09 | **live 15:1x** |
|
||||
|---|---|---|
|
||||
| ap1 | `cap-wifi1` / `cap-wifi2` | `cap-wifi1` / `cap-wifi2` |
|
||||
| ap2 | `cap-wifi3` / `cap-wifi5` | **`cap-wifi5` / `cap-wifi6`** |
|
||||
| ap3 | `cap-wifi4` / `cap-wifi6` | **`cap-wifi3` / `cap-wifi4`** |
|
||||
|
||||
⇒ Die Karte verschiebt sich bei **jedem** CAP-Rejoin, nicht nur beim Re-Provisionieren. Bei fünf
|
||||
Reboots an einem Tag heißt das: **Interface-Namen in Logzeilen sind ohne Zeitstempel-nahen
|
||||
Karten-Snapshot nicht zuschreibbar.** Wer die Vormittagszeilen mit der jetzigen Karte liest, ordnet
|
||||
falsch zu. *(Strukturelle Antwort wäre ein stündlicher Karten-Snapshot ins Log — der Core ist
|
||||
**kein** `device-mode=home`, Scheduler ist dort erlaubt. Nicht gebaut, nur vorgeschlagen.)*
|
||||
|
||||
**3. Sticky-Verdacht, teilweise belegt.** Um 14:23 unbewegt am Schreibtisch **−72 dBm**, um 14:38 am
|
||||
selben Platz **−49 dBm**. Die Pegeldifferenz ist ein Faktum; **welcher** AP jeweils dahinterstand,
|
||||
ist wegen (2) nicht mehr rekonstruierbar. Über den Tag zeigt jedes Interface dieselbe Spannweite
|
||||
(−91…−47) — das Telefon hängt regelmäßig auf −85…−91, obwohl −47 möglich wäre.
|
||||
|
||||
**4. `docs/wifi-p750w-coverage-and-map.md` ist als Beleg unbrauchbar.** Die Datei ist vom
|
||||
**2026-07-02** — vor CAPsMAN-Cutover, vor ap2s Umzug nach oben, vor ap3. Ihre Aussage „Terrasse
|
||||
grenzwertig −76…−89 dBm" beschreibt ein Netz, das es nicht mehr gibt. Christophs Einschätzung
|
||||
(„seit ap2 nach oben hat die Terrasse faire Coverage") ist die jüngere Information. **In dieser
|
||||
Session hat die veraltete Zeile beinahe dazu geführt, den 13:16-Vorfall als „erwartbar" abzutun.**
|
||||
|
||||
**5. Erste ruhige Phase des Tages — unbewertet.** Zwischen dem Core-Reboot (14:37) und 15:12 steht
|
||||
**1** `reauthenticating` im Log, **keines vom iPhone**. 35 Minuten sind keine Aussage, und das
|
||||
iPhone lag zuletzt bei −49…−52 dBm. **Nicht als Erfolg verbuchen** — aber morgen früh gezielt
|
||||
prüfen, ob 7.24.1 auf dem Manager etwas verändert hat.
|
||||
|
||||
## Entscheidungslage für die nächste Session
|
||||
|
||||
Hebel 1 ist gescheitert. `sec-main` unterscheidet sich von den fünf ereignislosen SSIDs in **zwei**
|
||||
Attributen (bereits im Vorgänger korrigiert):
|
||||
|
||||
```
|
||||
sec-main authentication-types=wpa3-psk ft=yes ft-over-ds=no ← 93/93 Ereignisse
|
||||
sec-infra… authentication-types=wpa2-psk,wpa3-psk ft=no ← null Ereignisse
|
||||
```
|
||||
|
||||
| Option | Dafür | Dagegen |
|
||||
|---|---|---|
|
||||
| **Hebel 2 `ft=no`** | folgt der beschlossenen Reihenfolge, isoliert die FT-Achse sauber | bleibt WPA3-only; wenn das die Ursache ist, ändert sich nichts |
|
||||
| **`wpa2-psk,wpa3-psk`** | `no cached PMK` ist eine SAE/PMKSA-Meldung; iOS + WPA3-only + PMK-Caching ist ein bekanntes Problemfeld; bringt `main` exakt auf den Stand der ruhigen SSIDs | ändert das zweite Attribut, nicht das aus dem Plan |
|
||||
| **beides** | höchste Chance auf Ruhe | hinterher weiß niemand, welches gewirkt hat |
|
||||
|
||||
**Vor der Entscheidung zuerst prüfen:** ob 7.24.1 auf dem Manager das Verhalten schon verändert hat
|
||||
(Punkt 5). Ein Hebel, der auf ein bereits gelöstes Problem gezogen wird, verbrennt einen Messtag.
|
||||
|
||||
⚠️ Die Transaktion **`TP25-fund-e-ft-over-ds` bleibt offen** (Ablauf 2026-09-03), Compliance steht
|
||||
deshalb weiter absichtlich auf **134/135**. Rollback oder Commit ist eine bewusste Entscheidung,
|
||||
kein Aufräumen.
|
||||
|
||||
## Messrezept (unverändert gültig)
|
||||
|
||||
```bash
|
||||
ssh root@10.40.20.100 "pct exec 400 -- sh -c '
|
||||
grep -c reauthenticating /opt/tp5-syslog/log/10.40.20.1/2026-09-01.log;
|
||||
grep -c \" caps,\" /opt/tp5-syslog/log/10.40.20.1/2026-09-01.log'"
|
||||
```
|
||||
Erste Zahl = Fund A. Zweite Zahl = Reboots/Rejoins; steht sie über 0, **erst dort nachsehen**,
|
||||
bevor die erste Zahl gedeutet wird.
|
||||
|
||||
## Unverändert offen
|
||||
|
||||
1. TP25-Messrunde mit Rundgang (`bash docs/tp25-runde.sh`) — **Terrasse und Arbeitszimmer**, um die
|
||||
Sticky-Frage aus Punkt 3 zu entscheiden. `ap-map` dabei neu einfrieren.
|
||||
2. Passwort-Rotation TP30 (Admin-PW am 08-30 verbrannt; fehlende `MCP_MIKROMCP_*_PASS`).
|
||||
3. ap1-Umzug ans Sideboard (`core ether3`, `5260/Ce`, Frequenz-**Liste**, `tx-power` vorher messen).
|
||||
4. Karten-Snapshot ins Log automatisieren (Vorschlag aus Punkt 2, nicht gebaut).
|
||||
91
docs/handoff-20260831-wlan-fund-e.md
Normal file
91
docs/handoff-20260831-wlan-fund-e.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Handoff 2026-08-31 — TP25 Fund E: der Befund liegt vor, der Hebel ist zu ziehen
|
||||
|
||||
## Ausgangslage
|
||||
|
||||
ap3 ist live und stabil (15 h+ verbunden, Kabel `ether2`→`core ether22` ist gezogen,
|
||||
`ether22` = `no-link`). Compliance **135/135, 0 Drifts** über 5 Geräte. Alles committet und
|
||||
gepusht (`fd05286`, `1006f91`, `1754862`).
|
||||
|
||||
Am 2026-08-30 wurde WLAN-Logging persistent gemacht (`topics=wireless` + `topics=caps` vom Core
|
||||
in den TP5-Kollektor `10.40.20.18:514`, Tagesdateien unter
|
||||
`/opt/tp5-syslog/log/10.40.20.1/`). **Nach einer Nacht liegt der Befund vor.**
|
||||
|
||||
## 🔴 Der Befund
|
||||
|
||||
**559 `wireless`-Zeilen in ~16 h, davon 439 (79 %) von einem einzigen Gerät: Christophs iPhone
|
||||
`F2:62:4C:E1:AF:09`.**
|
||||
|
||||
Entscheidend ist aber nicht die Menge, sondern die **Trennschärfe**:
|
||||
|
||||
| Frage | Messung |
|
||||
|---|---|
|
||||
| Welche Clients erzeugen `reauthenticating`? | **93 von 93 = nur das iPhone.** Kein anderes Gerät im Netz. |
|
||||
| Auf welcher SSID? | **93 von 93 = nur `dirtyvader-main`.** |
|
||||
| Was unterscheidet `main` von den anderen fünf SSIDs? | **Genau ein Attribut: `ft=yes` + `ft-over-ds=yes`** (WPA3-PSK + 802.11r). `infra`/`iot`/`media`/`untrusted`/`guest` laufen mit `ft=no` → **null** Ereignisse. |
|
||||
|
||||
Das ist eine saubere Kontrollgruppe: **dieselben APs, dieselben Radios, derselbe Zeitraum,
|
||||
dieselben Clients — nur die SSID mit Fast Transition zeigt das Verhalten.**
|
||||
|
||||
**Verlauf des Schwalls am 2026-08-31 auf `cap-wifi6` (ap3, 2,4 GHz):**
|
||||
|
||||
```
|
||||
07:25 10 × 07:31 9 × 07:33 14 ×
|
||||
07:27 1 × 07:32 17 × 07:34 21 ×
|
||||
07:30 6 ×
|
||||
07:34:42 → roamed to cap-wifi2, signal strength -89
|
||||
```
|
||||
|
||||
Eskalierende Reauthentifizierung, teils mehrere pro Sekunde, endend mit der Flucht auf einen
|
||||
**25 dB schlechteren** AP. Genau so sieht „Link weg trotz gutem Kontakt, danach Mobilfunk" von
|
||||
der Infrastrukturseite aus.
|
||||
|
||||
Zusätzlich erfasst: zwei `disconnected, not responding` am 30.08. um 21:47 und 22:10 — aber bei
|
||||
**−80/−76 dBm**, also grenzwertigem Signal. ⚠️ **Die sind NICHT dasselbe** wie der Schwall und
|
||||
sollten nicht zusammengeworfen werden (die Ursprungsmessung vom 08-20 hatte −47 dBm).
|
||||
|
||||
## ⚠️ Korrektur an der Hebel-Reihenfolge vom 2026-08-30
|
||||
|
||||
Der Plan von gestern setzte **`2g-probe-delay=yes`** als Hebel 1, weil es der ungefährlichste ist.
|
||||
**Das war vor diesem Befund und ist jetzt falsch:** `2g-probe-delay` adressiert **Band-Steering**,
|
||||
hier liegt aber ein **Authentifizierungsproblem** vor. Neue Reihenfolge:
|
||||
|
||||
| # | Hebel | Begründung | Risiko |
|
||||
|---|---|---|---|
|
||||
| **1** | **`ft-over-ds=no`** auf `sec-main` | Nimmt genau die Änderung vom 2026-08-17 zurück (Standalone fuhr `ft-over-ds=no`). FT bleibt over-the-air via `ft=yes`. **Kleinster Eingriff, der die verdächtige Achse trifft.** | gering |
|
||||
| 2 | **`ft=no`** auf `sec-main` | Falls (1) nicht reicht: FT komplett aus. Kostet Roaming-Geschwindigkeit, nicht Roaming. | mittel |
|
||||
| 3 | `2g-probe-delay=yes` | Erst danach — adressiert die **Band-Oszillation**, ein anderes Symptom | sehr gering |
|
||||
| 4 | `signal-range`-Boden (Fund E im Original) | invasivster Hebel, **kann Clients aussperren**. Nur mit gemessenem Wert. | hoch |
|
||||
|
||||
**Vorgehen:** ein Hebel, dann 24 h messen, dann entscheiden. Jeder als Transaktion:
|
||||
`python3 nautobot/gc-transaktion.py begin --device crs326-core --scope wifi-security --change-id … --expires …`
|
||||
|
||||
🔴 **`wifi-security` ist NICHT deploybar** (TP22-Regel 1: maskierte Sektionen sind vom Push
|
||||
ausgeschlossen — die Passphrasen stehen im Template als `<<REDACTED>>`). Die Änderung muss also
|
||||
**am Gerät** erfolgen und danach per REST zurückgelesen werden, und das GC-Template ist
|
||||
anschließend von Hand nachzuziehen. Siehe Kommentar in `mikrotik_routeros.j2` [6b].
|
||||
|
||||
## Wie man die Wirkung misst
|
||||
|
||||
```bash
|
||||
# Basislinie und Kontrolle, beides aus dem Kollektor:
|
||||
ssh root@10.40.20.100 "pct exec 400 -- sh -c '
|
||||
cat /opt/tp5-syslog/log/10.40.20.1/2026-0*-*.log |
|
||||
grep reauthenticating | grep -oE \"([0-9A-F]{2}:){5}[0-9A-F]{2}\" | sort | uniq -c'"
|
||||
```
|
||||
**Erfolgskriterium:** `reauthenticating` für `F2:62:4C:E1:AF:09` geht auf ~0 zurück, **ohne** dass
|
||||
die anderen SSIDs neue Ereignisse zeigen. Die Zahl muss sich **bewegen** — bleibt sie gleich, hat
|
||||
der Hebel nicht gegriffen (dieselbe Merkregel wie bei den Compliance-Zahlen).
|
||||
|
||||
## Ebenfalls offen
|
||||
|
||||
1. **TP25-Messrunde** — `bash docs/tp25-runde.sh ap3-bringup`, dann `docs/tp25-walk-messung.sh`.
|
||||
Braucht einen Rundgang. Frage: deckt ap3 allein ab, was ap1 abgedeckt hat?
|
||||
2. **Passwort-Rotation (TP30)** — das gemeinsame Admin-PW ist am 2026-08-30 im Transkript
|
||||
verbrannt. ap3 trägt es mit. Zusätzlich fehlen in `~/.secrets/exports.zsh`:
|
||||
`MCP_MIKROMCP_ROUTER_AP3_PASS`, `MCP_MIKROMCP_CRS326_CORE_PASS`, `MCP_MIKROMCP_CRS326_BRANCH_PASS`.
|
||||
3. **MikroMCP-Neustart** — Registry (jetzt `bf-infra`, inkl. ap3) wird nur beim Start gelesen.
|
||||
4. **ap1-Umzug ans Sideboard** — Uplink auf `core ether3` (dort vorher die VLAN40-Altlast
|
||||
abräumen), Kanal `5260/Ce`. TP25-Auflagen: **Frequenz-LISTE** statt Einzelwert (Radar sonst
|
||||
SPOF) und **vorher `tx-power` messen** (Fund B: 18 dBm gesetzt, 9 gesendet).
|
||||
5. **Versions-Angleichung** — ap3 auf 7.24.1, die anderen vier auf 7.24 (eigener TP27-Durchgang,
|
||||
Core-Reboot = Standort-Ausfall).
|
||||
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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user