From 1578de50c3ce1132bc36bbac949946b29d94c43e Mon Sep 17 00:00:00 2001 From: Christoph Emsenhuber Date: Wed, 22 Jul 2026 19:46:24 +0200 Subject: [PATCH] TP15/TP16.1: kein RB5009, WG-Mesh auf CRS326; TP21: Golden-Config-Image im Repo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RB5009 final gestrichen (User-Entscheid 2026-07-22) — Router bleibt ap1/ap2, Referenzen in teilprojekte.md + hw-refresh-requirements.md bereinigt. - TP16.1 Ziel-Device von ap1 auf CRS326 Core-Switch retargeted (Doku-only, Scharfschalten bleibt gated bis TP21 den CRS326 abdeckt), Runbook umbenannt auf tp16.1-warp-mesh-native-crs326.md, cf-tunnel-mapping.md §14 + Handoff- Prompt mitgezogen. - TP21: docs/nas-vlan20/nautobot-image/ neu — der Dockerfile/nautobot_config.py/ allnet_sg8316m_driver.py, aus denen das laufende Custom-Image tatsächlich gebaut ist (der bisherige Verweis auf scratch/nautobot-gc-build existierte nirgends). Ergänzt napalm-ros + nornir-napalm + librouteros + gepinntes setuptools<81 (pkg_resources-Regression), Nornir-Credentials auf CredentialsNautobotSecrets umgestellt, Compliance/Intended-Config/SoT-Agg aktiviert. Backup/Intended/Compliance-Pipeline live gegen ap1 verifiziert. Co-Authored-By: Claude Sonnet 5 --- docs/cf-tunnel-mapping.md | 16 ++-- docs/hw-refresh-requirements.md | 2 +- docs/nas-vlan20/nautobot-image/Dockerfile | 28 ++++++ .../nautobot-image/allnet_sg8316m_driver.py | 89 +++++++++++++++++++ .../nautobot-image/nautobot_config.py | 67 ++++++++++++++ docs/teilprojekte.md | 29 +++--- docs/tp16.1-session-handoff-prompt.md | 7 +- ...1.md => tp16.1-warp-mesh-native-crs326.md} | 50 +++++++---- 8 files changed, 246 insertions(+), 42 deletions(-) create mode 100644 docs/nas-vlan20/nautobot-image/Dockerfile create mode 100644 docs/nas-vlan20/nautobot-image/allnet_sg8316m_driver.py create mode 100644 docs/nas-vlan20/nautobot-image/nautobot_config.py rename docs/{tp16.1-warp-mesh-native-ap1.md => tp16.1-warp-mesh-native-crs326.md} (77%) diff --git a/docs/cf-tunnel-mapping.md b/docs/cf-tunnel-mapping.md index 36beee5..5fd6c3f 100644 --- a/docs/cf-tunnel-mapping.md +++ b/docs/cf-tunnel-mapping.md @@ -323,24 +323,26 @@ Letzte in §9.2/§8 als „bleibt `.41`" geführte Origin-Klasse (`pve .41.100`, **Einordnung „WARP spinnt" beim User selbst:** die macmini-Connector-Flaps waren ein echter, messbarer Backend-Defekt (Befund 1) und plausibel (mit-)ursächlich für die Unzuverlässigkeit; der ICMP-Totalausfall (Befund 3) ist davon getrennt und strukturell. -**Nächster Schritt = Richtungswechsel, s. §14:** Private Access verlässt den cloudflared-Pfad und wandert auf einen **nativen Cloudflare-Mesh-Node (WireGuard) auf ap1**. Der cloudflared-Public-FQDN-Teil (3-Tunnel-HA) bleibt unberührt. (Ghost-Connector-Eintrag bei `bf-pve`, arm64, 1 Conn, `run_at` 2026-07-12, seither inaktiv — harmlos, Cleanup bei Gelegenheit.) +**Nächster Schritt = Richtungswechsel, s. §14:** Private Access verlässt den cloudflared-Pfad und wandert auf einen **nativen Cloudflare-Mesh-Node (WireGuard) auf dem CRS326 Core-Switch** (Retarget von ap1 auf CRS326, User-Entscheid 2026-07-22). Der cloudflared-Public-FQDN-Teil (3-Tunnel-HA) bleibt unberührt. (Ghost-Connector-Eintrag bei `bf-pve`, arm64, 1 Conn, `run_at` 2026-07-12, seither inaktiv — harmlos, Cleanup bei Gelegenheit.) --- -## 14. Richtungsentscheid 2026-07-16 — Private Access via native Cloudflare Mesh (WARP Connector) auf ap1 (TP16.1) +## 14. Richtungsentscheid 2026-07-16 — Private Access via native Cloudflare Mesh (WARP Connector) auf dem CRS326 Core-Switch (TP16.1) + +> ✅ **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):** - **Public FQDNs** (`*.emsenhuber.net`, MCP-Endpoints, HA-Companion, Access-Policies): bleiben auf dem **cloudflared 3-Tunnel-HA** (bf-nas/bf-pve/bf-mm). Unverändert. macmini-Connectoren = `http2` (Befund 1). -- **Private Access** (unterwegs → `10.40.0.0/16` per IP, inkl. ICMP): wechselt vom cloudflared-QUIC-Proxy auf einen **nativen WireGuard-Mesh-Node auf ap1**. +- **Private Access** (unterwegs → `10.40.0.0/16` per IP, inkl. ICMP): wechselt vom cloudflared-QUIC-Proxy auf einen **nativen WireGuard-Mesh-Node auf dem CRS326 Core-Switch**. -**Warum ap1-nativ statt cloudflared/LXC/Container:** Cloudflare Mesh spricht WireGuard, RouterOS kann natives WireGuard (der TP10-Hub *ist* einer) → Mesh-Node = WG-Peer zu einem CF-PoP, **kein Container, kein `/dev/net/tun`, kein LXC, keine neue HW**. Erfüllt „ap1 = einziger SPOF, keine Abhängigkeit zu anderen Rechnern", keine macvlan-Blindheit (ap1 routet alle VLANs nativ L3), ICMP/TCP/UDP nativ. RouterOS-Container-Weg ist tot (kein TUN-Passthrough auf JEDER Router-HW) → **hAP ax³ löst das nicht** und ist zudem Wi-Fi 6 (nicht 7); HW-Kauf vom Tunnel-Fix entkoppelt. +**Warum CRS326-nativ statt cloudflared/LXC/Container:** Cloudflare Mesh spricht WireGuard, RouterOS kann natives WireGuard (der TP10-Hub auf ap1 *ist* einer, Muster überträgt sich) → Mesh-Node = WG-Peer zu einem CF-PoP, **kein Container, kein `/dev/net/tun`, kein LXC, keine neue HW**. Der CRS326 ist der zentrale Kabel-Fabric-Knoten und sieht ohnehin alle VLANs; ap1 bleibt Public-Edge/WLAN-Anker, übernimmt aber nicht mehr die Mesh-Node-Rolle. RouterOS-Container-Weg bleibt tot (kein TUN-Passthrough auf JEDER Router/Switch-HW) — daher weiterhin natives WireGuard. -**Status: Konzept + Runbook fertig, Scharfschalten = eigene Session** (User-Entscheid: heute nur Konzept, da der TCP-Pfad funktioniert und nur ICMP-Komfort fehlt; die CF-Prerequisites sind account-weit und träfen die Live-WARP-Geräte). **Vollständiges Runbook + gemessener Account-Ist-Stand: `docs/tp16.1-warp-mesh-native-ap1.md`.** +**Status: Konzept + Runbook fertig, Scharfschalten = eigene Session, jetzt zusätzlich gated durch CRS326-Bring-up** (User-Entscheid: heute nur Konzept, da der TCP-Pfad funktioniert und nur ICMP-Komfort fehlt; die CF-Prerequisites sind account-weit und träfen die Live-WARP-Geräte). **Vollständiges Runbook + gemessener Account-Ist-Stand: `docs/tp16.1-warp-mesh-native-crs326.md`.** **Kernpunkte fürs Scharfschalten (Details im TP16.1-Doc):** - Plan-Probe zuerst: `POST /accounts/…/warp_connector` (via `CF_API_TOKEN`) — zeigt, ob Mesh im Free-ZT-Plan erlaubt ist; sonst Fallback LXC-auf-pve. - Account-weit (1× kurzer WARP-Reconnect): Unique-Device-IP AN (`use_zt_virtual_ip`), „allow CF-One-Traffic → devices", Device-Profile „Cloudflare Mesh" (WireGuard), Split-Tunnel-Exclude `100.64.0.0/10` → `/11`+`100.112.0.0/12`. -- WG-Config via `ghcr.io/animmouse/wgcf-connector ` (ephemer) → 4 native WG-Zeilen auf ap1 (IF + CF-PoP-Peer `bmXOC+…`/`162.159.193.x:2408` + `100.96.x/32` + Route `100.96.0.0/12`). +- WG-Config via `ghcr.io/animmouse/wgcf-connector ` (ephemer) → 4 native WG-Zeilen auf dem **CRS326** (IF + CF-PoP-Peer `bmXOC+…`/`162.159.193.x:2408` + `100.96.x/32` + Route `100.96.0.0/12`) — konkrete Interface-/IP-Zuordnung erst nach CRS326-Bring-up (TP15) final. - vnet-Route `5546dcb6…` von `bf-pve` auf den Mesh-Tunnel umhängen (Rollback = PATCH zurück; bf-pve bleibt Fallback). - Team-Domain gemessen: `emsenhuber.cloudflareaccess.com` → Node-Identität `warp_connector@emsenhuber.cloudflareaccess.com`. Noch kein `warp_connector`-Tunnel im Account. -- ⚠️ Governance „Config nur via Nautobot" (TP21): ap1-WG-Zeilen über GC oder als genehmigte Ausnahme. +- Governance „Config nur via Nautobot" (TP21): CRS326-WG-Zeilen regulär via Golden Config, sobald das Device dort adoptiert ist — die alte ap1-Ausnahme gilt hierfür **nicht**. diff --git a/docs/hw-refresh-requirements.md b/docs/hw-refresh-requirements.md index 38bd828..27a57b9 100644 --- a/docs/hw-refresh-requirements.md +++ b/docs/hw-refresh-requirements.md @@ -4,7 +4,7 @@ > **Ziel:** ALLNET-Core + 2 Branch-Switches ablösen, Energieeffizienz + zentrales Management + DC-USV-Konzept > **⚠️ ENTSCHEIDUNGEN 2026-07-14 (überschreiben Teile dieses Recherche-Docs):** -> Ecosystem-Commit **MikroTik** (Kabel+Routing) / **Omada nur WLAN**. **2× CRS326-24G-2S+RM bestellt** als Switches (RouterOS → **in-model** bei MikroMCP/Nautobot; ⚠️ **kein PoE** → EAPs via Injektor). WLAN → **Omada-EAP** (nicht hAP be³). Router → **RB5009** (mittelfristig). Die **A/B/C/D-Switch-Varianten unten sind damit Archiv**; DC-USV/Energie-Abschnitte bleiben gültig. **SSoT = TP15/TP20/TP20.1/TP21 in `teilprojekte.md`** + Memory `project_mikrotik_commit_nautobot_gc`. +> Ecosystem-Commit **MikroTik** (Kabel+Routing) / **Omada nur WLAN**. **2× CRS326-24G-2S+RM bestellt** als Switches (RouterOS → **in-model** bei MikroMCP/Nautobot; ⚠️ **kein PoE** → EAPs via Injektor). WLAN → **Omada-EAP** (nicht hAP be³). Router → **kein RB5009** (User-Entscheid 2026-07-22, überschreibt die ursprüngliche Absicht hier) — bleibt dauerhaft **ap1/ap2** (hAP ax²). Die **A/B/C/D-Switch-Varianten unten sind damit Archiv**; DC-USV/Energie-Abschnitte bleiben gültig. **SSoT = TP15/TP20/TP20.1/TP21 in `teilprojekte.md`** + Memory `project_mikrotik_commit_nautobot_gc`. --- diff --git a/docs/nas-vlan20/nautobot-image/Dockerfile b/docs/nas-vlan20/nautobot-image/Dockerfile new file mode 100644 index 0000000..54a1348 --- /dev/null +++ b/docs/nas-vlan20/nautobot-image/Dockerfile @@ -0,0 +1,28 @@ +# Nautobot + Golden Config + Nornir, extending the official image in place +# (not a satellite/side image). Reconstructed 2026-07-22 from the running +# container's actual `docker image history` after the original build context +# (referenced in git history as "scratch/nautobot-gc-build") turned out to +# never have been committed to this repo -- this file replaces that dangling +# reference as the real, versioned source of truth going forward. +# +# Rebuild: docker build -t bf-nautobot-golden-config: docs/nas-vlan20/nautobot-image/ +# then point docs/nas-vlan20/stacks/210-nautobot.yml's 3 `image:` lines at +# and redeploy the Portainer stack (id 203, endpoint 14). +# Rollback: point those 3 image lines back at ghcr.io/nautobot/nautobot:3.1.7 +# (drops the golden-config/nornir plugins; Nautobot core itself is unmodified). +FROM ghcr.io/nautobot/nautobot:3.1.7 + +USER root +RUN pip install --no-cache-dir \ + nautobot-golden-config \ + nautobot-plugin-nornir \ + nornir-netmiko \ + nornir-napalm \ + napalm-ros \ + librouteros \ + "setuptools<81" + +COPY --chown=nautobot:nautobot nautobot_config.py /opt/nautobot/nautobot_config.py +COPY --chown=nautobot:nautobot allnet_sg8316m_driver.py /opt/nautobot/allnet_sg8316m_driver.py + +USER nautobot diff --git a/docs/nas-vlan20/nautobot-image/allnet_sg8316m_driver.py b/docs/nas-vlan20/nautobot-image/allnet_sg8316m_driver.py new file mode 100644 index 0000000..0a08d68 --- /dev/null +++ b/docs/nas-vlan20/nautobot-image/allnet_sg8316m_driver.py @@ -0,0 +1,89 @@ +"""Custom Netmiko driver for the ALL-SG8316M (sw1) -- Telnet-only, IOS-like but +non-standard CLI (no `terminal length`, `--More--` paging, `end` from +config-vlan skips straight to the top level). No stock Netmiko/NAPALM driver +matches this device. + +NOT YET WIRED IN: this module is imported nowhere yet. The `claudecode` +Telnet account on sw1 is currently rejected ("Incorrect User Name!!", found +2026-07-16) so this driver is unverified against the real device. Once +working credentials exist, activate it from nautobot_config.py: + + import importlib + import allnet_sg8316m_driver # noqa: F401 (registers itself on import) + +and add to PLUGINS_CONFIG["nautobot_plugin_nornir"]["dispatcher_mapping"]: + + "allnet_sg8316m": "allnet_sg8316m_driver.GoldenConfigAllnetSg8316m" + +(dispatcher class still needs writing once the connection class below is +confirmed to log in cleanly -- see project_nautobot_allnet_cudy_scope_20260716 +memory for the full status and the two netmiko gotchas that cost the most +time: device_type must contain the literal substring "_telnet" for Netmiko to +pick the Telnet transport at all (BaseConnection.__init__ checks this by +string, not by class hierarchy), and `netmiko.ssh_dispatcher` at package level +is the dispatcher *function*, not the submodule -- reach CLASS_MAPPER via +`importlib.import_module("netmiko.ssh_dispatcher")`. +""" + +import importlib +import time + +from netmiko.cisco_base_connection import CiscoBaseConnection + +_nm_dispatch = importlib.import_module("netmiko.ssh_dispatcher") + + +class AllnetSg8316mTelnet(CiscoBaseConnection): + def session_preparation(self): + self._test_channel_read(pattern=r"[>#]") + self.set_base_prompt() + self.ansi_escape_codes = True + + def disable_paging(self, *args, **kwargs): + # No config knob for this on this firmware; paging is handled + # per-command in send_command_paged() below instead. + return "" + + def telnet_login( + self, + pri_prompt_terminator=r"#\s*$", + alt_prompt_terminator=r">\s*$", + username_pattern=r"Username", + pwd_pattern=r"Password", + delay_factor=1, + max_loops=20, + ): + return super().telnet_login( + pri_prompt_terminator=pri_prompt_terminator, + alt_prompt_terminator=alt_prompt_terminator, + username_pattern=username_pattern, + pwd_pattern=pwd_pattern, + delay_factor=delay_factor, + max_loops=max_loops, + ) + + def send_command_paged(self, command_string, max_pages=200, delay=0.3): + """sg8316m paginates with '--More--' and has no length-0 setting; + page through by sending a space each time it appears.""" + self.write_channel(command_string + self.RETURN) + time.sleep(delay) + output = "" + for _ in range(max_pages): + chunk = self.read_channel() + output += chunk + if "--More--" in chunk: + self.write_channel(" ") + time.sleep(delay) + continue + if any(p in chunk for p in ["sw1#", "sw1>"]) and "--More--" not in chunk: + break + if chunk == "": + time.sleep(delay) + return output.replace("--More--", "") + + +# Registered under the "_telnet" suffix required by Netmiko's own transport +# selection (see module docstring) -- registration is safe/inert on its own, +# nothing calls ConnectHandler(device_type="allnet_sg8316m_telnet") yet. +_nm_dispatch.CLASS_MAPPER["allnet_sg8316m_telnet"] = AllnetSg8316mTelnet +_nm_dispatch.platforms = list(_nm_dispatch.CLASS_MAPPER.keys()) diff --git a/docs/nas-vlan20/nautobot-image/nautobot_config.py b/docs/nas-vlan20/nautobot-image/nautobot_config.py new file mode 100644 index 0000000..6df8ddd --- /dev/null +++ b/docs/nas-vlan20/nautobot-image/nautobot_config.py @@ -0,0 +1,67 @@ +import os +import sys + +from nautobot.core.settings import * # noqa F401,F403 +from nautobot.core.settings_funcs import is_truthy, parse_redis_connection + +if DATABASES["default"]["ENGINE"].endswith("mysql"): + DATABASES["default"]["OPTIONS"] = {"charset": "utf8mb4"} + +SECRET_KEY = os.getenv("NAUTOBOT_SECRET_KEY", "05^)=zgn3ytglmp_iv4@era^e23u3#_wtop-@yeaeazempdy^=") + +INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRICS_ENABLED", "True")) + +# --- BF-Netzwerk additions: Golden Config + Nornir (TP21) --- +# +# Extends the stock config shipped in the base ghcr.io/nautobot/nautobot image +# (unchanged above this point) instead of replacing it, so a rollback is just +# "point the compose file's image tag back at ghcr.io/nautobot/nautobot:3.1.7". +PLUGINS = [ + "nautobot_plugin_nornir", + "nautobot_golden_config", +] + +PLUGINS_CONFIG = { + "nautobot_plugin_nornir": { + "nornir_settings": { + # Per-device creds via each Device's SecretsGroup (ap1/ap2 -> "RouterOS + # Nornir" group, access_type=Generic to match this class's default -- + # see get_device_creds()/_get_access_type_value() in nautobot_secrets.py). + # Switched 2026-07-22 from env_vars.CredentialsEnvVars (a single global + # NAPALM_USERNAME/PASSWORD pair for the whole fleet) so future devices + # (CRS326 etc.) can carry their own credentials. + "credentials": "nautobot_plugin_nornir.plugins.credentials.nautobot_secrets.CredentialsNautobotSecrets", + "runner": {"plugin": "threaded", "options": {"num_workers": 5}}, + }, + # nautobot-plugin-nornir 2.0+ dropped PLUGINS_CONFIG["dispatcher_mapping"] + # (it now errors on boot if present) -- per-platform dispatcher overrides + # moved onto the Platform model itself (network_driver_mappings). The + # ALLNET sg8316m custom driver will be wired in there once credentials + # are sorted, not here. + }, + "nautobot_golden_config": { + # Backup + Intended-Config + Compliance enabled 2026-07-22 (TP21 follow-up + # session) once a Jinja template + Git repo target existed. Plan/Deploy + # (device push) stay off on purpose -- this pipeline is pull/read-only + # for now, pushing config is a deliberately separate future step. + "enable_backup": True, + "enable_compliance": True, + "enable_intended": True, + "enable_sotagg": True, + "enable_plan": False, + "enable_deploy": False, + "enable_postprocessing": False, + "postprocessing_callables": [], + "postprocessing_subscribed": [], + "per_feature_bar": True, + "per_feature_width": 0.13, + "per_feature_height": 4, + "default_deploy_status": "Not Approved", + "get_custom_compliance": None, + "sot_agg_transposer": None, + }, +} + +NAPALM_USERNAME = os.getenv("NAUTOBOT_NAPALM_USERNAME", "") +NAPALM_PASSWORD = os.getenv("NAUTOBOT_NAPALM_PASSWORD", "") +NAPALM_TIMEOUT = int(os.getenv("NAUTOBOT_NAPALM_TIMEOUT", "30")) diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index 5aeab54..ee0294f 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -345,9 +345,9 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". - ✅ **CRS = RouterOS-fähig → in-model:** MikroMCP-Write + Nautobot Golden Config (TP21) managen auch die **Switches**, nicht nur den Router → config-as-code deckt den **ganzen Kabel-Fabric**. (SwOS-Boot bliebe als Fallback möglich, aber nicht genutzt.) - ⚠️ **kein PoE** (Sonoff/PoE-Verbraucher via Injektor, falls nötig). - **📶 WLAN bleibt hAP ax²/CAPsMAN** — kein Hardware-/Ecosystem-Wechsel. Coverage-Schwachstellen (P750W-Fall, Terrasse/Kanten) bleiben Platzierungs-/Roaming-Thema von **TP3.3**, nicht durch neue Hardware gelöst. -- **🧭 Router → RB5009 (mittelfristig):** L3/CAKE/Firewall vom hAP ax² lösen (device-mode=home blockt scheduler/fetch; „AP=Router"-Fragilität) → dedizierte RouterOS-Box, in MikroMCP + Nautobot. hAP ax² danach nur noch WLAN/Reserve. +- **🧭 Router-HW final (User-Entscheid 2026-07-22): kein RB5009.** Router bleibt dauerhaft **ap1/ap2** (hAP ax²). L3/CAKE/Firewall bleiben auf ap1; device-mode=home-Einschränkungen (kein scheduler/fetch) bleiben bekannter Kompromiss, kein HW-Wechsel geplant. - **🔋 DC-USV** (unverändert gültig): MeanWell LRS-150-48 + DDR-120-48 + LiFePO4 20Ah (~€190), 48V-Bus; CRS326 DC-input passt. -- **Offen:** RB5009-Beschaffung; Standort-Zuordnung der 2 CRS326 (Diele/OG) nach TP19-VLAN1-Retirement; ob/wann sw2 durch einen 3. CRS326 abgelöst wird. +- **Offen:** Standort-Zuordnung der 2 CRS326 (Diele/OG) nach TP19-VLAN1-Retirement; ob/wann sw2 durch einen 3. CRS326 abgelöst wird. - **Hinweis:** die A/B/C/D-Switch-Varianten in `hw-refresh-requirements.md` sind durch die CRS326-Beschaffung überholt (Doc = Recherche-Archiv + USV/Energie-Referenz). - Abh.: TP14 ✅ (IP-Migration). Verzahnt: **TP20** (Platform-DB), **TP21** (Nautobot GC), **TP2.1** (sw2-Standalone-Recovery). @@ -371,14 +371,15 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". - Abh.: TP14.1/14.2 ✅. Verwandt: **TP11** (CF-Tunnel-Track-B/C + Access), #1033. SSoT: `docs/cf-tunnel-mapping.md`. Memory `project_cf_tunnel_1033`. - ✅ **Incident 2026-07-16 (User unterwegs, WARP „spinnt", keine BF-IPs mehr) ▸ Public-FQDN-Teil gefixt:** macmini-Connectoren (`cloudflared-bfnas`/`-bfpve`) flappten live unter QUIC/UDP (Docker-Desktop-Bridge-NAT) → `bf-nas`/`bf-pve` von 2 auf 1 Connector degradiert (HA faktisch weg, nicht down). Fix: beide auf `TUNNEL_TRANSPORT_PROTOCOL=http2` umgestellt (rollend, 0 Downtime), wieder voll HA. Konvention: macmini-Connectoren künftig immer `http2`. **ICMP-Befund (getrennt, strukturell):** TCP über die WARP-Route ging überall, ICMP nicht (fm 36 %/bf 100 %/dw 100 % Loss) — cloudflared ist QUIC-Proxy, kein WireGuard. **Kurz als „bf-pve-Route wegen USV" notiert (Commit `1c1a676`) → REVIDIERT** (Begründung invertiert: bf-pve-Connectoren laufen auf NAS+macmini, nicht pve). Details: `docs/cf-tunnel-mapping.md §13`. **→ Richtungswechsel für Private Access = TP16.1.** -### TP16.1 — Private Access via native Cloudflare Mesh (WireGuard) auf ap1 ▸ 📋 Konzept+Runbook fertig (2026-07-16), **Recherche verifiziert + Runbook gehärtet (2026-07-17)**, Scharfschalten = eigene Session — `docs/tp16.1-warp-mesh-native-ap1.md` -- **Trennung:** Public FQDNs bleiben auf cloudflared-3-Tunnel-HA (TP16); **Private Access** (unterwegs → `10.40.0.0/16` per IP inkl. ICMP) wandert vom cloudflared-QUIC-Proxy auf einen **nativen WireGuard-Mesh-Node auf ap1**. -- **Warum ap1-nativ:** Cloudflare Mesh spricht WireGuard, RouterOS kann natives WireGuard (TP10-Hub *ist* einer) → Mesh-Node = WG-Peer zu CF-PoP, **kein Container/TUN/LXC/neue HW**. Erfüllt „ap1 = einziger SPOF", keine macvlan-Blindheit, ICMP nativ. RouterOS-Container-Weg tot (kein `/dev/net/tun`-Passthrough auf JEDER Router-HW) → **hAP ax³ löst das nicht** (zudem Wi-Fi 6, nicht 7) → HW-Kauf vom Tunnel-Fix entkoppelt (ggf. TP15). +### TP16.1 — Private Access via native Cloudflare Mesh (WireGuard) auf dem CRS326 Core-Switch ▸ 📋 Konzept+Runbook fertig (2026-07-16), **Recherche verifiziert + Runbook gehärtet (2026-07-17)**, **Ziel-Device retargeted auf CRS326 (User-Entscheid 2026-07-22)**, Scharfschalten = eigene Session, gated bis TP21 den CRS326 abdeckt — `docs/tp16.1-warp-mesh-native-crs326.md` +- ✅ **Update (User-Entscheid 2026-07-22):** Ziel-Device für den WG-Mesh-Node ist jetzt der **CRS326 Core-Switch statt ap1** — konsistent mit dem TP15-Endstand (kein RB5009, Router bleibt ap1/ap2 rein für L3/WLAN) und TP21s "ganzer Kabel-Fabric via RouterOS"-Modell (CRS326 ist ohnehin RouterOS-fähig und wird Nautobot-verwaltet). **Reine Ziel-Doku-Änderung** — das Scharfschalten bleibt weiterhin eine eigene, spätere Session und bleibt gated, bis TP21 den CRS326 als Device abdeckt. **Keine neue Governance-Ausnahme:** die bestehende ap1-Ausnahme (s. Ist-Stand-Zeile 31) gilt explizit **nicht** automatisch für den CRS326 — CRS326-Konfiguration soll regulär über Nautobot GC laufen, sobald TP21 so weit ist. Die CRS326 selbst sind aktuell noch Werkszustand (physisch bereits mit dem aktuellen Core verkabelt, aber die betreffende Uplink-Port bislang ungenutzt/down) — konkrete Management-IP/Interface-Zuordnung für den CRS326 als L3/WG-Endpoint ist noch **nicht** getroffen (TBD nach TP15-Bring-up). +- **Trennung:** Public FQDNs bleiben auf cloudflared-3-Tunnel-HA (TP16); **Private Access** (unterwegs → `10.40.0.0/16` per IP inkl. ICMP) wandert vom cloudflared-QUIC-Proxy auf einen **nativen WireGuard-Mesh-Node auf dem CRS326 Core-Switch**. +- **Warum CRS326-nativ:** Cloudflare Mesh spricht WireGuard, RouterOS kann natives WireGuard (TP10-Hub auf ap1 *ist* einer, Muster überträgt sich) → Mesh-Node = WG-Peer zu CF-PoP, **kein Container/TUN/LXC/neue HW**. Verlagert die Rolle vom Router (ap1, der weiterhin Public-Edge + WLAN-Anker bleibt) auf den Core-Switch, der als zentraler Kabel-Fabric-Knoten ohnehin alle VLANs sieht. RouterOS-Container-Weg bleibt tot (kein `/dev/net/tun`-Passthrough auf JEDER Router/Switch-HW) — daher weiterhin natives WireGuard, kein Container-Ansatz. - **Verworfen:** WG-Roadwarrior (User will keine Extra-App/Profil je Gerät), alle Helper-Host-ZT-Anbieter (SPOF-Verletzung). -- **Warum heute nur Konzept:** TCP-Pfad funktioniert (nur ICMP-Komfort fehlt), und die CF-Prerequisites sind **account-weit** (Unique-Device-IP, Split-Tunnel-Exclude, Device-Profile) → treffen Live-WARP-Geräte (1× kurzer Reconnect) → nicht unter Zeitdruck. -- **Nächste Session:** Plan-Probe `POST warp_connector` (Free-Plan-Gate; sonst LXC-Fallback) → account-weite Prereqs → `wgcf-connector`-Token→WG-Config → 4 WG-Zeilen auf ap1 → Subnetz-Route + vnet-Route `5546dcb6…` von bf-pve umhängen (Rollback trivial) → Verifikation (Ping verlustfrei). Team-Domain `emsenhuber.cloudflareaccess.com`. ⚠️ Governance „Config nur via Nautobot" → ap1-Zeilen via GC oder genehmigte Ausnahme. -- ✅ **Recherche-Härtung 2026-07-17 (Primärquellen animmouse + offizielle CF-Docs + OpenAPI-Spec, alles verifiziert):** (1) Produkt heißt seit 2026-04-14 offiziell **Cloudflare Mesh** (API-Pfade bleiben `warp_connector`, im Spec bestätigt inkl. Token- und sogar HA-Endpoints); (2) ICMP-Proxy ist **bereits AN** (User-Korrektur: fm-Ping `10.101.0.0/24` beweist es — kein To-Do; mein „fehlt" war ein Fehlschluss aus dem API-Spec, das Flag ist Dashboard-only); (3) Split-Tunnel-Exclude auf **beiden** Device-Profilen (Default + Mesh); (4) **vnet-Gotcha** beim Route-Umzug („virtual networks only for cloudflared") → Weg A PATCH, Weg B DELETE+POST dokumentiert; (5) **v4-only-Entscheid** (Mesh-IPv6-site-to-site laut Guide broken, NAT66-Gefrickel nicht nötig); (6) keepalive 1m statt 25s ok. Alles in `docs/tp16.1-warp-mesh-native-ap1.md` §2/§4 eingearbeitet — **Runbook ist jetzt ausführungsreif für die Delegations-Session.** -- Abh.: TP16 ✅ (Public-Teil), TP10 ✅ (WG-Grundmuster auf ap1). SSoT: `docs/tp16.1-warp-mesh-native-ap1.md`, `docs/cf-tunnel-mapping.md §14`. +- **Warum heute nur Konzept:** TCP-Pfad funktioniert (nur ICMP-Komfort fehlt), und die CF-Prerequisites sind **account-weit** (Unique-Device-IP, Split-Tunnel-Exclude, Device-Profile) → treffen Live-WARP-Geräte (1× kurzer Reconnect) → nicht unter Zeitdruck. Zusätzlich jetzt gated durch den Retarget: CRS326-Bring-up (Management-IP, VLAN-Filtering) muss erst stehen. +- **Nächste Session (nach CRS326-Bring-up):** Plan-Probe `POST warp_connector` (Free-Plan-Gate; sonst LXC-Fallback) → account-weite Prereqs → `wgcf-connector`-Token→WG-Config → 4 WG-Zeilen auf dem CRS326 → Subnetz-Route + vnet-Route `5546dcb6…` von bf-pve umhängen (Rollback trivial) → Verifikation (Ping verlustfrei). Team-Domain `emsenhuber.cloudflareaccess.com`. Governance „Config nur via Nautobot" → CRS326-Zeilen regulär via TP21/GC, sobald das Device dort adoptiert ist. +- ✅ **Recherche-Härtung 2026-07-17 (Primärquellen animmouse + offizielle CF-Docs + OpenAPI-Spec, alles verifiziert, gilt unabhängig vom Zielgerät):** (1) Produkt heißt seit 2026-04-14 offiziell **Cloudflare Mesh** (API-Pfade bleiben `warp_connector`, im Spec bestätigt inkl. Token- und sogar HA-Endpoints); (2) ICMP-Proxy ist **bereits AN** (User-Korrektur: fm-Ping `10.101.0.0/24` beweist es — kein To-Do; mein „fehlt" war ein Fehlschluss aus dem API-Spec, das Flag ist Dashboard-only); (3) Split-Tunnel-Exclude auf **beiden** Device-Profilen (Default + Mesh); (4) **vnet-Gotcha** beim Route-Umzug („virtual networks only for cloudflared") → Weg A PATCH, Weg B DELETE+POST dokumentiert; (5) **v4-only-Entscheid** (Mesh-IPv6-site-to-site laut Guide broken, NAT66-Gefrickel nicht nötig); (6) keepalive 1m statt 25s ok. Alles in `docs/tp16.1-warp-mesh-native-crs326.md` §2/§4 eingearbeitet (Config-Block dort als Platzhalter markiert, IP/Interface TBD). +- Abh.: TP16 ✅ (Public-Teil), TP10 ✅ (WG-Grundmuster, jetzt als Vorbild statt Direktziel), **TP15** (CRS326-Bring-up), **TP21** (Nautobot-Adoption des CRS326, Voraussetzung fürs Scharfschalten). SSoT: `docs/tp16.1-warp-mesh-native-crs326.md`, `docs/cf-tunnel-mapping.md §14`. ### TP17 — Shelly-Übersiedelung VLAN1 → VLAN30 (IOT) + `shelly-mcp` ▸ ✅ WLAN+IP DURCH (22/26, 2026-07-13); Geräte-PW + cudy-Teardown offen — `mcp/shelly/`, Runbook `docs/tp17-shelly-go-runbook.md` - ✅ **GO durchgezogen 2026-07-13 (16 Shellys VLAN1→VLAN30, 0 Fehler):** Pilot s26 + Welle A (s4–s9) + Welle B (s10/11/13/15/17/19/20/21/25) → alle auf `dirtyvader-iot`/`10.40.30.` verifiziert (SSID+IP+rssi). Mit den 6 Vorab-Migrierten (s14/16/18/22/23/24) = **22/26 auf VLAN30**; VLAN1-Sweep `.180-250` = **0 Shellys**. Offen nur 4 saisonal ausgesteckte (s1/s2/s3/s12 → beim Einstecken). @@ -485,17 +486,17 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". - **Verwandt/Abgrenzung:** vw ist auch in **TP16** offen (CF-Access: `bypass`→WARP-geschützt) — **DB-HA ≠ Access**, getrennt behandeln. Reziprokes 2-Site-Muster analog **TP16**/**TP18**. - Abh.: **TP20** (Tier-1 Postgres muss stehen), **TP10** (WG-Transport für Phase-2), **TP18** (Backup-Schirm). Kein Blocker für TP21. -### TP21 — Nautobot Golden Config (config-as-code Control-Plane) ▸ ⏳ **Plattform live (2026-07-16)**, Golden-Config-App/Device-Adoption offen — Memory `project_mikrotik_commit_nautobot_gc` +### TP21 — Nautobot Golden Config (config-as-code Control-Plane) ▸ ⏳ **Plattform + Golden-Config-App live** (App-Install nachträglich verifiziert 2026-07-22, Doku war stale), **Datenmodell/Git-Backend/Device-Adoption noch offen** — Memory `project_mikrotik_commit_nautobot_gc` - **Ziel:** modellierter Control-Plane über den MikroTik-**RouterOS**-Kern: GUI-SoT + **Config-Compliance/Drift** + intended-config + Push. **Ergänzt** MikroMCP (interaktiv/Debug), **ersetzt es nicht** (deklarativ/DR/Compliance). Aus User-Recherche 2026-07-14: MikroTik in Golden Config **erstklassig** (`mikrotik_routeros` + `_api`, Nornir/NAPALM, backup+deploy). -- **Scope-Grenze:** RouterOS in-model = **Router (ap1 heute / RB5009 künftig) + beide CRS326-Switches** (RouterOS-Boot) → Golden Config deckt den **ganzen Kabel-Fabric**. Außerhalb bleibt nur **Omada-WLAN** (eigener Controller, spielt aber laut TP15-Korrektur ohnehin keine Rolle mehr). +- **Scope-Grenze:** RouterOS in-model = **Router (ap1/ap2, dauerhaft — kein RB5009) + beide CRS326-Switches** (RouterOS-Boot) → Golden Config deckt den **ganzen Kabel-Fabric**. Außerhalb bleibt nur **Omada-WLAN** (eigener Controller, spielt aber laut TP15-Korrektur ohnehin keine Rolle mehr). - 🔒 **Wird zum alleinigen Config-Weg für Netzgeräte (Governance-Entscheid 2026-07-16, s. oben):** ab hier keine ad-hoc MikroMCP-Writes/Switch-UI-Klicks mehr auf Dauer — Nautobot managed den Fleet. - ✅ **Nautobot-Stack live (2026-07-16), auf NAS statt Mac mini** (Ressourcen-Check hatte Mac mini vorgeschlagen, dann auf NAS umentschieden — mehr Headroom + Gitea-Co-Location, s. TP20-Log): Portainer-Stack `nautobot` (Id 203, ep14), 4 Container — `nautobot` (App/API, `10.40.20.30:8080`), `nautobot-worker` (Celery), `nautobot-scheduler` (Celery Beat), `nautobot-redis`. Bild `ghcr.io/nautobot/nautobot:3.1.7` (offizielles Image direkt, **nicht** das `nautobot-docker-compose`-Repo — das ist ein `invoke`/Poetry-getriebenes Dev-Tooling-Repo ohne eigenständige `docker-compose.yml`, für einen Portainer-String-Stack ungeeignet; bewusste Abweichung, dokumentiert statt stillschweigend). DB = Platform-Postgres (`10.40.20.20`, TP20). Compose-Datei `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored, wie alle NAS-Stack-Files). - 🐛 **Gotcha beim ersten Deploy:** alle 3 Nautobot-Container liefen initial gleichzeitig `migrate` (Standard-Entrypoint-Verhalten) → Race-Condition, `IntegrityError` auf `pg_type`. Fix: `nautobot`-Service kriegt einen `healthcheck` (`curl .../health/`), `nautobot-worker`/`nautobot-scheduler` starten erst bei `depends_on: nautobot: condition: service_healthy` — serialisiert die Migration sauber auf einen Container. DB dafür einmal `DROP`+`CREATE` (sauberer Neustart, kein Datenverlust — war eh leer). - ✅ **End-to-End verifiziert:** `/api/status/` mit Token 200, Nautobot-Version 3.1.7, alle 4 Container laufen. Superuser `admin` angelegt, Creds im Stack-File (gitignored) + `postgres/.secrets` (DB-Seite). - ⚠️ **Bekannt offen, nicht blockierend:** kein HTTPS/Reverse-Proxy vor Nautobot (Django-Security-Warnings beim Start, erwartet für internen HTTP-only-Betrieb auf VLAN20 — analog anderen internen Diensten); Celery-Worker-Registrierung beim allerersten Start nicht sofort sichtbar (`celery-workers-running:0` initial), unkritisch, braucht kurz zum Einpendeln. - **PoC-Pfad (angepasst an die Montag-Deadline):** ~~Nautobot-Stack hoch~~ ✅ → **ap1 + ap2 in einem Rutsch adoptieren** (ap2 bekommt dabei gleich seinen VLAN99-Mgmt-Umzug aus TP19.1, s.o. — nicht isoliert vorher) → sobald CRS326 verkabelt sind, **direkt als Nautobot-verwaltete Geräte adoptieren statt erst manuell konfigurieren** → Compliance/Drift + Templates/intended für VLAN-/Firewall-Standards danach. -- **Offen:** Golden-Config-App noch nicht installiert/konfiguriert (nur Nautobot-Core läuft bisher); Git-Backend-Anbindung an Gitea; ap1-Adoption via RouterOS-API; ob OpenWrt je in-model muss (custom Nornir-Dispatcher — nur relevant falls Router doch OpenWrt+cake-autorate statt RB5009). -- Abh.: **TP20** (Postgres muss stehen), Gitea ✅, RouterOS-Router (ap1 heute / RB5009 TP15). +- **Offen:** Git-Backend-Anbindung an Gitea; ap1/ap2-Adoption via RouterOS-API; ob OpenWrt je in-model muss (custom Nornir-Dispatcher — nur relevant falls der Router-Pfad je auf OpenWrt+cake-autorate wechselt, aktuell nicht geplant). +- Abh.: **TP20** (Postgres muss stehen), Gitea ✅, RouterOS-Router (ap1/ap2, dauerhaft). ### TP-R — Router-Capabilities-Sweep ▸ FERTIG (`docs/research/routeros-capabilities.md`) - **Leitsatz: nativ vor Container, NAS vor Router** (128MB-Flash-Limit). @@ -508,7 +509,7 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". --- ## Reihenfolge / Abhängigkeiten -> 🎯 **AKTUELLER KRITISCHER PFAD (Stand 2026-07-16, überschreibt die Reihenfolge unten): TP20 (Platform-Postgres) → TP21 (Nautobot) — Ziel: fertig vor CRS326-Produktivsetzung, spätestens Montag 2026-07-20.** TP18 (Garage-S3) und die Komodo-Abhängigkeit wurden am selben Tag als Blocker entfernt/entkoppelt (s. TP20), um diese Deadline zu halten — beide werden später nachgezogen, nicht mehr vorher abgewartet. Danach: TP21 adoptiert ap1+ap2 (inkl. TP19.1-Rest) und die neu gelieferten CRS326-Switches direkt, dann erst TP5/TP6. Grund: Governance-Entscheid „Config exklusiv über Nautobot" (s. oben) macht Nautobot zur Voraussetzung für praktisch jede weitere Router-/Switch-Änderung. Die Punkte 3-4 unten (Omada-PVID-Fix etc.) sind **historisch/überholt** (Omada spielt seit TP15-Korrektur keine Rolle mehr) — ganze Liste braucht mal eine Aufräum-Session, hier nur der aktuelle Fokus vorangestellt. +> 🎯 **AKTUELLER KRITISCHER PFAD (Stand 2026-07-16, überschreibt die Reihenfolge unten): TP20 (Platform-Postgres) → TP21 (Nautobot) — Ziel: fertig vor CRS326-Produktivsetzung, spätestens Montag 2026-07-20.** TP18 (Garage-S3) und die Komodo-Abhängigkeit wurden am selben Tag als Blocker entfernt/entkoppelt (s. TP20), um diese Deadline zu halten — beide werden später nachgezogen, nicht mehr vorher abgewartet. Danach: TP21 adoptiert ap1+ap2 (inkl. TP19.1-Rest) und die neu gelieferten CRS326-Switches direkt, dann erst TP5/TP6. Grund: Governance-Entscheid „Config exklusiv über Nautobot" (s. oben) macht Nautobot zur Voraussetzung für praktisch jede weitere Router-/Switch-Änderung. Die Punkte 3-4 unten (Omada-PVID-Fix etc.) sind **obsolet** (User-Entscheid 2026-07-22 — Omada spielt seit TP15-Korrektur keine Rolle mehr, nie wieder aufgreifen) — ganze Liste braucht mal eine Aufräum-Session, hier nur der aktuelle Fokus vorangestellt. > ✅ **TP16 (CF-Tunnel Round-Robin/macvlan-Host-Isolation → reziprokes 3-Tunnel-HA)** KERN UMGESETZT 2026-07-10 (#1033 strukturell weg). Offen nur Access-Strang (WARP/`vw`) = user-gated. As-Built `docs/cf-tunnel-mapping.md §10`. 1. ~~**TP1 (GE8) → TP2 (Omada Controller).**~~ ✅ erledigt 2026-06-15. 2. ~~**TP4 (Router-Cutover L3-Infra + WAN-Edge).**~~ ✅ erledigt 2026-06-15 (L3) + 2026-07-01 (Edge-Cutover, FB physisch weg). diff --git a/docs/tp16.1-session-handoff-prompt.md b/docs/tp16.1-session-handoff-prompt.md index 5a4260f..26917fe 100644 --- a/docs/tp16.1-session-handoff-prompt.md +++ b/docs/tp16.1-session-handoff-prompt.md @@ -1,7 +1,12 @@ # TP16.1 — Handoff-Prompt für die Delegations-Session (Sonnet) +> ⚠️ **Veraltet seit 2026-07-22 — Ziel-Device jetzt CRS326 Core-Switch statt ap1** (s. TP16.1 in `teilprojekte.md` +> und `docs/tp16.1-warp-mesh-native-crs326.md`). Dieser Prompt richtet sich noch komplett an ap1 (Text + literale +> RouterOS-Befehle) und ist zusätzlich gated, bis der CRS326-Bring-up (TP15) + die Nautobot-Adoption (TP21) stehen. +> **Vor Nutzung überarbeiten** — nicht ungeprüft an eine neue Session weitergeben. + > **Zweck:** Dieses File ist der kopierfertige Auftrag für eine frische Session, die TP16.1 -> (Private Access via native Cloudflare Mesh/WireGuard auf ap1) scharfschaltet. +> (Private Access via native Cloudflare Mesh/WireGuard, ursprünglich auf ap1 geplant) scharfschaltet. > **Empfohlenes Modell:** Sonnet (Christoph zuhause = physischer ap1-Zugriff, alles reversibel, > Runbook ausführungsreif). Bei Bedarf Opus, falls die account-weiten Prereqs/eine Überraschungs- > Diagnose mehr Urteilsvermögen brauchen. diff --git a/docs/tp16.1-warp-mesh-native-ap1.md b/docs/tp16.1-warp-mesh-native-crs326.md similarity index 77% rename from docs/tp16.1-warp-mesh-native-ap1.md rename to docs/tp16.1-warp-mesh-native-crs326.md index 7bfd950..e8b9332 100644 --- a/docs/tp16.1-warp-mesh-native-ap1.md +++ b/docs/tp16.1-warp-mesh-native-crs326.md @@ -1,9 +1,10 @@ -# TP16.1 — Private Access via native Cloudflare Mesh (WARP Connector) auf ap1 +# TP16.1 — Private Access via native Cloudflare Mesh (WARP Connector) auf dem CRS326 Core-Switch -> **Status: Konzept + Runbook fertig (2026-07-16), Recherche verifiziert + Runbook gehärtet (2026-07-17), Scharfschalten = eigene Session.** -> Selbst-tragend: eine frische Session kann das mit diesem Doc + `docs/cf-tunnel-mapping.md` straight bauen. +> **Status: Konzept + Runbook fertig (2026-07-16), Recherche verifiziert + Runbook gehärtet (2026-07-17), Ziel-Device retargeted von ap1 auf CRS326 (User-Entscheid 2026-07-22), Scharfschalten = eigene Session, gated bis TP21 den CRS326 abdeckt.** +> ⚠️ **Retarget-Hinweis (2026-07-22):** Alles unten war ursprünglich für **ap1** geschrieben und ist jetzt auf den **CRS326 Core-Switch** ummünzt. Der CRS326 ist aktuell noch Werkszustand — die konkrete Management-IP/Interface-Zuordnung für den WG-Mesh-Node ist **noch nicht getroffen** (TBD nach TP15-Bring-up). §4.3 (Config-Befehle) ist deshalb ein **Platzhalter**, keine ausführungsreifen Werte. Grund für den Retarget: TP15-Endstand (kein RB5009, Router bleibt ap1/ap2 rein für L3/WLAN) + TP21s Modell "ganzer Kabel-Fabric via RouterOS" — der CRS326 wird ohnehin Nautobot-verwaltet, ap1 bleibt Public-Edge/WLAN-Anker. +> Selbst-tragend: eine frische Session kann das mit diesem Doc + `docs/cf-tunnel-mapping.md` straight bauen — vorausgesetzt der CRS326-Bring-up (TP15) und die Nautobot-Adoption (TP21) stehen. > SSoT-Kontext: `docs/cf-tunnel-mapping.md` §13/§14, Memory `project_cf_tunnel_1033`. -> Härtungs-Delta 2026-07-17: Split-Tunnel auf BEIDEN Profilen (§4.1.4), vnet-Gotcha + Weg B beim Route-Umzug (§4.4), +> Härtungs-Delta 2026-07-17 (gilt unabhängig vom Zielgerät): Split-Tunnel auf BEIDEN Profilen (§4.1.4), vnet-Gotcha + Weg B beim Route-Umzug (§4.4), > v4-only-Entscheid (IPv6-site-to-site laut Guide broken), Quellen verifiziert (§2). **Korrektur:** ICMP-Proxy ist bereits AN > (fm-Ping `10.101.0.0/24` beweist es) — kein To-Do, s. §4.1.5. @@ -28,13 +29,13 @@ zuverlässig eingerichtet. **Der WARP-Client selbst spricht WireGuard** — die - **Alle ZT-Anbieter mit Helper-Host** (CF WARP Connector als Daemon-Host, Tailscale, NetBird, Twingate): brauchen dauerhaft einen Linux-Host → verletzt „Router = einziger SPOF, keine Abhängigkeit zu anderen Rechnern". - **Connector als RouterOS-Container:** ❌ nicht möglich — RouterOS-7-Container haben **kein `/dev/net/tun`- - Passthrough**; der WARP-Connector-Daemon braucht ein TUN-Device. Gilt auf **jeder** Router-HW (hAP ax²/ax³/CRS/RB5009). + Passthrough**; der WARP-Connector-Daemon braucht ein TUN-Device. Gilt auf **jeder** Router-/Switch-HW (hAP ax²/ax³/CRS326/RB5009 — RB5009 mittlerweile ohnehin nicht mehr geplant, s. TP15). → **hAP ax³ löst das NICHT** (und ist zudem Wi-Fi 6, nicht 7 — kein WLAN-Gewinn ggü. ax²). HW-Kauf ist vom - Tunnel-Fix **entkoppelt** (separat unter TP15 zu bewerten, falls 2,5G/USB/CPU gewünscht). -- **✅ Gewählt: Cloudflare Mesh als NATIVES WireGuard-Interface auf ap1.** Cloudflare Mesh spricht WireGuard, - RouterOS kann natives WireGuard (der TP10-Hub *ist* schon einer). Ein Mesh-Node wird als WG-Peer zu einem - CF-PoP registriert — **kein Container, kein TUN, kein LXC, keine neue HW.** Erfüllt „ap1 = einziger SPOF" - am besten, keine macvlan-Blindheit (ap1 routet alle VLANs nativ L3), ICMP/TCP/UDP nativ. + Tunnel-Fix **entkoppelt**. +- **✅ Gewählt: Cloudflare Mesh als NATIVES WireGuard-Interface auf dem CRS326 Core-Switch** (Retarget 2026-07-22, ursprünglich ap1). Cloudflare Mesh spricht WireGuard, + RouterOS kann natives WireGuard (der TP10-Hub auf ap1 *ist* schon einer, Muster überträgt sich). Ein Mesh-Node wird als WG-Peer zu einem + CF-PoP registriert — **kein Container, kein TUN, kein LXC, keine neue HW.** Der CRS326 ist der zentrale Kabel-Fabric-Knoten + und sieht ohnehin alle VLANs; ap1 bleibt Public-Edge/WLAN-Anker, übernimmt aber nicht mehr die Mesh-Node-Rolle. ICMP/TCP/UDP nativ. Quelle/Vorlage: animmouse „Setup Cloudflare Mesh on MikroTik" + „Setup Cloudflare Mesh using WireGuard". Ehrliche Einschränkung: **von uns noch nicht gebaut** — starker, technisch schlüssiger Lead; echter Beweis = bauen+pingen. @@ -68,8 +69,11 @@ Ehrliche Einschränkung: **von uns noch nicht gebaut** — starker, technisch sc `10.40.0.0/16` schon heute über WARP (= warum TCP funktioniert). - vnet-Route `10.40.0.0/16` (vnet `1480b545…`, Route-ID **`5546dcb6-5901-4da6-8d91-b17f94703f71`**) zeigt aktuell auf **cfd_tunnel `bf-pve`** (`f7fdf3a6…`). Das bleibt der **Fallback**, bis Mesh bewiesen ist — nichts vorher löschen. -- ap1-WireGuard IST-Stand: 1 Interface `wg-hub` (listen 51821, MTU 1412), Peers `fm` (10.101.0.0/24) + `dw` (10.95.10.0/24). - Das neue Mesh-Interface ist **separat** (outbound zum CF-PoP, kein Listen-Port) → keine Kollision. +- ap1-WireGuard IST-Stand (bleibt unverändert, unabhängig vom Retarget): 1 Interface `wg-hub` (listen 51821, MTU 1412), + Peers `fm` (10.101.0.0/24) + `dw` (10.95.10.0/24) — das ist TP10, nicht Teil dieses TPs. +- **CRS326 IST-Stand (Retarget-Ziel):** Werkszustand, noch keine WireGuard-Config, keine Management-IP zugewiesen — + das neue Mesh-Interface (outbound zum CF-PoP, kein Listen-Port) entsteht dort auf einem sauberen Blatt, sobald + der CRS326-Bring-up (TP15: Management-IP, VLAN-Filtering) steht. ## 4. Runbook (nächste Session — Reihenfolge) @@ -121,7 +125,14 @@ ignorieren, wir bauen v4-only), **DNS** (CF-Resolver — ignorieren, ap1 hat eig Registriert den Node via CF-API (macht Netz-Call), läuft danach nie wieder. **PrivateKey nach `mcp/cloudflare/.env` o. `~/.secrets`** (nicht committen). -### 4.3 ap1 nativ konfigurieren (MikroMCP: `plan_changes` dryRun → `apply_plan`) +### 4.3 CRS326 nativ konfigurieren ⚠️ PLATZHALTER — noch NICHT ausführungsreif + +> Dieser Block war ursprünglich für ap1 geschrieben (per MikroMCP `plan_changes` dryRun → `apply_plan`). Nach dem +> Retarget auf den CRS326 (2026-07-22) fehlen noch: die Management-IP/Interface-Zuordnung des CRS326 (TP15-Bring-up), +> und der Zugriffsweg für Config-Changes ist dann **Nautobot Golden Config (TP21)**, nicht mehr MikroMCP direkt (die +> ap1-Ausnahme gilt für den CRS326 nicht). Die folgenden Zeilen zeigen nur das **Muster** (identisch zur RouterOS-Syntax), +> `` und die konkreten IP-Werte müssen nach dem Bring-up final werden: + ``` /interface wireguard add name=cf-mesh mtu=1420 private-key="" /interface wireguard peers add interface=cf-mesh name=cf-pop \ @@ -132,12 +143,13 @@ o. `~/.secrets`** (nicht committen). /ip route add dst-address=100.96.0.0/12 gateway=cf-mesh ``` - Endpoint: falls die Config `162.159.192.x` liefert → `162.159.193.x` nehmen (Latenz-Tuning laut Guide). -- MTU 1420 aus dem Guide; gegen unsere Hub-MTU 1412 gegenprüfen (ggf. angleichen bei Path-MTU-Problemen). -- **Kein** Extra-Static-Route für den Rückweg nötig (anders als der LXC-Plan): ap1 IST der L3-Router aller VLANs. -- Firewall: forward ist aktuell permissiv (TP5-Deny offen) → kein neues Loch nötig; falls doch ein Drop greift, - gezielte Accept `100.96.0.0/12 ↔ 10.40.0.0/16` dokumentiert ergänzen. -- ⚠️ **Governance:** „Config nur via Nautobot" (TP21) → diese ap1-Zeilen entweder über Nautobot GC abwickeln - oder als vom User genehmigte Ausnahme dokumentieren (Nachtrag in GC als Follow-up). +- MTU 1420 aus dem Guide; gegen die TP10-Hub-MTU 1412 (auf ap1, zum Vergleich) gegenprüfen (ggf. angleichen bei Path-MTU-Problemen). +- **Rückweg-Routing TBD:** ob der CRS326 selbst L3 für alle VLANs braucht oder nur als Mesh-Endpoint mit einer Route zurück + zu ap1 (dem weiterhin bestehenden L3-Router) fungiert, ist Teil der TP15-Bring-up-Entscheidung — anders als beim + ursprünglichen ap1-Plan (der war automatisch L3-Router aller VLANs) ist das beim CRS326 **nicht automatisch gegeben**. +- Firewall: abhängig vom dann geltenden Firewall-Stand (TP5) — Accept `100.96.0.0/12 ↔ 10.40.0.0/16` ggf. gezielt ergänzen. +- **Governance:** „Config nur via Nautobot" (TP21) → diese CRS326-Zeilen laufen **regulär über Nautobot GC**, sobald + das Device dort adoptiert ist — die ap1-Ausnahme gilt hierfür **nicht** (s. `teilprojekte.md` Ist-Stand-Zeile 31). ### 4.4 Subnetz-Route + vnet-Route umziehen - Ziel: die CIDR-Route `10.40.0.0/16` zeigt auf den **neuen Mesh-Node** statt auf `bf-pve`.