TP16.1 ABGESCHLOSSEN: privater Zugang via natives WireGuard, ICMP repariert

4.5 Abnahme bestanden: 0% Ping-Loss auf alle BF-VLANs (vorher 100%), TCP mit
echtem Datenfluss ok, FQDN-Smoke beweist cloudflared-Public-Teil unberuehrt.
4.6 Auflage #4 erfuellt: Ist-Stand als intended config nach Nautobot,
65/68 -> Template ergaenzt -> 68/68 keine Drifts.

Zentrale Falle dokumentiert: /ip service address=10.40.0.0/16 sperrt das
Router-Mgmt aus der Mesh-Range 100.96.0.0/12 aus - Ping geht, SSH/REST/MikroMCP
sterben. Fuer branch/ap1/ap2 noch offen. Und: nc -z ueber WARP ist kein
Reachability-Beweis, der CF-Proxy terminiert den Handshake.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 12:28:03 +02:00
parent 44c1fbcca8
commit 63851ad0ad
3 changed files with 101 additions and 9 deletions

View File

@@ -478,12 +478,17 @@ 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 `crs326-core` ▸ 🟡 **§4.0 DURCH, läuft — §4.1 user-gated (2026-08-17)** — `docs/tp16.1-warp-mesh-native-crs326.md`
### TP16.1 — Private Access via native Cloudflare Mesh (WireGuard) auf `crs326-core` ▸ ✅ **ABGESCHLOSSEN (2026-08-17)** — `docs/tp16.1-warp-mesh-native-crs326.md`
- ✅ **Kernergebnis: ICMP ist repariert.** Privater Zugang unterwegs läuft über **natives WireGuard auf `crs326-core`** statt cloudflared-QUIC — **0 % Ping-Loss auf alle BF-VLANs, vorher 100 %**. Genau das Symptom aus dem Incident 2026-07-16, das dieses TP ausgelöst hat. Öffentliche FQDNs unberührt auf dem 3-Tunnel-HA (TP16). Compliance **68/68**.
- ✅ **§4.0 erledigt 2026-08-17: Mesh-Node angelegt.** `bf-core-mesh` = **`d1da7c8a-2736-4cbb-8af1-32db5393fb9c`**, Register-Token in `mcp/cloudflare/.env` (`CF_MESH_REGISTER_TOKEN`, gitignored). ➡️ **Die seit 2026-07-17 offene Free-Plan-Frage ist beantwortet: der Free-ZT-Plan erlaubt Cloudflare Mesh — der LXC-Fallback ist vom Tisch.**
- 🔑 **Der Weg dahin war ein Token-Problem, kein Plan-Problem (kostete 2 Anläufe).** Der alte User-Token hatte **zwei** fehlende Permissions (§4.0 *und* §4.1 — `devices/settings` war schon lesend `403`). Ersetzt durch einen **account-owned** Token (`9984078812bc…`, ⏰ **gültig bis 2027-01-09**). Zwei Fallen, beide sehen aus wie „Token kaputt": (1) Account-Tokens verifizieren an `/accounts/{id}/tokens/verify` — am alten `/user/tokens/verify` melden sie `1000 "Invalid API Token"`, **während alle echten Endpoints 200 liefern**; (2) Dashboard-Fehler `"Account tag in access policy must match tag in request uri"` = eine **Zone**-Permission (`DNS`) steckt in der Policy-Zeile mit **Account**-Ressourcen → braucht eine eigene Zeile. Verifiziertes Soll-Set + Permission-IDs in `docs/tp16.1-…md` §4.0. **Merke: Dashboard sagt „Edit", API sagt „Write".**
- ✅ **§4.1–§4.4 durchgezogen 2026-08-17 (User-Freigabe „jetzt durchziehen").** Prereqs: `use_zt_virtual_ip=true`, Device-Profil „Cloudflare Mesh" (`4d3c0f57…`), Split-Tunnel auf **beiden** Profilen korrigiert (`100.64.0.0/10` → `/11` + `100.112.0.0/12`). Gerät: `cf-mesh` auf `crs326-core`, Mesh-IP **`100.96.0.6/32`**, Peer `162.159.193.2:2408`, **Handshake steht**, Route `100.96.0.0/12 → cf-mesh` aktiv; Backup `pre-tp16.1-mesh-20260817.backup` vorher (Auflage #4 ✅). CF meldet Node **healthy**. **§4.4: Weg A hat funktioniert — der befürchtete vnet-Gotcha trat NICHT ein**, `10.40.0.0/16` zeigt jetzt auf `bf-core-mesh` statt `bf-pve` (Rollback = 1 PATCH zurück, `bf-pve` unangetastet).
- ⚠️ **Zwei Werkzeug-Fallen, real getroffen (gehören in jede künftige WG-Arbeit):** (1) **MikroMCPs `manage_wireguard_interface` kann grundsätzlich keinen privaten Schlüssel annehmen** — RouterOS erzeugt ihn selbst; bei CF Mesh kommt er aber von CF → Key per SSH mit Interpolation aus der gitignoreten `.env` setzen, nicht über das Tool. (2) **`manage_wireguard_peer` schreibt `endpoint: "IP:Port"` komplett in `endpoint-address` und lässt `endpoint-port=0`** → **kein Handshake**, sieht aus wie ein Firewall-Problem, ist ein Parameter-Bug. Nach jedem Peer-Add `print detail` gegenlesen. Auch `persistent-keepalive` fehlt dem Tool.
- 🔴 **Offen, beide user-gated:** (1) **„Allow all Cloudflare One traffic to reach enrolled devices"** — laut CF-Docs Mesh-Prerequisite, aber **Dashboard-only** (kein API-Feld, in Spec *und* Profil-GET gegengeprüft) und entgegen unserem Runbook eine **Profil**- statt Account-Einstellung. (2) **§4.5 Ping-Abnahme** mit verbundenem WARP. Danach fällig: Auflage #4 — Ist-Stand als intended config zurück nach Nautobot.
- ✅ **§4.5 ABNAHME BESTANDEN 2026-08-17** (MacBook am Hotspot, WARP connected): **Ping 0 % Loss** auf `10.40.10.1` / `10.40.20.105` / `10.40.99.12` / `10.40.20.10` / `10.40.99.1` (47–63 ms) — **vorher 100 %**. TCP mit echtem Datenfluss (pve 8006 → 200, Nautobot → 302, `ssh macmini` → ok). FQDN-Smoke gitea/hass/pve/nautobot/vw → 200/200/302/302/200 ⇒ **cloudflared-Public-Teil unberührt.**
- ✅ **Auflage Ausnahme #4 erfüllt:** Ist-Stand als intended config zurück nach Nautobot → zuerst **65/68** (drei `extra`-Drifts = die Mesh-Zeilen), Zeilen **byte-genau aus dem Backup** ins Jinja-Template, Push nach `bf-golden-config`, Repo-Sync → **68/68, keine Drifts**. Privkey bleibt draußen (`<<REDACTED>>`-Maske wie bei `wg-hub`). ⚠️ **Push-Gotcha:** Nautobot schreibt Backups+intended in **dasselbe** Repo → `git pull --rebase` vor jedem Push, sonst `rejected (fetch first)`.
- 🔴🔴 **DIE FALLE DIESES TPs — `/ip service` sperrt das Router-Mgmt aus dem Mesh aus.** Direkt nach dem WARP-Connect war `crs326-core` mgmt-tot: MikroMCP `Connection lost before handshake`, SSH `kex_exchange_identification: Connection reset`, REST **502** — **bei gleichzeitig verlustfreiem Ping auf dieselbe IP**, und alle Hosts *hinter* dem Core normal. Ursache: `/ip service ssh,www address=10.40.0.0/16`, der Mesh-Client kommt aus `100.96.0.0/12`. ICMP kennt keine Service-ACL. **Und `nc -z` meldet „offen", weil der CF-Gateway-Proxy den TCP-Handshake terminiert — ein TCP-Connect ist über WARP KEIN Reachability-Beweis.** Fix: `address=10.40.0.0/16,100.96.0.0/12`. **Merkregel: wer per Mesh ans Netz kommt, ist noch lange nicht am Router.** ⚠️ **Für `crs326-branch`/`ap1`/`ap2` noch OFFEN** — deren eigene `/ip service`-ACLs sind ungeprüft. Entscheidender Diagnose-Schritt war der **Banner-Grab vom macmini** (`nc 10.40.99.1 22` → `SSH-2.0-ROSSSH`): von innen gesund ⇒ Pfad/ACL, nicht Gerät. Fehlspuren, die man sich sparen kann: MTU (die großen Pings scheitern am **WARP-Client**-`utun` MTU 1380, nicht an `cf-mesh`) und SSH-Session-Erschöpfung.
- 🟡 **Einziger Restpunkt, user-gated:** Dashboard-only-Schalter **„Allow all Cloudflare One traffic to reach enrolled devices"** (kein API-Feld — in Spec *und* Profil-GET gegengeprüft; entgegen unserem Runbook eine **Profil**- statt Account-Einstellung). **Der Mesh läuft nachweislich ohne ihn**; vermutlich zählt er erst für **Client↔Client**. Setzen, wenn das gebraucht wird.
- 📌 **Bleibt gültig:** die HA-Degradierung der öffentlichen Tunnel (TP16, `bf-pve` fährt nur einen Connector) wird davon **nicht** geheilt — eigener offener Punkt. Und für **TP5** vormerken: bei deny-by-default braucht der Mesh explizit `forward accept 100.96.0.0/12 ↔ 10.40.0.0/16`.
- ✅ **Gate erfüllt (2026-08-16):** die Bedingung „gated bis TP21 den CRS326 abdeckt" ist eingelöst — `crs326-core` ist seit 2026-08-08 der produktive L3-Router und seit 2026-08-13 in Nautobot adoptiert (68/68 compliant). Runbook §3 neu gemessen, §4.3 von Platzhalter auf **echte Werte** gezogen.
- 🧭 **Erwartung geraderücken (wichtig, weil leicht zu verwechseln): das Mesh ersetzt die CF-Tunnel NICHT.** TP16.1 löst ausschließlich den **privaten** Zugang (unterwegs → `10.40.0.0/16` per IP, **inklusive ICMP**) und tauscht dort den cloudflared-QUIC-Proxy gegen natives WireGuard auf dem Core. Die **öffentlichen FQDNs bleiben** auf dem 3-Tunnel-HA aus TP16. Beide Stränge laufen nebeneinander — die HA-Degradierung aus TP16 (2026-08-16) wird davon **nicht** geheilt und bleibt ein eigener offener Punkt.
- 📌 **Live-Befunde 2026-08-16 (read-only erhoben, kein Eingriff):**

View File

@@ -1,13 +1,22 @@
# TP16.1 — Private Access via native Cloudflare Mesh (WARP Connector) auf dem CRS326 Core-Switch
> **🟡 Status 2026-08-17: §4.0–§4.4 DURCH, Mesh-Tunnel steht — Abnahme (§4.5) offen.** `cf-mesh` auf
> `crs326-core` handshaked mit dem CF-PoP, CF meldet den Node **healthy**, und die Route `10.40.0.0/16` zeigt
> bereits auf ihn statt auf `bf-pve`. **Zwei Dinge fehlen noch, beide erfordern dich:** (1) der Dashboard-only-
> Schalter „Allow all Cloudflare One traffic to reach enrolled devices" (§4.1 Schritt 2), (2) die Ping-Abnahme mit
> verbundenem WARP (§4.5). Danach ist die Auflage aus Ausnahme #4 fällig: Ist-Stand als intended config zurück
> nach Nautobot.
> # ✅ **TP16.1 ABGESCHLOSSEN — 2026-08-17**
> Der private Zugang läuft über **natives WireGuard auf `crs326-core`** statt über den cloudflared-QUIC-Proxy.
> **ICMP ist damit repariert: 0 % Loss auf alle BF-VLANs (vorher 100 %)** — genau das Symptom aus dem Incident
> vom 2026-07-16, das dieses TP ausgelöst hat. Die öffentlichen FQDNs blieben unberührt auf dem 3-Tunnel-HA
> (TP16). Auflage aus Ausnahme #4 erfüllt: **68/68 compliant, keine Drifts.**
>
> *Vorstufe:* **§4.0 DURCH — Plan-Gate offen, Mesh-Node existiert.** `POST /warp_connector` erfolgreich:
> **Die drei Erkenntnisse, die Zeit gekostet haben und beim nächsten Mal Zeit sparen:**
> 1. Der Blocker war nie der Free-Plan, sondern der **API-Token** (§4.0) — Mesh ist im Free-ZT-Plan erlaubt.
> 2. **`/ip service address=10.40.0.0/16` sperrt das Router-Mgmt aus dem Mesh aus** (§4.5) — Ping geht,
> Management nicht. Für `branch`/`ap1`/`ap2` noch offen.
> 3. **MikroMCP taugt für WireGuard nur halb** (§4.3): kein Privkey möglich, und `endpoint="IP:Port"` wird
> falsch zerlegt → kein Handshake.
>
> 🔴 **Einziger verbliebener Punkt, user-gated:** der Dashboard-only-Schalter „Allow all Cloudflare One traffic
> to reach enrolled devices" (§4.1 Schritt 2). **Der Mesh läuft nachweislich auch ohne ihn** — CF führt ihn als
> Prerequisite, für Device→Node/Subnetz war er offenkundig nicht nötig. Vermutlich zählt er erst für
> **Client↔Client** (Gerät zu Gerät). Setzen, wenn das gebraucht wird. `POST /warp_connector` erfolgreich:
> **`bf-core-mesh` = `d1da7c8a-2736-4cbb-8af1-32db5393fb9c`**, Register-Token in `mcp/cloudflare/.env`
> (`CF_MESH_REGISTER_TOKEN`, gitignored, `chmod 600`). ➡️ **Die seit 2026-07-17 offene Free-Plan-Frage ist damit
> beantwortet: der Free-ZT-Plan erlaubt Cloudflare Mesh. Der LXC-Fallback (§6) ist vom Tisch.**
@@ -391,6 +400,66 @@ keine Templatezeilen — die gehören nach Nautobot und von dort gerendert.
ganze Zeit bestehen. **Wichtig fürs Remote-Arbeiten:** alle CF-API-Writes laufen über die öffentliche API
(api.cloudflare.com), NICHT über WARP → Rollback funktioniert auch, wenn der private Pfad gerade tot ist.
### 4.5 Verifikation — ✅ **BESTANDEN 2026-08-17** (MacBook am iPhone-Hotspot, WARP connected)
**Ping — der eigentliche Zweck des TPs. Vorher 100 % Loss, jetzt:**
| Ziel | VLAN | Loss | avg RTT |
|---|---|---|---|
| `10.40.10.1` | 10 | **0 %** | 47 ms |
| `10.40.20.105` (HA) | 20 | **0 %** | 56 ms |
| `10.40.99.12` (ap2) | 99 | **0 %** | 57 ms |
| `10.40.20.10` (NAS) | 20 | **0 %** | 63 ms |
| `10.40.99.1` (core) | 99 | **0 %** | 58 ms |
**TCP-Gegenprobe (echter Datenfluss, nicht nur Connect):** `https://10.40.20.100:8006` → 200 ·
`http://10.40.20.30:8080` → 302 · `ssh macmini` → ok. **FQDN-Smoke** (gitea/hass/pve/nautobot/vw über
`*.emsenhuber.net`): 200/200/302/302/200 in 0,2–0,3 s → **der cloudflared-Public-Teil blieb unberührt.**
*(`10.40.20.10:5000/5001` antwortet nicht — die DSM-Web-Ports lauschen dort schlicht nicht; SSH und 443 auf
demselben Host sind offen. Kein Mesh-Befund.)*
> 🔴🔴 **DIE FALLE DIESES TPs — `/ip service` sperrt das Router-Management aus dem Mesh aus.**
>
> Unmittelbar nach dem WARP-Connect war **`crs326-core` mgmt-seitig tot**: MikroMCP brach mit
> `Connection lost before handshake` ab, SSH mit `kex_exchange_identification: Connection reset`, REST mit
> **HTTP 502** — **während Ping zu genau derselben IP verlustfrei lief** und alle Hosts *hinter* dem Core
> (pve, Nautobot, macmini) normal antworteten.
>
> **Ursache:** auf dem Core steht `/ip service set ssh,www address=10.40.0.0/16`. Der Mesh-Client kommt aus
> **`100.96.0.0/12`** und fällt aus der ACL. ICMP kennt keine Service-ACL → geht. Und `nc -z` meldete
> „offen", weil der **CF-Gateway-Proxy** den TCP-Handshake terminiert, bevor das Origin überhaupt antwortet —
> ein TCP-Connect ist über WARP also **kein** Reachability-Beweis.
>
> **Fix:** `/ip service set [find name=ssh] address=10.40.0.0/16,100.96.0.0/12` (analog `www`).
> Danach SSH und REST über den Mesh sauber. **Merkregel: wer per Mesh ans Netz kommt, ist noch lange nicht
> am Router.** Jede Mgmt-ACL, die auf `10.40.0.0/16` steht, muss die Mesh-Range mitnehmen —
> für `crs326-branch`/`ap1`/`ap2` ist das noch **offen** (die haben eigene `/ip service`-Beschränkungen).
>
> ⚠️ Zwei Fehlspuren, die ich unterwegs verfolgt habe und die man sich sparen kann: (1) **MTU** — große Pings
> ab ~1350 B scheitern, das ist aber das **WARP-Client-Interface** (`utun` MTU 1380), nicht `cf-mesh`;
> normaler TCP-Verkehr ist davon nicht betroffen. (2) **SSH-Session-Erschöpfung** — naheliegend bei
> `Connection reset`, war es aber nicht. Der Test, der es entschied: **Banner-Grab vom macmini aus**
> (`nc 10.40.99.1 22` → `SSH-2.0-ROSSSH`) — von innen gesund, also Pfad/ACL statt Gerät.
>
> ℹ️ Nebenbefund beim Setzen: `/ip service set [find name=ssh] …` trifft **auch den dynamischen
> Verbindungs-Eintrag** (`D c ssh … local 10.40.99.1`) und quittiert mit `failure: this is configured
> elsewhere`. **Harmlos** — der statische Eintrag wird trotzdem gesetzt. Nicht als Fehlschlag werten.
### 4.6 Auflage Ausnahme #4 — ✅ **ERLEDIGT 2026-08-17: Ist-Stand ist intended config, 68/68 compliant**
Ablauf: `--refresh-compliance` zeigte zuerst **65/68** mit drei `extra`-Drifts (interface-wireguard,
ip-address, ip-route) — exakt die Mesh-Zeilen. Die Zeilen **byte-genau aus dem Nautobot-Backup** (nicht aus
dem Runbook!) ins Jinja-Template übernommen, ins GC-Repo `bf-golden-config` gepusht, Repo-Sync, erneut
compliance: **68/68, keine Drifts.**
- Der Privkey bleibt draußen: das Template emittiert `private-key="<<REDACTED>>"` — byte-identisch zur
`ConfigReplace`-Maske aus TP22 Schritt 0, genau wie bei `wg-hub`. Secret-Gegenprobe vor jedem Push gelaufen.
- ⚠️ **Gotcha beim Push:** Nautobot schreibt Backups *und* intended configs in **dasselbe** Repo → der zweite
Push wurde `rejected (fetch first)`, weil die Compliance-Läufe dazwischen committen. `git pull --rebase`
vor jedem Push einplanen.
- `/ip service` steht **nicht** im Template → die ACL-Erweiterung erzeugt keine Drift, ist damit aber auch
**nicht** in der SoT abgebildet. Bewusst so belassen; gehört zu TP5, wenn die Mgmt-Ebene modelliert wird.
<details><summary>Ursprüngliche Abnahme-Kriterien</summary>
### 4.5 Verifikation (Abnahme)
- MacBook, WARP **connected**: `ping 10.40.20.105`, `ping 10.40.10.1`, `ping 10.40.99.12` → **verlustfrei**
(Regressions-Gegenprobe zu heute: fm 36 % / bf 100 %).
@@ -398,6 +467,8 @@ keine Templatezeilen — die gehören nach Nautobot und von dort gerendert.
(gitea) mehrfach → Beweis „keine Blindheit".
- FQDN-Smoke (Stichprobe gitea/hass/pve über `*.emsenhuber.net`) → der cloudflared-Public-Teil (3-Tunnel-HA) blieb unberührt.
</details>
## 5. Danach (Cleanup, teils ins „vertagt"-Gespräch)
- Nach Mesh-Beweis: `warp-routing` auf bf-nas/bf-pve/bf-mm ggf. auf `false` (Hygiene — Public-Tunnel bedienen keine
privaten Netze mehr). CF-vnet-Route-Historie bereinigen.

View File

@@ -137,6 +137,22 @@
/interface wireguard add comment="TP10 Multi-Site VPN Hub (FM/DW spokes)" listen-port=51821 mtu=1412 name=wg-hub private-key="<<REDACTED>>"
/interface wireguard peers add allowed-address=10.101.0.0/24 comment=fm endpoint-address=abxhutfgsid9snmy.myfritz.net endpoint-port=52476 interface=wg-hub name=fm public-key="dzRY0lnnUygijChWe5wXZmXPeNcbdALpqBptA3fyiVE="
/interface wireguard peers add allowed-address=10.95.10.0/24 comment=dw interface=wg-hub name=dw public-key="FqYZLztQ/qME5VDie5QLGH++5299WJiE1dPpQnPbzUw="
# [10] CF-MESH (TP16.1) — privater Zugang unterwegs via natives WireGuard zum CF-PoP.
# Ersetzt den cloudflared-QUIC-Proxy fuer 10.40.0.0/16 (die oeffentlichen FQDNs bleiben
# auf dem 3-Tunnel-HA aus TP16). Privkey kommt von CLOUDFLARE, nicht vom Geraet — er
# steht in mcp/cloudflare/.env (CF_MESH_PRIVKEY, gitignored) und wurde einmalig per SSH
# eingespielt; hier nur die Backup-Maske, wie bei wg-hub.
# MTU 1420 aus dem animmouse-Guide. Vergleichswert auf demselben Geraet: wg-hub = 1412.
# Bei Path-MTU-Symptomen (TCP baut auf, grosse Transfers haengen) zuerst dorthin angleichen.
# Peer wurde von RouterOS zunaechst "peer5" auto-benannt und auf "cf-pop" umbenannt.
# ⚠️ MikroMCPs manage_wireguard_peer kennt weder persistent-keepalive noch einen Namen,
# und es schreibt endpoint="IP:Port" komplett in endpoint-address (endpoint-port bleibt 0
# -> KEIN Handshake). Nach jedem Peer-Add per `print detail` gegenlesen.
/interface wireguard add comment="TP16.1 Cloudflare Mesh" listen-port=13279 mtu=1420 name=cf-mesh private-key="<<REDACTED>>"
/interface wireguard peers add allowed-address=0.0.0.0/0 comment="TP16.1 CF-PoP" endpoint-address=162.159.193.2 endpoint-port=2408 interface=cf-mesh name=cf-pop persistent-keepalive=25s public-key="bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="
/ip address add address=100.96.0.6 comment="TP16.1 Mesh-Overlay" interface=cf-mesh network=100.96.0.6
/ip route add comment="TP16.1 Mesh" disabled=no distance=1 dst-address=100.96.0.0/12 gateway=cf-mesh
{% elif obj.role.name == "Switch" %}
# =====================================================================================
# L2-Switch (crs326-branch) — Sollzustand des Mgmt-Layers.