From 1fddf5d7982d44031b46d63213a2e6a8b4f42656 Mon Sep 17 00:00:00 2001 From: Christoph Emsenhuber Date: Sat, 3 Oct 2026 15:56:44 +0200 Subject: [PATCH] TP10: Mesh-WARP-Quelle fuer FM/DW-Spokes auf BF-IP NATen Spoke-FritzBoxen akzeptieren am WG-Peer nur Quell-IPs aus 10.40.0.0/16; WARP-Clients kommen ueber cf-mesh mit 100.96.0.0/12 und wurden verworfen. src-nat auf wg-hub-Egress legt die Quelle in den AllowedIPs-Raum. Template (Soll) + idempotenter Job tp10-mesh-nat (manual Plan, nie full-intended). Compliance 145/145, end-to-end verifiziert (Mac/WARP -> 10.95.10.1). Co-Authored-By: Claude Fable 5 --- nautobot/gc-configplan.py | 29 +++++++++++++++++++++++++++++ nautobot/mikrotik_routeros.j2 | 1 + 2 files changed, 30 insertions(+) diff --git a/nautobot/gc-configplan.py b/nautobot/gc-configplan.py index 8193c04..118b972 100644 --- a/nautobot/gc-configplan.py +++ b/nautobot/gc-configplan.py @@ -926,6 +926,34 @@ def job_tp45_c_dns(): return [(["crs326-core"], "\n".join(lines), "TP45-c-dns")] +def job_tp10_mesh_nat(): + """TP10 (2026-10-03): Mesh-WARP-Verkehr Richtung FM/DW-Spokes auf eine BF-IP NATen. + + WARUM: die Spoke-FritzBoxen akzeptieren am WG-Peer nur Quell-IPs aus 10.40.0.0/16 + (AllowedIPs). WARP-Clients kommen ueber cf-mesh mit 100.96.0.0/12 -> die FritzBox + verwirft den Verkehr (bewiesen: ping src=100.96.0.6 -> 100% Loss, src=10.40.20.1 + -> 0%). Eine src-nat auf dem wg-hub-Egress legt die Quelle in den AllowedIPs-Raum. + + `action=src-nat` (NICHT masquerade): wg-hub hat keine Interface-IP, masquerade + haette keine Quelle. src-nat auf eine feste BF-IP (10.40.10.1) haelt zudem das + Connection-Tracking -- die Antwort an 10.40.10.1 wird im prerouting auf die + Mesh-IP zurueckuebersetzt und via cf-mesh geroutet. + + KEIN LOCKOUT-RISIKO: reine srcnat-Ergaenzung; der no-NAT-accept (dst 10.40.0.0/16) + und der WAN-masquerade bleiben unberuehrt, die Regel matcht nur out-interface=wg-hub. + """ + cmt = "TP10: NAT mesh source to WG spokes (AllowedIPs)" + find = f'find where comment="{cmt}"' + add = (f'/ip firewall nat add action=src-nat chain=srcnat comment="{cmt}" ' + f'out-interface=wg-hub src-address=100.96.0.0/12 to-addresses=10.40.10.1') + lines = [ + f':if ([:len [/ip firewall nat {find}]] = 0) do={{ {add} }} ' + f'else={{ :log info "tp10-mesh-nat: Regel existiert schon" }}', + f':log info ("tp10-mesh-nat: regeln=" . [:tostr [:len [/ip firewall nat {find}]]])', + ] + return [(["crs326-core"], "\n".join(lines), "TP10-mesh-nat")] + + JOBS = { "drift-cleanup": job_drift_cleanup, "mgmt-acl": job_mgmt_acl, @@ -938,6 +966,7 @@ JOBS = { "tp45-v30-leases": job_tp45_v30_leases, "tp45-v30-revert": job_tp45_v30_revert, "tp45-v30-restore": job_tp45_v30_restore, + "tp10-mesh-nat": job_tp10_mesh_nat, } diff --git a/nautobot/mikrotik_routeros.j2 b/nautobot/mikrotik_routeros.j2 index 8243cc6..a8d7412 100644 --- a/nautobot/mikrotik_routeros.j2 +++ b/nautobot/mikrotik_routeros.j2 @@ -359,6 +359,7 @@ # [7] NAT /ip firewall nat add action=accept chain=srcnat comment="TP4: no-NAT inter-VLAN (LAN-internal, before masquerade)" dst-address=10.40.0.0/16 /ip firewall nat add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none out-interface-list=WAN +/ip firewall nat add action=src-nat chain=srcnat comment="TP10: NAT mesh source to WG spokes (AllowedIPs)" out-interface=wg-hub src-address=100.96.0.0/12 to-addresses=10.40.10.1 # [7b] FIREWALL FILTER (TP26, 2026-08-17). Kommt als DATEN aus # local_config_context_data.firewall_filter, nicht als Templatezeilen —