TP15: CRS326-Core als L3-Router aktiviert

- crs326-core nimmt Routing/DHCP/DNS/NAT/WAN/WireGuard von ap1 ueber.
- L2-Portplan korrigiert (ap1 #15, Arris WAN #16, branch #8, Sonos #2/3/5/6,
  IoT #14, VLAN10-Access #11, VLAN1-Hybrid #3/7/9/10/12/17-24).
- Backup-RSC gefixt (ether3-24 disabled) und via fixed-RSC eingespielt.
- Gestagede L3-Config enabled in einem Rutsch.
- Falsche statische Default-Route 0.0.0.0/0 -> 10.40.41.1 entfernt,
  WAN-DHCP via 90.146.33.177/24 aktiv.
- SFP-Ports bleiben disabled (Stromersparnis).
- ap1 ist L3-stillgelegt und wird in naechster Session reiner AP.

Backup-Dateien (*.backup) und leases-export.json bleiben lokal.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-07 22:39:29 +02:00
parent d8c8c3b828
commit d281a0f36f
25 changed files with 3214 additions and 9 deletions

View File

@@ -0,0 +1,10 @@
ap1 Cutover-Export vom 2026-08-05T22:44:30+02:00
DHCP-Leases gesamt: 59
statisch (dynamic=no): 54
dynamisch: 5
WG-Hub private-key erfasst: ja
Nächste Schritte im Cutover-Fenster:
1. ap1-leases-export.json filtern: nur dynamic=no, server-Namen auf core dhcp-v10..v99 mappen.
2. ap1-wg-hub.privkey in core-Config einsetzen (ersetzt <<< AP1_WG_HUB_PRIVKEY >>>).
3. Generate Intended Config für crs326-core erneut laufen lassen -> Nautobot-Deployment.

View File

@@ -0,0 +1,59 @@
# ap1 static leases -> crs326-core (STAGED, disabled=yes)
# Quelle: ap1-leases-export.json | 54 statische Leases
/ip/dhcp-server/lease add server=dhcp-v10 mac-address="F2:62:4C:E1:AF:09" address="10.40.10.196" client-id="1:f2:62:4c:e1:af:9" comment="iPhone" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v10 mac-address="56:71:6C:22:E6:A9" address="10.40.10.82" client-id="1:56:71:6c:22:e6:a9" dhcp-option='dns 1.1.1.1' comment="Mac" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v20 mac-address="90:09:D0:58:20:F9" address="10.40.20.10" comment="nas-bf" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="FC:EE:11:03:32:26" address="10.40.30.150" client-id="1:fc:ee:11:3:32:26" comment="ingenic-3226 / Ender3V3KE-3226" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:BC:96:1F:B2:81" address="10.40.30.180" client-id="1:e4:bc:96:1f:b2:81" dhcp-option='dns 1.1.1.1' comment="espressif / Airfryer" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="A0:85:E3:C8:65:34" address="10.40.30.202" comment="shelly-s22_kueche_steckdose3-2" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="AC:15:18:7B:62:20" address="10.40.30.203" comment="shelly-s23_dieleug-wohnzimmer_licht" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="14:33:5C:D8:2D:7C" address="10.40.30.204" comment="shelly-s24_bad_spiegelschrank" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="98:A3:16:79:38:50" address="10.40.30.205" comment="shelly-s25_bad_lichtschalter" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="98:A3:16:7C:5F:EC" address="10.40.30.206" comment="shelly-s20_kueche_steckdosen2" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="20:6E:F1:01:F9:F8" address="10.40.30.207" comment="shelly-s21_kueche_steckdosen4" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:D7:C7:A4" address="10.40.30.208" comment="shelly-s1_weihnachten_kueche" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="28:37:2F:36:F4:7C" address="10.40.30.209" comment="shelly-s2_weihnachten_terrasse" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:E4:EF:7C" address="10.40.30.210" comment="shelly-s3_weihnachten_kinderzimmer" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:E4:0F:30" address="10.40.30.211" comment="shelly-s4_kueche_mikrowelle" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="D8:85:AC:0C:5C:C8" address="10.40.30.212" comment="shelly-s5_kueche_backofen" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="D0:CF:13:D8:18:FC" address="10.40.30.213" comment="shelly-s6_kueche_kuehlschrank" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="D0:CF:13:D9:94:E8" address="10.40.30.214" comment="shelly-s7_kueche_tiefkuehlschrank" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:FA:FD:E0" address="10.40.30.215" comment="shelly-s8_kueche_geschirrspueler" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E8:F6:0A:61:88:08" address="10.40.30.216" comment="shelly-s9_wohnzimmer_sideboard" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:FC:57:E4" address="10.40.30.217" comment="shelly-s10_bad_sonos" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:FA:6C:00" address="10.40.30.218" comment="shelly-s11_kinderzimmer_sonos" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="48:F6:EE:C8:E6:AC" address="10.40.30.219" comment="shelly-s12_dieleug_steckdosen" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="48:F6:EE:DD:6A:F4" address="10.40.30.220" comment="shelly-s13_arbeitszimmer_technik" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:FC:59:48" address="10.40.30.221" comment="shelly-s14_schlafzimmer_bett" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="E4:B0:63:FA:D5:34" address="10.40.30.222" comment="shelly-s15_technik_pve" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="10:20:BA:FA:F5:40" address="10.40.30.223" comment="shelly-s16_wohnzimmer_steckdosen" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="10:20:BA:FB:6D:64" address="10.40.30.224" comment="shelly-s17_bad_steckdosen" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="48:F6:EE:CC:16:E4" address="10.40.30.225" comment="shelly-s18_kueche_steckdosen1" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="10:20:BA:FB:70:FC" address="10.40.30.226" comment="shelly-s19_kueche_steckdosen3" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="B8:F8:62:09:F2:04" address="10.40.30.227" comment="SwitchBot-floor-lamp / switchbot-floorlamp" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="98:F4:AB:2C:A7:88" address="10.40.30.228" comment="Twinkly-2CA789 / Twinkly_Weihnachtsgirlande" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="00:24:E4:40:2A:72" address="10.40.30.230" comment="Withings_waage" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="A4:7E:FA:18:2C:64" address="10.40.30.231" comment="Withings_blutdruck" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="BC:24:11:8E:0A:57" address="10.40.30.232" comment="pve-homematic-raspi-ccu" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="98:A3:16:7A:A3:54" address="10.40.30.233" comment="shelly-s26_bad_luefter" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="A4:F0:0F:5F:D0:EC" address="10.40.30.236" comment="lichterkette" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="24:DC:C3:9B:89:64" address="10.40.30.237" comment="lichterkette-mini" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="28:DB:A7:09:7B:54" address="10.40.30.241" comment="NukiSmartlock" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="24:62:AB:B1:63:F4" address="10.40.30.244" comment="NukiBridge" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="4C:EB:BD:E3:25:F2" address="10.40.30.5" comment="P750W / P750W" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v30 mac-address="54:F2:9F:12:51:F0" address="10.40.30.8" comment="DTUBI-414392337823 / DTUBI-414392337823" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="70:AF:24:B8:C9:86" address="10.40.40.11" comment="tv" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="34:7E:5C:32:37:96" address="10.40.40.191" client-id="1:34:7e:5c:32:37:96" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="34:7E:5C:32:33:B8" address="10.40.40.192" client-id="1:34:7e:5c:32:33:b8" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="78:28:CA:80:2A:F6" address="10.40.40.193" client-id="1:78:28:ca:80:2a:f6" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="48:A6:B8:14:FE:D0" address="10.40.40.194" client-id="1:48:a6:b8:14:fe:d0" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="78:28:CA:82:16:C2" address="10.40.40.195" client-id="1:78:28:ca:82:16:c2" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="48:A6:B8:16:38:AE" address="10.40.40.196" client-id="1:48:a6:b8:16:38:ae" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="48:A6:B8:14:FE:F2" address="10.40.40.197" client-id="1:48:a6:b8:14:fe:f2" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="78:28:CA:D2:0D:AC" address="10.40.40.198" comment="SonosZP / SonosTerrasse" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="48:A6:B8:0B:63:10" address="10.40.40.199" client-id="1:48:a6:b8:b:63:10" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="48:A6:B8:69:69:7B" address="10.40.40.200" client-id="1:48:a6:b8:69:69:7b" comment="SonosZP" disabled=yes
/ip/dhcp-server/lease add server=dhcp-v40 mac-address="94:9F:3E:49:59:EE" address="10.40.40.201" client-id="1:94:9f:3e:49:59:ee" comment="SonosZP" disabled=yes
# Cutover: /ip/dhcp-server/lease/enable [find comment~"ap1 lease"]

View File

@@ -0,0 +1,558 @@
# 2026-08-06 06:16:12 by RouterOS 7.23.2
# software id = 2ATI-ZRRH
#
# model = C52iG-5HaxD2HaxD
# serial number = HM70BFZBYVQ
/interface bridge
add admin-mac=D0:EA:11:4D:40:E1 auto-mac=no comment=defconf name=bridge \
vlan-filtering=yes
/interface wireguard
add comment="TP10 Multi-Site VPN Hub (FM/DW spokes). Kein IP aufs IF (Routing \
via AllowedIPs/Routes)." listen-port=51821 mtu=1412 name=wg-hub
/interface vlan
add comment="MAIN 10.40.10.0/24" interface=bridge name=vlan10 vlan-id=10
add comment="INFRA 10.40.20.0/24" interface=bridge name=vlan20 vlan-id=20
add comment="IOT 10.40.30.0/24" interface=bridge name=vlan30 vlan-id=30
add comment="MEDIA 10.40.40.0/24" interface=bridge name=vlan40 vlan-id=40
add comment="UNTRUSTED 10.40.50.0/24" interface=bridge name=vlan50 vlan-id=50
add comment="GUEST 10.40.90.0/24" interface=bridge name=vlan90 vlan-id=90
add comment="MGMT 10.40.99.0/24" interface=bridge name=vlan99 vlan-id=99
add comment="WAN Arris (Liwest)" interface=bridge name=vlan100 vlan-id=100
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface wifi channel
add band=2ghz-ax disabled=no frequency=2462 name=ch-2g width=20mhz
add band=5ghz-ax disabled=no frequency=5745 name=ch-5g skip-dfs-channels=\
10min-cac width=20/40/80mhz
/interface wifi datapath
add bridge=bridge name=dp-main vlan-id=10
add bridge=bridge name=dp-iot vlan-id=30
add bridge=bridge name=dp-media vlan-id=40
add bridge=bridge name=dp-untrusted vlan-id=50
add bridge=bridge name=dp-guest vlan-id=90
add bridge=bridge name=dp-infra vlan-id=20
/interface wifi security
add authentication-types=wpa3-psk disabled=no ft=yes ft-over-ds=yes name=\
sec-main
add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=sec-iot
add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no ft-over-ds=no \
name=sec-media
add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=\
sec-untrusted
add authentication-types=wpa2-psk,wpa3-psk ft=yes ft-over-ds=yes name=\
sec-guest
add authentication-types=wpa2-psk,wpa3-psk ft=no name=sec-infra
/interface wifi configuration
add country=Austria disabled=no mode=ap name=cfg-main-2g security=sec-main \
ssid=dirtyvader-main tx-power=20
add country=Austria datapath=dp-iot mode=ap multicast-enhance=enabled name=\
cfg-iot security=sec-iot ssid=dirtyvader-iot
add country=Austria datapath=dp-media mode=ap multicast-enhance=enabled name=\
cfg-media security=sec-media ssid=dirtyvader-media
add country=Austria datapath=dp-untrusted mode=ap name=cfg-untrusted \
security=sec-untrusted ssid=dirtyvader-untrusted
add country=Austria datapath=dp-guest mode=ap name=cfg-guest security=\
sec-guest ssid=dirtyvader-guest
add country=Austria datapath=dp-infra mode=ap name=cfg-infra security=\
sec-infra ssid=dirtyvader-infra
/interface wifi
set [ find default-name=wifi2 ] channel.frequency=2412 configuration=\
cfg-main-2g configuration.manager=local disabled=no
add configuration=cfg-guest disabled=no mac-address=D2:EA:11:4D:40:EB \
master-interface=wifi2 name=w2-guest
add configuration=cfg-iot disabled=no mac-address=D2:EA:11:4D:40:E8 \
master-interface=wifi2 name=w2-iot
add configuration=cfg-media disabled=no mac-address=D2:EA:11:4D:40:E9 \
master-interface=wifi2 name=w2-media
add configuration=cfg-untrusted disabled=no mac-address=D2:EA:11:4D:40:EA \
master-interface=wifi2 name=w2-untrusted
/interface wifi steering
add name=st-main neighbor-group=bf-main rrm=yes wnm=yes
/interface wifi configuration
add channel=ch-5g country=Austria datapath=dp-main mode=ap name=cfg-main-5g \
security=sec-main ssid=dirtyvader-main steering=st-main
/interface wifi
set [ find default-name=wifi1 ] channel.frequency=5180 configuration=\
cfg-main-5g configuration.manager=local disabled=no
add configuration=cfg-guest disabled=no mac-address=D2:EA:11:4D:40:E7 \
master-interface=wifi1 name=w5-guest
add configuration=cfg-media disabled=no mac-address=D2:EA:11:4D:40:E5 \
master-interface=wifi1 name=w5-media
add configuration=cfg-untrusted disabled=no mac-address=D2:EA:11:4D:40:E6 \
master-interface=wifi1 name=w5-untrusted
/ip dhcp-server option
add code=6 name="dns 1.1.1.1" value=0x01010101
add code=138 name=omada-inform value=0x0A2814AF
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
add name=pool-v10 ranges=10.40.10.100-10.40.10.200
add name=pool-v20 ranges=10.40.20.100-10.40.20.200
add name=pool-v30 ranges=10.40.30.100-10.40.30.250
add name=pool-v40 ranges=10.40.40.100-10.40.40.200
add name=pool-v50 ranges=10.40.50.100-10.40.50.200
add name=pool-v90 ranges=10.40.90.100-10.40.90.200
add name=pool-v99 ranges=10.40.99.100-10.40.99.200
add comment="BF flat .41 (legacy, retiring)" name=pool-v1 ranges=\
10.40.41.180-10.40.41.199
/ip dhcp-server
add address-pool=pool-v1 disabled=yes interface=bridge lease-time=2h name=\
defconf
add address-pool=pool-v10 comment=MAIN interface=vlan10 lease-time=1d name=\
dhcp-v10
add address-pool=pool-v20 comment=INFRA interface=vlan20 lease-time=1d name=\
dhcp-v20
add address-pool=pool-v30 comment=IOT interface=vlan30 lease-time=1d name=\
dhcp-v30
add address-pool=pool-v40 comment=MEDIA interface=vlan40 lease-time=1d name=\
dhcp-v40
add address-pool=pool-v50 comment=UNTRUSTED interface=vlan50 lease-time=1d \
name=dhcp-v50
add address-pool=pool-v90 comment=GUEST interface=vlan90 lease-time=12h name=\
dhcp-v90
add address-pool=pool-v99 comment=MGMT interface=vlan99 lease-time=1d name=\
dhcp-v99
/system logging action
add disk-file-name=wan-test disk-lines-per-file=2000 name=wantest target=disk
/system script
add dont-require-permissions=no name=wantest-probe owner=admin policy=\
read,write,policy,test source=" :local ts ([/system clock get date] . \" \
\" . [/system clock get time])\
\n :local e1stat \"\?\"\
\n :do { :set e1stat [/ip dhcp-client get [find interface=ether1] status]\
\_} on-error={}\
\n :local e1addr \"-\"\
\n :do { :set e1addr [/ip dhcp-client get [find interface=ether1] address\
] } on-error={}\
\n :local e1mac [/interface ethernet get [find name=ether1] mac-address]\
\n :log info (\"WANTEST [\" . \$ts . \"] ether1 status=\" . \$e1stat . \"\
\_addr=\" . \$e1addr . \" mac=\" . \$e1mac)\
\n :local gw \"-\"\
\n :do { :set gw [/ip route get [find dst-address=\"0.0.0.0/0\" active=ye\
s] gateway] } on-error={}\
\n :log info (\"WANTEST route default-gw=\" . \$gw)\
\n # WAN-Routing+NAT: Router -> public 1.1.1.1 (UDP/53). UNABH\C3\84NGIG \
von ap1-DNS-Config.\
\n # (ICMP/HTTPS sind hier geblockt -> :resolve gegen feste IP ist das ro\
buste Signal.)\
\n :do { :local w [:resolve \"google.com\" server=1.1.1.1] ; :log info (\
\"WANTEST wan-reach via-1.1.1.1 ok google.com=\" . \$w) } on-error={ :log \
info \"WANTEST wan-reach via-1.1.1.1 FAIL (Routing/NAT\?)\" }\
\n # DoH end-to-end: ap1-Resolver = was die Clients als DNS bekommen\
\n :do { :local d [:resolve \"google.com\"] ; :log info (\"WANTEST dns-do\
h ok google.com=\" . \$d) } on-error={ :log info \"WANTEST dns-doh FAIL (D\
oH/Bootstrap\?)\" }"
add dont-require-permissions=no name=wantest-run owner=admin policy=\
read,write,policy,test source=" :global WTN\
\n :if (([:typeof \$WTN] = \"nothing\") or (\$WTN = \"\")) do={ :set WTN \
24 }\
\n :log info (\"WANTEST run start (\" . \$WTN . \"x @15s, ~\" . (\$WTN * \
15 / 60) . \" min)\")\
\n :for i from=1 to=\$WTN do={\
\n /system script run wantest-probe\
\n :delay 15s\
\n }\
\n :log info \"WANTEST run done\""
add dont-require-permissions=no name=wanmac-clone owner=admin policy=\
read,write,policy,test source=" :global FBMAC\
\n :if (([:typeof \$FBMAC] = \"nothing\") or (\$FBMAC = \"\")) do={ :set \
FBMAC \"0C:72:74:36:90:99\" }\
\n :global E1ORIG\
\n :set E1ORIG [/interface ethernet get [find name=ether1] mac-address]\
\n :log info (\"WANTEST macclone: orig=\" . \$E1ORIG . \" -> fb=\" . \$FB\
MAC . \" (Auto-Revert in ~90s)\")\
\n /interface ethernet set [find name=ether1] mac-address=\$FBMAC\
\n :do { /ip dhcp-client release [find interface=ether1] } on-error={}\
\n :delay 2s\
\n :do { /ip dhcp-client renew [find interface=ether1] } on-error={}\
\n :delay 25s\
\n :for i from=1 to=4 do={ /system script run wantest-probe ; :delay 15s \
}\
\n # --- garantierter Auto-Revert im selben Lauf (kein Scheduler n\C3\B6t\
ig) ---\
\n /interface ethernet reset-mac-address [find name=ether1]\
\n :do { /ip dhcp-client release [find interface=ether1] } on-error={}\
\n :delay 2s\
\n :do { /ip dhcp-client renew [find interface=ether1] } on-error={}\
\n :delay 15s\
\n /system script run wantest-probe\
\n :log info (\"WANTEST macclone done -> revert auf factory-MAC (orig war\
\_\" . \$E1ORIG . \")\")"
add dont-require-permissions=no name=wanmac-revert owner=admin policy=\
read,write,policy,test source=" /interface ethernet reset-mac-address [fi\
nd name=ether1]\
\n :do { /ip dhcp-client release [find interface=ether1] } on-error={}\
\n :delay 2s\
\n :do { /ip dhcp-client renew [find interface=ether1] } on-error={}\
\n :delay 10s\
\n /system script run wantest-probe\
\n :log info \"WANTEST macclone manual-revert -> factory-MAC\""
/disk settings
set auto-media-interface=bridge auto-media-sharing=yes auto-smb-sharing=yes
/interface bridge port
add bridge=bridge comment=defconf interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
add bridge=bridge comment=defconf interface=wifi2
add bridge=bridge interface=ether1
/interface bridge vlan
add bridge=bridge untagged=bridge,ether2 vlan-ids=1
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=10
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=20
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=30
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=40
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=50
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=90
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=99
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=100
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add comment="WAN Arris via vlan100" interface=vlan100 list=WAN
/interface wifi access-list
add action=accept comment="pin P750W to ap1 (1/2): accept on ap1 iot" \
disabled=yes interface=w2-iot mac-address=4C:EB:BD:E3:25:F2
add action=reject comment=\
"pin P750W to ap1 (2/2): reject on any other AP incl dynamic ap2 VAPs" \
disabled=yes mac-address=4C:EB:BD:E3:25:F2
/interface wifi cap
set caps-man-addresses=10.40.41.1 discovery-interfaces=bridge
/interface wifi capsman
set enabled=yes interfaces=bridge
/interface wifi provisioning
add action=create-dynamic-enabled master-configuration=cfg-main-2g \
slave-configurations=cfg-iot,cfg-media,cfg-untrusted,cfg-guest,cfg-infra \
supported-bands=2ghz-ax
add action=create-dynamic-enabled master-configuration=cfg-main-5g \
slave-configurations=cfg-media,cfg-untrusted,cfg-guest,cfg-infra \
supported-bands=5ghz-ax
/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="
add allowed-address=10.95.10.0/24 comment=dw interface=wg-hub name=dw \
public-key="FqYZLztQ/qME5VDie5QLGH++5299WJiE1dPpQnPbzUw="
/ip address
add address=10.40.41.1/24 comment=defconf interface=bridge network=10.40.41.0
add address=10.40.10.1/24 comment="MAIN GW" interface=vlan10 network=\
10.40.10.0
add address=10.40.20.1/24 comment="INFRA GW" interface=vlan20 network=\
10.40.20.0
add address=10.40.30.1/24 comment="IOT GW" interface=vlan30 network=\
10.40.30.0
add address=10.40.40.1/24 comment="MEDIA GW" interface=vlan40 network=\
10.40.40.0
add address=10.40.50.1/24 comment="UNTRUSTED GW" interface=vlan50 network=\
10.40.50.0
add address=10.40.90.1/24 comment="GUEST GW" interface=vlan90 network=\
10.40.90.0
add address=10.40.99.1/24 comment="MGMT GW" interface=vlan99 network=\
10.40.99.0
add address=10.40.41.254/24 comment="Secondary = alte FB-GW-IP; haelt statisch\
e .41-Hosts online nach Arris-Swap (ap1 NATs + WG-Hub)" interface=bridge \
network=10.40.41.0
/ip dhcp-client
add comment=defconf disabled=yes interface=ether1 name=client1 use-peer-dns=\
no
add comment="WAN Arris DHCP (Liwest) via vlan100" interface=vlan100 name=\
client2 use-peer-dns=no use-peer-ntp=no
/ip dhcp-server lease
add address=10.40.10.82 client-id=1:56:71:6c:22:e6:a9 dhcp-option=\
"dns 1.1.1.1" mac-address=56:71:6C:22:E6:A9 server=dhcp-v10
add address=10.40.10.196 client-id=1:f2:62:4c:e1:af:9 mac-address=\
F2:62:4C:E1:AF:09 server=dhcp-v10
add address=10.40.40.199 client-id=1:48:a6:b8:b:63:10 mac-address=\
48:A6:B8:0B:63:10 server=dhcp-v40
add address=10.40.40.191 client-id=1:34:7e:5c:32:37:96 mac-address=\
34:7E:5C:32:37:96 server=dhcp-v40
add address=10.40.40.192 client-id=1:34:7e:5c:32:33:b8 mac-address=\
34:7E:5C:32:33:B8 server=dhcp-v40
add address=10.40.40.193 client-id=1:78:28:ca:80:2a:f6 mac-address=\
78:28:CA:80:2A:F6 server=dhcp-v40
add address=10.40.40.195 client-id=1:78:28:ca:82:16:c2 mac-address=\
78:28:CA:82:16:C2 server=dhcp-v40
add address=10.40.40.201 client-id=1:94:9f:3e:49:59:ee mac-address=\
94:9F:3E:49:59:EE server=dhcp-v40
add address=10.40.40.196 client-id=1:48:a6:b8:16:38:ae mac-address=\
48:A6:B8:16:38:AE server=dhcp-v40
add address=10.40.40.197 client-id=1:48:a6:b8:14:fe:f2 mac-address=\
48:A6:B8:14:FE:F2 server=dhcp-v40
add address=10.40.40.200 client-id=1:48:a6:b8:69:69:7b mac-address=\
48:A6:B8:69:69:7B server=dhcp-v40
add address=10.40.40.194 client-id=1:48:a6:b8:14:fe:d0 mac-address=\
48:A6:B8:14:FE:D0 server=dhcp-v40
add address=10.40.40.198 comment=SonosTerrasse mac-address=78:28:CA:D2:0D:AC \
server=dhcp-v40
add address=10.40.30.202 comment=shelly-s22_kueche_steckdose3-2 mac-address=\
A0:85:E3:C8:65:34 server=dhcp-v30
add address=10.40.30.203 comment=shelly-s23_dieleug-wohnzimmer_licht \
mac-address=AC:15:18:7B:62:20 server=dhcp-v30
add address=10.40.30.205 comment=shelly-s25_bad_lichtschalter mac-address=\
98:A3:16:79:38:50 server=dhcp-v30
add address=10.40.30.206 comment=shelly-s20_kueche_steckdosen2 mac-address=\
98:A3:16:7C:5F:EC server=dhcp-v30
add address=10.40.30.207 comment=shelly-s21_kueche_steckdosen4 mac-address=\
20:6E:F1:01:F9:F8 server=dhcp-v30
add address=10.40.30.208 comment=shelly-s1_weihnachten_kueche mac-address=\
E4:B0:63:D7:C7:A4 server=dhcp-v30
add address=10.40.30.209 comment=shelly-s2_weihnachten_terrasse mac-address=\
28:37:2F:36:F4:7C server=dhcp-v30
add address=10.40.30.210 comment=shelly-s3_weihnachten_kinderzimmer \
mac-address=E4:B0:63:E4:EF:7C server=dhcp-v30
add address=10.40.30.211 comment=shelly-s4_kueche_mikrowelle mac-address=\
E4:B0:63:E4:0F:30 server=dhcp-v30
add address=10.40.30.212 comment=shelly-s5_kueche_backofen mac-address=\
D8:85:AC:0C:5C:C8 server=dhcp-v30
add address=10.40.30.213 comment=shelly-s6_kueche_kuehlschrank mac-address=\
D0:CF:13:D8:18:FC server=dhcp-v30
add address=10.40.30.214 comment=shelly-s7_kueche_tiefkuehlschrank \
mac-address=D0:CF:13:D9:94:E8 server=dhcp-v30
add address=10.40.30.215 comment=shelly-s8_kueche_geschirrspueler \
mac-address=E4:B0:63:FA:FD:E0 server=dhcp-v30
add address=10.40.30.216 comment=shelly-s9_wohnzimmer_sideboard mac-address=\
E8:F6:0A:61:88:08 server=dhcp-v30
add address=10.40.30.217 comment=shelly-s10_bad_sonos mac-address=\
E4:B0:63:FC:57:E4 server=dhcp-v30
add address=10.40.30.218 comment=shelly-s11_kinderzimmer_sonos mac-address=\
E4:B0:63:FA:6C:00 server=dhcp-v30
add address=10.40.30.219 comment=shelly-s12_dieleug_steckdosen mac-address=\
48:F6:EE:C8:E6:AC server=dhcp-v30
add address=10.40.30.220 comment=shelly-s13_arbeitszimmer_technik \
mac-address=48:F6:EE:DD:6A:F4 server=dhcp-v30
add address=10.40.30.221 comment=shelly-s14_schlafzimmer_bett mac-address=\
E4:B0:63:FC:59:48 server=dhcp-v30
add address=10.40.30.222 comment=shelly-s15_technik_pve mac-address=\
E4:B0:63:FA:D5:34 server=dhcp-v30
add address=10.40.30.223 comment=shelly-s16_wohnzimmer_steckdosen \
mac-address=10:20:BA:FA:F5:40 server=dhcp-v30
add address=10.40.30.224 comment=shelly-s17_bad_steckdosen mac-address=\
10:20:BA:FB:6D:64 server=dhcp-v30
add address=10.40.30.225 comment=shelly-s18_kueche_steckdosen1 mac-address=\
48:F6:EE:CC:16:E4 server=dhcp-v30
add address=10.40.30.226 comment=shelly-s19_kueche_steckdosen3 mac-address=\
10:20:BA:FB:70:FC server=dhcp-v30
add address=10.40.30.227 comment=switchbot-floorlamp mac-address=\
B8:F8:62:09:F2:04 server=dhcp-v30
add address=10.40.30.228 comment=Twinkly_Weihnachtsgirlande mac-address=\
98:F4:AB:2C:A7:88 server=dhcp-v30
add address=10.40.30.230 comment=Withings_waage mac-address=00:24:E4:40:2A:72 \
server=dhcp-v30
add address=10.40.30.231 comment=Withings_blutdruck mac-address=\
A4:7E:FA:18:2C:64 server=dhcp-v30
add address=10.40.30.232 comment=pve-homematic-raspi-ccu mac-address=\
BC:24:11:8E:0A:57 server=dhcp-v30
add address=10.40.30.233 comment=shelly-s26_bad_luefter mac-address=\
98:A3:16:7A:A3:54 server=dhcp-v30
add address=10.40.30.236 comment=lichterkette mac-address=A4:F0:0F:5F:D0:EC \
server=dhcp-v30
add address=10.40.30.237 comment=lichterkette-mini mac-address=\
24:DC:C3:9B:89:64 server=dhcp-v30
add address=10.40.30.241 comment=NukiSmartlock mac-address=28:DB:A7:09:7B:54 \
server=dhcp-v30
add address=10.40.30.244 comment=NukiBridge mac-address=24:62:AB:B1:63:F4 \
server=dhcp-v30
add address=10.40.30.8 comment=DTUBI-414392337823 mac-address=\
54:F2:9F:12:51:F0 server=dhcp-v30
add address=10.40.20.10 comment=nas-bf mac-address=90:09:D0:58:20:F9 server=\
dhcp-v20
add address=10.40.40.11 comment=tv mac-address=70:AF:24:B8:C9:86 server=\
dhcp-v40
add address=10.40.30.5 comment=P750W mac-address=4C:EB:BD:E3:25:F2 server=\
dhcp-v30
add address=10.40.30.180 client-id=1:e4:bc:96:1f:b2:81 comment=Airfryer \
dhcp-option="dns 1.1.1.1" mac-address=E4:BC:96:1F:B2:81 server=dhcp-v30
add address=10.40.30.204 comment=shelly-s24_bad_spiegelschrank mac-address=\
14:33:5C:D8:2D:7C server=dhcp-v30
add address=10.40.30.150 client-id=1:fc:ee:11:3:32:26 comment=Ender3V3KE-3226 \
mac-address=FC:EE:11:03:32:26 server=dhcp-v30
/ip dhcp-server network
add address=10.40.10.0/24 comment=MAIN dns-server=10.40.10.1 gateway=\
10.40.10.1
add address=10.40.20.0/24 comment=INFRA dns-server=10.40.20.1 gateway=\
10.40.20.1
add address=10.40.30.0/24 comment=IOT dns-server=10.40.30.1 gateway=\
10.40.30.1
add address=10.40.40.0/24 comment=MEDIA dns-server=10.40.40.1 gateway=\
10.40.40.1
add address=10.40.41.0/24 comment=defconf dns-server=10.40.41.1 gateway=\
10.40.41.1 netmask=24
add address=10.40.50.0/24 comment=UNTRUSTED dns-server=10.40.50.1 gateway=\
10.40.50.1
add address=10.40.90.0/24 comment=GUEST dns-server=10.40.90.1 gateway=\
10.40.90.1
add address=10.40.99.0/24 comment=MGMT dhcp-option=omada-inform dns-server=\
10.40.99.1 gateway=10.40.99.1
/ip dns
set allow-remote-requests=yes mdns-repeat-ifaces=\
vlan10,vlan20,vlan40,vlan30,vlan90,bridge servers=1.1.1.1 use-doh-server=\
https://px35ynlol3.cloudflare-gateway.com/dns-query verify-doh-cert=yes
/ip dns static
add address=10.40.41.1 comment=defconf name=router.lan type=A
add address=10.40.41.2 comment=\
"TP4-transition; update to 10.40.99.2 after MGMT migration" name=\
ap2.bf.lan type=A
add address=10.40.41.11 comment="ALLNET core switch" name=sw1.bf.lan type=A
add address=10.40.41.12 comment="Omada access switch" name=sw2.bf.lan type=A
add address=10.40.20.167 comment=\
"Mac mini (INFRA VLAN20, migriert 2026-06-16)" name=macmini.bf.lan type=A
add address=10.40.20.100 comment="Proxmox hypervisor" name=pve.bf.lan type=A
add address=10.40.20.173 comment="pve-mcp SSE server" name=pve-mcp.bf.lan \
type=A
add address=10.40.20.10 comment=\
"DS923+ NAS (VLAN20, TP14.1, DNS-Sweep TP14.3 2026-07-16)" name=\
nas.bf.lan type=A
add address=10.40.20.126 comment=\
"Docker-LXC / Portainer (VLAN20, TP14.2, DNS-Sweep TP14.3 2026-07-16)" \
name=docker.bf.lan type=A
add address=10.40.99.1 comment=\
"TP19.1: ap1 MGMT = vlan99 GW (live since TP4), no separate move needed" \
name=ap1.bf.lan type=A
add address=10.40.20.20 comment=\
"TP20: Platform-Postgres LXC 105 on pve, PG16, nautobot DB" name=\
platform-pg.bf.lan type=A
/ip firewall filter
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
connection-state=established,related
add action=accept chain=forward comment=\
"defconf: accept established,related, untracked" connection-state=\
established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
connection-state=invalid
add action=drop chain=forward comment=\
"defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
in-interface-list=WAN
add action=accept chain=input comment=TP10-seal-est connection-state=\
established,related,untracked
add action=drop chain=input comment=TP10-seal-inv connection-state=invalid
add action=accept chain=input comment="TP10: WG hub listen (51821)" dst-port=\
51821 protocol=udp
add action=accept chain=forward comment="TP10: allow from WG spokes (FM/DW)" \
in-interface=wg-hub
add action=accept chain=forward comment="TP10: allow to WG spokes (FM/DW)" \
out-interface=wg-hub
add action=accept chain=input comment=TP10-seal-dhcp dst-port=68 \
in-interface-list=WAN protocol=udp
add action=accept chain=input comment=TP10-seal-icmp protocol=icmp
add action=accept chain=input comment=TP10-seal-lan in-interface-list=LAN
add action=drop chain=input comment=TP10-seal-wandrop in-interface-list=WAN
add action=accept chain=forward comment=\
"TP5: MAIN->MEDIA forward (AirPlay/Sonos)" in-interface=vlan10 \
out-interface=vlan40
add action=accept chain=forward comment=\
"TP5: MEDIA->MAIN forward (AirPlay/Sonos)" in-interface=vlan40 \
out-interface=vlan10
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan10 (repeater)" dst-port=5353 in-interface=\
vlan10 protocol=udp
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan40 (repeater)" dst-port=5353 in-interface=\
vlan40 protocol=udp
add action=accept chain=forward comment=\
"TP5: INFRA->MEDIA forward (HA<->Sonos)" in-interface=vlan20 \
out-interface=vlan40
add action=accept chain=forward comment=\
"TP5: MEDIA->INFRA forward (HA<->Sonos)" in-interface=vlan40 \
out-interface=vlan20
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan20 (repeater/HA)" dst-port=5353 in-interface=\
vlan20 protocol=udp
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan30 (repeater)" dst-port=5353 in-interface=\
vlan30 protocol=udp
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan90 (repeater)" dst-port=5353 in-interface=\
vlan90 protocol=udp
add action=accept chain=forward comment=\
"TP5: GUEST->MEDIA forward (Sonos/Cast)" in-interface=vlan90 \
out-interface=vlan40
add action=accept chain=forward comment=\
"TP5: MEDIA->GUEST forward (Sonos/Cast)" in-interface=vlan40 \
out-interface=vlan90
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
ipsec-policy=out,none out-interface-list=WAN
add action=accept chain=srcnat comment=\
"TP4: no-NAT inter-VLAN (LAN-internal, before masquerade)" dst-address=\
10.40.0.0/16
add action=masquerade chain=srcnat comment="TP4: masquerade VLANs toward FB" \
disabled=yes out-interface=bridge
add action=masquerade chain=srcnat comment=\
"TP4: masquerade VLANs via ether1 (Liwest WAN)" disabled=yes \
out-interface=ether1
/ip route
add comment="TP10: FM spoke -> wg-hub" dst-address=10.101.0.0/24 gateway=\
wg-hub
add comment="TP10: DW spoke (kuenftig) -> wg-hub" dst-address=10.95.10.0/24 \
gateway=wg-hub
/ipv6 firewall address-list
add address=::/128 comment="defconf: unspecified address" list=bad_ipv6
add address=::1/128 comment="defconf: lo" list=bad_ipv6
add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6
add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6
add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6
add address=100::/64 comment="defconf: discard only " list=bad_ipv6
add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6
add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6
add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6
/ipv6 firewall filter
add action=accept chain=input comment=\
"defconf: accept established,related,untracked" connection-state=\
established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
invalid
add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\
icmpv6
add action=accept chain=input comment="defconf: accept UDP traceroute" \
dst-port=33434-33534 protocol=udp
add action=accept chain=input comment=\
"defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\
udp src-address=fe80::/10
add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \
protocol=udp
add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\
ipsec-ah
add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\
ipsec-esp
add action=accept chain=input comment=\
"defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=input comment=\
"defconf: drop everything else not coming from LAN" in-interface-list=\
!LAN
add action=fasttrack-connection chain=forward comment="defconf: fasttrack6" \
connection-state=established,related
add action=accept chain=forward comment=\
"defconf: accept established,related,untracked" connection-state=\
established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
connection-state=invalid
add action=drop chain=forward comment=\
"defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6
add action=drop chain=forward comment=\
"defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6
add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \
hop-limit=equal:1 protocol=icmpv6
add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\
icmpv6
add action=accept chain=forward comment="defconf: accept HIP" protocol=139
add action=accept chain=forward comment="defconf: accept IKE" dst-port=\
500,4500 protocol=udp
add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\
ipsec-ah
add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\
ipsec-esp
add action=accept chain=forward comment=\
"defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=forward comment=\
"defconf: drop everything else not coming from LAN" in-interface-list=\
!LAN
/system clock
set time-zone-name=Europe/Vienna
/system identity
set name=ap1
/system logging
add action=wantest topics=script

View File

@@ -0,0 +1,558 @@
# 2026-08-06 09:36:00 by RouterOS 7.23.2
# software id = 2ATI-ZRRH
#
# model = C52iG-5HaxD2HaxD
# serial number = HM70BFZBYVQ
/interface bridge
add admin-mac=D0:EA:11:4D:40:E1 auto-mac=no comment=defconf name=bridge \
vlan-filtering=yes
/interface wireguard
add comment="TP10 Multi-Site VPN Hub (FM/DW spokes). Kein IP aufs IF (Routing \
via AllowedIPs/Routes)." listen-port=51821 mtu=1412 name=wg-hub
/interface vlan
add comment="MAIN 10.40.10.0/24" interface=bridge name=vlan10 vlan-id=10
add comment="INFRA 10.40.20.0/24" interface=bridge name=vlan20 vlan-id=20
add comment="IOT 10.40.30.0/24" interface=bridge name=vlan30 vlan-id=30
add comment="MEDIA 10.40.40.0/24" interface=bridge name=vlan40 vlan-id=40
add comment="UNTRUSTED 10.40.50.0/24" interface=bridge name=vlan50 vlan-id=50
add comment="GUEST 10.40.90.0/24" interface=bridge name=vlan90 vlan-id=90
add comment="MGMT 10.40.99.0/24" interface=bridge name=vlan99 vlan-id=99
add comment="WAN Arris (Liwest)" interface=bridge name=vlan100 vlan-id=100
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface wifi channel
add band=2ghz-ax disabled=no frequency=2462 name=ch-2g width=20mhz
add band=5ghz-ax disabled=no frequency=5745 name=ch-5g skip-dfs-channels=\
10min-cac width=20/40/80mhz
/interface wifi datapath
add bridge=bridge name=dp-main vlan-id=10
add bridge=bridge name=dp-iot vlan-id=30
add bridge=bridge name=dp-media vlan-id=40
add bridge=bridge name=dp-untrusted vlan-id=50
add bridge=bridge name=dp-guest vlan-id=90
add bridge=bridge name=dp-infra vlan-id=20
/interface wifi security
add authentication-types=wpa3-psk disabled=no ft=yes ft-over-ds=yes name=\
sec-main
add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=sec-iot
add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no ft-over-ds=no \
name=sec-media
add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=\
sec-untrusted
add authentication-types=wpa2-psk,wpa3-psk ft=yes ft-over-ds=yes name=\
sec-guest
add authentication-types=wpa2-psk,wpa3-psk ft=no name=sec-infra
/interface wifi configuration
add country=Austria disabled=no mode=ap name=cfg-main-2g security=sec-main \
ssid=dirtyvader-main tx-power=20
add country=Austria datapath=dp-iot mode=ap multicast-enhance=enabled name=\
cfg-iot security=sec-iot ssid=dirtyvader-iot
add country=Austria datapath=dp-media mode=ap multicast-enhance=enabled name=\
cfg-media security=sec-media ssid=dirtyvader-media
add country=Austria datapath=dp-untrusted mode=ap name=cfg-untrusted \
security=sec-untrusted ssid=dirtyvader-untrusted
add country=Austria datapath=dp-guest mode=ap name=cfg-guest security=\
sec-guest ssid=dirtyvader-guest
add country=Austria datapath=dp-infra mode=ap name=cfg-infra security=\
sec-infra ssid=dirtyvader-infra
/interface wifi
set [ find default-name=wifi2 ] channel.frequency=2412 configuration=\
cfg-main-2g configuration.manager=local disabled=no
add configuration=cfg-guest disabled=no mac-address=D2:EA:11:4D:40:EB \
master-interface=wifi2 name=w2-guest
add configuration=cfg-iot disabled=no mac-address=D2:EA:11:4D:40:E8 \
master-interface=wifi2 name=w2-iot
add configuration=cfg-media disabled=no mac-address=D2:EA:11:4D:40:E9 \
master-interface=wifi2 name=w2-media
add configuration=cfg-untrusted disabled=no mac-address=D2:EA:11:4D:40:EA \
master-interface=wifi2 name=w2-untrusted
/interface wifi steering
add name=st-main neighbor-group=bf-main rrm=yes wnm=yes
/interface wifi configuration
add channel=ch-5g country=Austria datapath=dp-main mode=ap name=cfg-main-5g \
security=sec-main ssid=dirtyvader-main steering=st-main
/interface wifi
set [ find default-name=wifi1 ] channel.frequency=5180 configuration=\
cfg-main-5g configuration.manager=local disabled=no
add configuration=cfg-guest disabled=no mac-address=D2:EA:11:4D:40:E7 \
master-interface=wifi1 name=w5-guest
add configuration=cfg-media disabled=no mac-address=D2:EA:11:4D:40:E5 \
master-interface=wifi1 name=w5-media
add configuration=cfg-untrusted disabled=no mac-address=D2:EA:11:4D:40:E6 \
master-interface=wifi1 name=w5-untrusted
/ip dhcp-server option
add code=6 name="dns 1.1.1.1" value=0x01010101
add code=138 name=omada-inform value=0x0A2814AF
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
add name=pool-v10 ranges=10.40.10.100-10.40.10.200
add name=pool-v20 ranges=10.40.20.100-10.40.20.200
add name=pool-v30 ranges=10.40.30.100-10.40.30.250
add name=pool-v40 ranges=10.40.40.100-10.40.40.200
add name=pool-v50 ranges=10.40.50.100-10.40.50.200
add name=pool-v90 ranges=10.40.90.100-10.40.90.200
add name=pool-v99 ranges=10.40.99.100-10.40.99.200
add comment="BF flat .41 (legacy, retiring)" name=pool-v1 ranges=\
10.40.41.180-10.40.41.199
/ip dhcp-server
add address-pool=pool-v1 disabled=yes interface=bridge lease-time=2h name=\
defconf
add address-pool=pool-v10 comment=MAIN interface=vlan10 lease-time=1d name=\
dhcp-v10
add address-pool=pool-v20 comment=INFRA interface=vlan20 lease-time=1d name=\
dhcp-v20
add address-pool=pool-v30 comment=IOT interface=vlan30 lease-time=1d name=\
dhcp-v30
add address-pool=pool-v40 comment=MEDIA interface=vlan40 lease-time=1d name=\
dhcp-v40
add address-pool=pool-v50 comment=UNTRUSTED interface=vlan50 lease-time=1d \
name=dhcp-v50
add address-pool=pool-v90 comment=GUEST interface=vlan90 lease-time=12h name=\
dhcp-v90
add address-pool=pool-v99 comment=MGMT interface=vlan99 lease-time=1d name=\
dhcp-v99
/system logging action
add disk-file-name=wan-test disk-lines-per-file=2000 name=wantest target=disk
/system script
add dont-require-permissions=no name=wantest-probe owner=admin policy=\
read,write,policy,test source=" :local ts ([/system clock get date] . \" \
\" . [/system clock get time])\
\n :local e1stat \"\?\"\
\n :do { :set e1stat [/ip dhcp-client get [find interface=ether1] status]\
\_} on-error={}\
\n :local e1addr \"-\"\
\n :do { :set e1addr [/ip dhcp-client get [find interface=ether1] address\
] } on-error={}\
\n :local e1mac [/interface ethernet get [find name=ether1] mac-address]\
\n :log info (\"WANTEST [\" . \$ts . \"] ether1 status=\" . \$e1stat . \"\
\_addr=\" . \$e1addr . \" mac=\" . \$e1mac)\
\n :local gw \"-\"\
\n :do { :set gw [/ip route get [find dst-address=\"0.0.0.0/0\" active=ye\
s] gateway] } on-error={}\
\n :log info (\"WANTEST route default-gw=\" . \$gw)\
\n # WAN-Routing+NAT: Router -> public 1.1.1.1 (UDP/53). UNABH\C3\84NGIG \
von ap1-DNS-Config.\
\n # (ICMP/HTTPS sind hier geblockt -> :resolve gegen feste IP ist das ro\
buste Signal.)\
\n :do { :local w [:resolve \"google.com\" server=1.1.1.1] ; :log info (\
\"WANTEST wan-reach via-1.1.1.1 ok google.com=\" . \$w) } on-error={ :log \
info \"WANTEST wan-reach via-1.1.1.1 FAIL (Routing/NAT\?)\" }\
\n # DoH end-to-end: ap1-Resolver = was die Clients als DNS bekommen\
\n :do { :local d [:resolve \"google.com\"] ; :log info (\"WANTEST dns-do\
h ok google.com=\" . \$d) } on-error={ :log info \"WANTEST dns-doh FAIL (D\
oH/Bootstrap\?)\" }"
add dont-require-permissions=no name=wantest-run owner=admin policy=\
read,write,policy,test source=" :global WTN\
\n :if (([:typeof \$WTN] = \"nothing\") or (\$WTN = \"\")) do={ :set WTN \
24 }\
\n :log info (\"WANTEST run start (\" . \$WTN . \"x @15s, ~\" . (\$WTN * \
15 / 60) . \" min)\")\
\n :for i from=1 to=\$WTN do={\
\n /system script run wantest-probe\
\n :delay 15s\
\n }\
\n :log info \"WANTEST run done\""
add dont-require-permissions=no name=wanmac-clone owner=admin policy=\
read,write,policy,test source=" :global FBMAC\
\n :if (([:typeof \$FBMAC] = \"nothing\") or (\$FBMAC = \"\")) do={ :set \
FBMAC \"0C:72:74:36:90:99\" }\
\n :global E1ORIG\
\n :set E1ORIG [/interface ethernet get [find name=ether1] mac-address]\
\n :log info (\"WANTEST macclone: orig=\" . \$E1ORIG . \" -> fb=\" . \$FB\
MAC . \" (Auto-Revert in ~90s)\")\
\n /interface ethernet set [find name=ether1] mac-address=\$FBMAC\
\n :do { /ip dhcp-client release [find interface=ether1] } on-error={}\
\n :delay 2s\
\n :do { /ip dhcp-client renew [find interface=ether1] } on-error={}\
\n :delay 25s\
\n :for i from=1 to=4 do={ /system script run wantest-probe ; :delay 15s \
}\
\n # --- garantierter Auto-Revert im selben Lauf (kein Scheduler n\C3\B6t\
ig) ---\
\n /interface ethernet reset-mac-address [find name=ether1]\
\n :do { /ip dhcp-client release [find interface=ether1] } on-error={}\
\n :delay 2s\
\n :do { /ip dhcp-client renew [find interface=ether1] } on-error={}\
\n :delay 15s\
\n /system script run wantest-probe\
\n :log info (\"WANTEST macclone done -> revert auf factory-MAC (orig war\
\_\" . \$E1ORIG . \")\")"
add dont-require-permissions=no name=wanmac-revert owner=admin policy=\
read,write,policy,test source=" /interface ethernet reset-mac-address [fi\
nd name=ether1]\
\n :do { /ip dhcp-client release [find interface=ether1] } on-error={}\
\n :delay 2s\
\n :do { /ip dhcp-client renew [find interface=ether1] } on-error={}\
\n :delay 10s\
\n /system script run wantest-probe\
\n :log info \"WANTEST macclone manual-revert -> factory-MAC\""
/disk settings
set auto-media-interface=bridge auto-media-sharing=yes auto-smb-sharing=yes
/interface bridge port
add bridge=bridge comment=defconf interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
add bridge=bridge comment=defconf interface=wifi2
add bridge=bridge interface=ether1
/interface bridge vlan
add bridge=bridge untagged=bridge,ether2 vlan-ids=1
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=10
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=20
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=30
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=40
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=50
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=90
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=99
add bridge=bridge tagged=bridge,ether2,ether1 vlan-ids=100
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add comment="WAN Arris via vlan100" interface=vlan100 list=WAN
/interface wifi access-list
add action=accept comment="pin P750W to ap1 (1/2): accept on ap1 iot" \
disabled=yes interface=w2-iot mac-address=4C:EB:BD:E3:25:F2
add action=reject comment=\
"pin P750W to ap1 (2/2): reject on any other AP incl dynamic ap2 VAPs" \
disabled=yes mac-address=4C:EB:BD:E3:25:F2
/interface wifi cap
set caps-man-addresses=10.40.41.1 discovery-interfaces=bridge
/interface wifi capsman
set enabled=yes interfaces=bridge
/interface wifi provisioning
add action=create-dynamic-enabled master-configuration=cfg-main-2g \
slave-configurations=cfg-iot,cfg-media,cfg-untrusted,cfg-guest,cfg-infra \
supported-bands=2ghz-ax
add action=create-dynamic-enabled master-configuration=cfg-main-5g \
slave-configurations=cfg-media,cfg-untrusted,cfg-guest,cfg-infra \
supported-bands=5ghz-ax
/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="
add allowed-address=10.95.10.0/24 comment=dw interface=wg-hub name=dw \
public-key="FqYZLztQ/qME5VDie5QLGH++5299WJiE1dPpQnPbzUw="
/ip address
add address=10.40.41.1/24 comment=defconf interface=bridge network=10.40.41.0
add address=10.40.10.1/24 comment="MAIN GW" interface=vlan10 network=\
10.40.10.0
add address=10.40.20.1/24 comment="INFRA GW" interface=vlan20 network=\
10.40.20.0
add address=10.40.30.1/24 comment="IOT GW" interface=vlan30 network=\
10.40.30.0
add address=10.40.40.1/24 comment="MEDIA GW" interface=vlan40 network=\
10.40.40.0
add address=10.40.50.1/24 comment="UNTRUSTED GW" interface=vlan50 network=\
10.40.50.0
add address=10.40.90.1/24 comment="GUEST GW" interface=vlan90 network=\
10.40.90.0
add address=10.40.99.1/24 comment="MGMT GW" interface=vlan99 network=\
10.40.99.0
add address=10.40.41.254/24 comment="Secondary = alte FB-GW-IP; haelt statisch\
e .41-Hosts online nach Arris-Swap (ap1 NATs + WG-Hub)" interface=bridge \
network=10.40.41.0
/ip dhcp-client
add comment=defconf disabled=yes interface=ether1 name=client1 use-peer-dns=\
no
add comment="WAN Arris DHCP (Liwest) via vlan100" interface=vlan100 name=\
client2 use-peer-dns=no use-peer-ntp=no
/ip dhcp-server lease
add address=10.40.10.82 client-id=1:56:71:6c:22:e6:a9 dhcp-option=\
"dns 1.1.1.1" mac-address=56:71:6C:22:E6:A9 server=dhcp-v10
add address=10.40.10.196 client-id=1:f2:62:4c:e1:af:9 mac-address=\
F2:62:4C:E1:AF:09 server=dhcp-v10
add address=10.40.40.199 client-id=1:48:a6:b8:b:63:10 mac-address=\
48:A6:B8:0B:63:10 server=dhcp-v40
add address=10.40.40.191 client-id=1:34:7e:5c:32:37:96 mac-address=\
34:7E:5C:32:37:96 server=dhcp-v40
add address=10.40.40.192 client-id=1:34:7e:5c:32:33:b8 mac-address=\
34:7E:5C:32:33:B8 server=dhcp-v40
add address=10.40.40.193 client-id=1:78:28:ca:80:2a:f6 mac-address=\
78:28:CA:80:2A:F6 server=dhcp-v40
add address=10.40.40.195 client-id=1:78:28:ca:82:16:c2 mac-address=\
78:28:CA:82:16:C2 server=dhcp-v40
add address=10.40.40.201 client-id=1:94:9f:3e:49:59:ee mac-address=\
94:9F:3E:49:59:EE server=dhcp-v40
add address=10.40.40.196 client-id=1:48:a6:b8:16:38:ae mac-address=\
48:A6:B8:16:38:AE server=dhcp-v40
add address=10.40.40.197 client-id=1:48:a6:b8:14:fe:f2 mac-address=\
48:A6:B8:14:FE:F2 server=dhcp-v40
add address=10.40.40.200 client-id=1:48:a6:b8:69:69:7b mac-address=\
48:A6:B8:69:69:7B server=dhcp-v40
add address=10.40.40.194 client-id=1:48:a6:b8:14:fe:d0 mac-address=\
48:A6:B8:14:FE:D0 server=dhcp-v40
add address=10.40.40.198 comment=SonosTerrasse mac-address=78:28:CA:D2:0D:AC \
server=dhcp-v40
add address=10.40.30.202 comment=shelly-s22_kueche_steckdose3-2 mac-address=\
A0:85:E3:C8:65:34 server=dhcp-v30
add address=10.40.30.203 comment=shelly-s23_dieleug-wohnzimmer_licht \
mac-address=AC:15:18:7B:62:20 server=dhcp-v30
add address=10.40.30.205 comment=shelly-s25_bad_lichtschalter mac-address=\
98:A3:16:79:38:50 server=dhcp-v30
add address=10.40.30.206 comment=shelly-s20_kueche_steckdosen2 mac-address=\
98:A3:16:7C:5F:EC server=dhcp-v30
add address=10.40.30.207 comment=shelly-s21_kueche_steckdosen4 mac-address=\
20:6E:F1:01:F9:F8 server=dhcp-v30
add address=10.40.30.208 comment=shelly-s1_weihnachten_kueche mac-address=\
E4:B0:63:D7:C7:A4 server=dhcp-v30
add address=10.40.30.209 comment=shelly-s2_weihnachten_terrasse mac-address=\
28:37:2F:36:F4:7C server=dhcp-v30
add address=10.40.30.210 comment=shelly-s3_weihnachten_kinderzimmer \
mac-address=E4:B0:63:E4:EF:7C server=dhcp-v30
add address=10.40.30.211 comment=shelly-s4_kueche_mikrowelle mac-address=\
E4:B0:63:E4:0F:30 server=dhcp-v30
add address=10.40.30.212 comment=shelly-s5_kueche_backofen mac-address=\
D8:85:AC:0C:5C:C8 server=dhcp-v30
add address=10.40.30.213 comment=shelly-s6_kueche_kuehlschrank mac-address=\
D0:CF:13:D8:18:FC server=dhcp-v30
add address=10.40.30.214 comment=shelly-s7_kueche_tiefkuehlschrank \
mac-address=D0:CF:13:D9:94:E8 server=dhcp-v30
add address=10.40.30.215 comment=shelly-s8_kueche_geschirrspueler \
mac-address=E4:B0:63:FA:FD:E0 server=dhcp-v30
add address=10.40.30.216 comment=shelly-s9_wohnzimmer_sideboard mac-address=\
E8:F6:0A:61:88:08 server=dhcp-v30
add address=10.40.30.217 comment=shelly-s10_bad_sonos mac-address=\
E4:B0:63:FC:57:E4 server=dhcp-v30
add address=10.40.30.218 comment=shelly-s11_kinderzimmer_sonos mac-address=\
E4:B0:63:FA:6C:00 server=dhcp-v30
add address=10.40.30.219 comment=shelly-s12_dieleug_steckdosen mac-address=\
48:F6:EE:C8:E6:AC server=dhcp-v30
add address=10.40.30.220 comment=shelly-s13_arbeitszimmer_technik \
mac-address=48:F6:EE:DD:6A:F4 server=dhcp-v30
add address=10.40.30.221 comment=shelly-s14_schlafzimmer_bett mac-address=\
E4:B0:63:FC:59:48 server=dhcp-v30
add address=10.40.30.222 comment=shelly-s15_technik_pve mac-address=\
E4:B0:63:FA:D5:34 server=dhcp-v30
add address=10.40.30.223 comment=shelly-s16_wohnzimmer_steckdosen \
mac-address=10:20:BA:FA:F5:40 server=dhcp-v30
add address=10.40.30.224 comment=shelly-s17_bad_steckdosen mac-address=\
10:20:BA:FB:6D:64 server=dhcp-v30
add address=10.40.30.225 comment=shelly-s18_kueche_steckdosen1 mac-address=\
48:F6:EE:CC:16:E4 server=dhcp-v30
add address=10.40.30.226 comment=shelly-s19_kueche_steckdosen3 mac-address=\
10:20:BA:FB:70:FC server=dhcp-v30
add address=10.40.30.227 comment=switchbot-floorlamp mac-address=\
B8:F8:62:09:F2:04 server=dhcp-v30
add address=10.40.30.228 comment=Twinkly_Weihnachtsgirlande mac-address=\
98:F4:AB:2C:A7:88 server=dhcp-v30
add address=10.40.30.230 comment=Withings_waage mac-address=00:24:E4:40:2A:72 \
server=dhcp-v30
add address=10.40.30.231 comment=Withings_blutdruck mac-address=\
A4:7E:FA:18:2C:64 server=dhcp-v30
add address=10.40.30.232 comment=pve-homematic-raspi-ccu mac-address=\
BC:24:11:8E:0A:57 server=dhcp-v30
add address=10.40.30.233 comment=shelly-s26_bad_luefter mac-address=\
98:A3:16:7A:A3:54 server=dhcp-v30
add address=10.40.30.236 comment=lichterkette mac-address=A4:F0:0F:5F:D0:EC \
server=dhcp-v30
add address=10.40.30.237 comment=lichterkette-mini mac-address=\
24:DC:C3:9B:89:64 server=dhcp-v30
add address=10.40.30.241 comment=NukiSmartlock mac-address=28:DB:A7:09:7B:54 \
server=dhcp-v30
add address=10.40.30.244 comment=NukiBridge mac-address=24:62:AB:B1:63:F4 \
server=dhcp-v30
add address=10.40.30.8 comment=DTUBI-414392337823 mac-address=\
54:F2:9F:12:51:F0 server=dhcp-v30
add address=10.40.20.10 comment=nas-bf mac-address=90:09:D0:58:20:F9 server=\
dhcp-v20
add address=10.40.40.11 comment=tv mac-address=70:AF:24:B8:C9:86 server=\
dhcp-v40
add address=10.40.30.5 comment=P750W mac-address=4C:EB:BD:E3:25:F2 server=\
dhcp-v30
add address=10.40.30.180 client-id=1:e4:bc:96:1f:b2:81 comment=Airfryer \
dhcp-option="dns 1.1.1.1" mac-address=E4:BC:96:1F:B2:81 server=dhcp-v30
add address=10.40.30.204 comment=shelly-s24_bad_spiegelschrank mac-address=\
14:33:5C:D8:2D:7C server=dhcp-v30
add address=10.40.30.150 client-id=1:fc:ee:11:3:32:26 comment=Ender3V3KE-3226 \
mac-address=FC:EE:11:03:32:26 server=dhcp-v30
/ip dhcp-server network
add address=10.40.10.0/24 comment=MAIN dns-server=10.40.10.1 gateway=\
10.40.10.1
add address=10.40.20.0/24 comment=INFRA dns-server=10.40.20.1 gateway=\
10.40.20.1
add address=10.40.30.0/24 comment=IOT dns-server=10.40.30.1 gateway=\
10.40.30.1
add address=10.40.40.0/24 comment=MEDIA dns-server=10.40.40.1 gateway=\
10.40.40.1
add address=10.40.41.0/24 comment=defconf dns-server=10.40.41.1 gateway=\
10.40.41.1 netmask=24
add address=10.40.50.0/24 comment=UNTRUSTED dns-server=10.40.50.1 gateway=\
10.40.50.1
add address=10.40.90.0/24 comment=GUEST dns-server=10.40.90.1 gateway=\
10.40.90.1
add address=10.40.99.0/24 comment=MGMT dhcp-option=omada-inform dns-server=\
10.40.99.1 gateway=10.40.99.1
/ip dns
set allow-remote-requests=yes mdns-repeat-ifaces=\
vlan10,vlan20,vlan40,vlan30,vlan90,bridge servers=1.1.1.1 use-doh-server=\
https://px35ynlol3.cloudflare-gateway.com/dns-query verify-doh-cert=yes
/ip dns static
add address=10.40.41.1 comment=defconf name=router.lan type=A
add address=10.40.41.2 comment=\
"TP4-transition; update to 10.40.99.2 after MGMT migration" name=\
ap2.bf.lan type=A
add address=10.40.41.11 comment="ALLNET core switch" name=sw1.bf.lan type=A
add address=10.40.41.12 comment="Omada access switch" name=sw2.bf.lan type=A
add address=10.40.20.167 comment=\
"Mac mini (INFRA VLAN20, migriert 2026-06-16)" name=macmini.bf.lan type=A
add address=10.40.20.100 comment="Proxmox hypervisor" name=pve.bf.lan type=A
add address=10.40.20.173 comment="pve-mcp SSE server" name=pve-mcp.bf.lan \
type=A
add address=10.40.20.10 comment=\
"DS923+ NAS (VLAN20, TP14.1, DNS-Sweep TP14.3 2026-07-16)" name=\
nas.bf.lan type=A
add address=10.40.20.126 comment=\
"Docker-LXC / Portainer (VLAN20, TP14.2, DNS-Sweep TP14.3 2026-07-16)" \
name=docker.bf.lan type=A
add address=10.40.99.1 comment=\
"TP19.1: ap1 MGMT = vlan99 GW (live since TP4), no separate move needed" \
name=ap1.bf.lan type=A
add address=10.40.20.20 comment=\
"TP20: Platform-Postgres LXC 105 on pve, PG16, nautobot DB" name=\
platform-pg.bf.lan type=A
/ip firewall filter
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
connection-state=established,related
add action=accept chain=forward comment=\
"defconf: accept established,related, untracked" connection-state=\
established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
connection-state=invalid
add action=drop chain=forward comment=\
"defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
in-interface-list=WAN
add action=accept chain=input comment=TP10-seal-est connection-state=\
established,related,untracked
add action=drop chain=input comment=TP10-seal-inv connection-state=invalid
add action=accept chain=input comment="TP10: WG hub listen (51821)" dst-port=\
51821 protocol=udp
add action=accept chain=forward comment="TP10: allow from WG spokes (FM/DW)" \
in-interface=wg-hub
add action=accept chain=forward comment="TP10: allow to WG spokes (FM/DW)" \
out-interface=wg-hub
add action=accept chain=input comment=TP10-seal-dhcp dst-port=68 \
in-interface-list=WAN protocol=udp
add action=accept chain=input comment=TP10-seal-icmp protocol=icmp
add action=accept chain=input comment=TP10-seal-lan in-interface-list=LAN
add action=drop chain=input comment=TP10-seal-wandrop in-interface-list=WAN
add action=accept chain=forward comment=\
"TP5: MAIN->MEDIA forward (AirPlay/Sonos)" in-interface=vlan10 \
out-interface=vlan40
add action=accept chain=forward comment=\
"TP5: MEDIA->MAIN forward (AirPlay/Sonos)" in-interface=vlan40 \
out-interface=vlan10
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan10 (repeater)" dst-port=5353 in-interface=\
vlan10 protocol=udp
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan40 (repeater)" dst-port=5353 in-interface=\
vlan40 protocol=udp
add action=accept chain=forward comment=\
"TP5: INFRA->MEDIA forward (HA<->Sonos)" in-interface=vlan20 \
out-interface=vlan40
add action=accept chain=forward comment=\
"TP5: MEDIA->INFRA forward (HA<->Sonos)" in-interface=vlan40 \
out-interface=vlan20
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan20 (repeater/HA)" dst-port=5353 in-interface=\
vlan20 protocol=udp
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan30 (repeater)" dst-port=5353 in-interface=\
vlan30 protocol=udp
add action=accept chain=input comment=\
"TP5: mDNS 5353 input vlan90 (repeater)" dst-port=5353 in-interface=\
vlan90 protocol=udp
add action=accept chain=forward comment=\
"TP5: GUEST->MEDIA forward (Sonos/Cast)" in-interface=vlan90 \
out-interface=vlan40
add action=accept chain=forward comment=\
"TP5: MEDIA->GUEST forward (Sonos/Cast)" in-interface=vlan40 \
out-interface=vlan90
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
ipsec-policy=out,none out-interface-list=WAN
add action=accept chain=srcnat comment=\
"TP4: no-NAT inter-VLAN (LAN-internal, before masquerade)" dst-address=\
10.40.0.0/16
add action=masquerade chain=srcnat comment="TP4: masquerade VLANs toward FB" \
disabled=yes out-interface=bridge
add action=masquerade chain=srcnat comment=\
"TP4: masquerade VLANs via ether1 (Liwest WAN)" disabled=yes \
out-interface=ether1
/ip route
add comment="TP10: FM spoke -> wg-hub" dst-address=10.101.0.0/24 gateway=\
wg-hub
add comment="TP10: DW spoke (kuenftig) -> wg-hub" dst-address=10.95.10.0/24 \
gateway=wg-hub
/ipv6 firewall address-list
add address=::/128 comment="defconf: unspecified address" list=bad_ipv6
add address=::1/128 comment="defconf: lo" list=bad_ipv6
add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6
add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6
add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6
add address=100::/64 comment="defconf: discard only " list=bad_ipv6
add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6
add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6
add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6
/ipv6 firewall filter
add action=accept chain=input comment=\
"defconf: accept established,related,untracked" connection-state=\
established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
invalid
add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\
icmpv6
add action=accept chain=input comment="defconf: accept UDP traceroute" \
dst-port=33434-33534 protocol=udp
add action=accept chain=input comment=\
"defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\
udp src-address=fe80::/10
add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \
protocol=udp
add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\
ipsec-ah
add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\
ipsec-esp
add action=accept chain=input comment=\
"defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=input comment=\
"defconf: drop everything else not coming from LAN" in-interface-list=\
!LAN
add action=fasttrack-connection chain=forward comment="defconf: fasttrack6" \
connection-state=established,related
add action=accept chain=forward comment=\
"defconf: accept established,related,untracked" connection-state=\
established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
connection-state=invalid
add action=drop chain=forward comment=\
"defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6
add action=drop chain=forward comment=\
"defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6
add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \
hop-limit=equal:1 protocol=icmpv6
add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\
icmpv6
add action=accept chain=forward comment="defconf: accept HIP" protocol=139
add action=accept chain=forward comment="defconf: accept IKE" dst-port=\
500,4500 protocol=udp
add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\
ipsec-ah
add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\
ipsec-esp
add action=accept chain=forward comment=\
"defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=forward comment=\
"defconf: drop everything else not coming from LAN" in-interface-list=\
!LAN
/system clock
set time-zone-name=Europe/Vienna
/system identity
set name=ap1
/system logging
add action=wantest topics=script

View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""Lade die staged L3-Cutover-Config auf crs326-core (noch NICHT enablen).
Creds aus ~/.claude.json. Alle operativen Objekte in der rsc sind disabled=yes,
also bleibt der aktive Datenpfad unberührt.
"""
import json
import pathlib
import subprocess
import sys
CORE_IP = "10.40.41.211"
RSC = pathlib.Path(__file__).with_name("tp15-core-cutover-intended.rsc")
CLAUDE_JSON = pathlib.Path.home() / ".claude.json"
def load_core_creds():
cfg = json.loads(CLAUDE_JSON.read_text())
env = cfg.get("mcpServers", {}).get("mikromcp", {}).get("env", {})
user = env.get("CRS326_CORE_USER") or env.get("ROUTER_USER")
pw = env.get("CRS326_CORE_PASS") or env.get("ROUTER_PASS")
if not user or not pw:
raise SystemExit("CRS326_CORE_USER/PASS nicht in ~/.claude.json mikromcp.env gefunden")
return user, pw
def ssh_base(user, pw):
return [
"sshpass", "-p", pw,
"ssh",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{CORE_IP}",
]
def run_silent(base, cmd):
r = subprocess.run(base + [cmd], capture_output=True, text=True)
if r.returncode != 0:
out = (r.stdout + r.stderr).replace(pw, "***")
raise SystemExit(f"Befehl fehlgeschlagen (rc={r.returncode}):\n{out}")
return r
def main():
if not RSC.exists():
raise SystemExit(f"{RSC} fehlt")
user, pw = load_core_creds()
base = ssh_base(user, pw)
print(f"crs326-core L3-Cutover-Config laden ({RSC.name}) ...")
# 1) Datei auf Router kopieren
r = subprocess.run(
["sshpass", "-p", pw,
"scp",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
str(RSC),
f"{user}@{CORE_IP}:{RSC.name}"],
capture_output=True, text=True,
)
if r.returncode != 0:
raise SystemExit(f"SCP fehlgeschlagen: {r.stderr.replace(pw, '***')}")
# 2) Import auslösen
run_silent(base, f'/import file-name="{RSC.name}"')
print(" Import abgeschlossen (staged / disabled).")
print(" Nächster Schritt: L2-Portplan + Cutover-Enable.")
if __name__ == "__main__":
main()

91
routeros/backup-ap1.py Normal file
View File

@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""Erstelle ein Binary-Backup + einen Text-Export von ap1 vor dem TP15-Cutover.
Creds aus ~/.claude.json (mikromcp-env). Backup-Dateien landen unter routeros/.
"""
import json
import pathlib
import subprocess
import sys
from datetime import datetime, timezone
AP1_IP = "10.40.10.1"
CLAUDE_JSON = pathlib.Path.home() / ".claude.json"
OUT_DIR = pathlib.Path(__file__).resolve().parent
def load_ap1_creds():
cfg = json.loads(CLAUDE_JSON.read_text())
env = cfg.get("mcpServers", {}).get("mikromcp", {}).get("env", {})
user = env.get("ROUTER_AP1_USER") or env.get("ROUTER_USER")
pw = env.get("ROUTER_AP1_PASS") or env.get("ROUTER_PASS")
if not user or not pw:
raise SystemExit("ROUTER_AP1_USER/PASS nicht in ~/.claude.json mikromcp.env gefunden")
return user, pw
def ssh_cmd(user, pw, remote_command):
return [
"sshpass", "-p", pw,
"ssh",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{AP1_IP}",
remote_command,
]
def scp_cmd(user, pw, remote_file, local_file):
return [
"sshpass", "-p", pw,
"scp",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{AP1_IP}:{remote_file}",
str(local_file),
]
def main():
user, pw = load_ap1_creds()
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
backup_name = f"ap1-pre-core-cutover-{ts}"
print(f"ap1 Backup via SSH {user}@{AP1_IP}")
# 1) Binary backup + Text-Export auf ap1 erzeugen
create_cmd = ssh_cmd(
user, pw,
f'/system backup save name="{backup_name}" dont-encrypt=yes; '
f'/export file="{backup_name}"'
)
print(f" Erzeuge Backup/Export auf ap1 ...")
subprocess.run(create_cmd, check=True)
# 2) Herunterladen
local_backup = OUT_DIR / f"{backup_name}.backup"
local_export = OUT_DIR / f"{backup_name}.rsc"
print(f" Lade {backup_name}.backup herunter ...")
subprocess.run(scp_cmd(user, pw, f"{backup_name}.backup", local_backup), check=True)
print(f" Lade {backup_name}.rsc herunter ...")
subprocess.run(scp_cmd(user, pw, f"{backup_name}.rsc", local_export), check=True)
# 3) Verifizieren
backup_size = local_backup.stat().st_size
export_size = local_export.stat().st_size
print(f" OK: {local_backup.name} ({backup_size} Bytes)")
print(f" OK: {local_export.name} ({export_size} Bytes)")
if backup_size < 1000:
print(" WARN: Backup-Datei auffällig klein!")
sys.exit(1)
print("\nNächster Schritt: Cutover-Config auf crs326-core laden.")
if __name__ == "__main__":
main()

86
routeros/backup-core.py Normal file
View File

@@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""Erstelle ein Binary-Backup + einen Text-Export von crs326-core vor dem TP15-Cutover.
Creds aus ~/.claude.json (mikromcp-env, CRS326_CORE_*). Backup-Dateien landen unter routeros/.
"""
import json
import pathlib
import subprocess
import sys
from datetime import datetime, timezone
CORE_IP = "10.40.41.211" # VLAN1-Temp; alternativ 10.40.99.11 sobald 99T auf Uplink
CLAUDE_JSON = pathlib.Path.home() / ".claude.json"
OUT_DIR = pathlib.Path(__file__).resolve().parent
def load_core_creds():
cfg = json.loads(CLAUDE_JSON.read_text())
env = cfg.get("mcpServers", {}).get("mikromcp", {}).get("env", {})
user = env.get("CRS326_CORE_USER") or env.get("ROUTER_USER")
pw = env.get("CRS326_CORE_PASS") or env.get("ROUTER_PASS")
if not user or not pw:
raise SystemExit("CRS326_CORE_USER/PASS nicht in ~/.claude.json mikromcp.env gefunden")
return user, pw
def ssh_cmd(user, pw, remote_command):
return [
"sshpass", "-p", pw,
"ssh",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{CORE_IP}",
remote_command,
]
def scp_cmd(user, pw, remote_file, local_file):
return [
"sshpass", "-p", pw,
"scp",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{CORE_IP}:{remote_file}",
str(local_file),
]
def main():
user, pw = load_core_creds()
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
backup_name = f"crs326-core-pre-cutover-{ts}"
print(f"crs326-core Backup via SSH {user}@{CORE_IP}")
create_cmd = ssh_cmd(
user, pw,
f'/system backup save name="{backup_name}" dont-encrypt=yes; '
f'/export file="{backup_name}"'
)
print(f" Erzeuge Backup/Export auf crs326-core ...")
subprocess.run(create_cmd, check=True)
local_backup = OUT_DIR / f"{backup_name}.backup"
local_export = OUT_DIR / f"{backup_name}.rsc"
print(f" Lade {backup_name}.backup herunter ...")
subprocess.run(scp_cmd(user, pw, f"{backup_name}.backup", local_backup), check=True)
print(f" Lade {backup_name}.rsc herunter ...")
subprocess.run(scp_cmd(user, pw, f"{backup_name}.rsc", local_export), check=True)
backup_size = local_backup.stat().st_size
export_size = local_export.stat().st_size
print(f" OK: {local_backup.name} ({backup_size} Bytes)")
print(f" OK: {local_export.name} ({export_size} Bytes)")
if backup_size < 1000:
print(" WARN: Backup-Datei auffällig klein!")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Konvertiert ap1-leases-export.json in RouterOS-Befehle für crs326-core.
Nur dynamic=false-Leases werden übernommen, mit server-Namen 1:1 übernommen
(dhcp-v10..dhcp-v99), disabled=yes, damit sie im Cutover zusammen mit den
DHCP-Servern enabled werden.
Ausgabe: routeros/ap1-leases-to-core.rsc
"""
import json
import pathlib
import shlex
LEASES = pathlib.Path(__file__).with_name("ap1-leases-export.json")
OUT = pathlib.Path(__file__).with_name("ap1-leases-to-core.rsc")
def escape(s):
# RouterOS comment darf Leerzeichen enthalten; wir quotieren mit doppelten Anführungszeichen
return s.replace('\\', '\\\\').replace('"', '\\"')
def main():
leases = json.loads(LEASES.read_text())
static = [l for l in leases if str(l.get("dynamic")).lower() == "false"]
lines = [
"# ap1 static leases -> crs326-core (STAGED, disabled=yes)",
f"# Quelle: {LEASES.name} | {len(static)} statische Leases",
"",
]
for l in sorted(static, key=lambda x: (x.get("server", ""), x.get("address", ""))):
server = l.get("server", "")
if not server.startswith("dhcp-v"):
lines.append(f"# SKIP unbekannter server '{server}': {l.get('address')} {l.get('mac-address')}")
continue
mac = l.get("mac-address", "")
addr = l.get("address", "")
client_id = l.get("client-id", "")
hostname = l.get("host-name", "")
dhcp_option = l.get("dhcp-option", "")
comment_parts = [hostname, l.get("comment", "")]
comment = " / ".join(p for p in comment_parts if p).strip()
if not comment:
comment = f"lease {addr}"
cmd = f'/ip/dhcp-server/lease add server={server} mac-address="{mac}" address="{addr}"'
if client_id:
cmd += f' client-id="{client_id}"'
if dhcp_option:
cmd += f' dhcp-option={shlex.quote(dhcp_option)}'
cmd += f' comment="{escape(comment)}" disabled=yes'
lines.append(cmd)
lines.append("")
lines.append("# Cutover: /ip/dhcp-server/lease/enable [find comment~\"ap1 lease\"]")
OUT.write_text("\n".join(lines) + "\n")
print(f"{OUT} written with {len(static)} static lease commands")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,92 @@
# 2025-09-04 23:25:19 by RouterOS 7.19.5
# software id = 4W04-URHT
#
# model = CRS326-24G-2S+
# serial number = HKA0AREXJFM
/interface bridge
add admin-mac=04:F4:1C:B4:17:76 auto-mac=no comment=defconf name=bridge \
vlan-filtering=yes
/interface ethernet
set [ find default-name=ether3 ] disabled=yes
set [ find default-name=ether4 ] disabled=yes
set [ find default-name=ether5 ] disabled=yes
set [ find default-name=ether6 ] disabled=yes
set [ find default-name=ether7 ] disabled=yes
set [ find default-name=ether8 ] disabled=yes
set [ find default-name=ether9 ] disabled=yes
set [ find default-name=ether10 ] disabled=yes
set [ find default-name=ether11 ] disabled=yes
set [ find default-name=ether12 ] disabled=yes
set [ find default-name=ether13 ] disabled=yes
set [ find default-name=ether14 ] disabled=yes
set [ find default-name=ether15 ] disabled=yes
set [ find default-name=ether16 ] disabled=yes
set [ find default-name=ether17 ] disabled=yes
set [ find default-name=ether18 ] disabled=yes
set [ find default-name=ether19 ] disabled=yes
set [ find default-name=ether20 ] disabled=yes
set [ find default-name=ether21 ] disabled=yes
set [ find default-name=ether22 ] disabled=yes
set [ find default-name=ether23 ] disabled=yes
set [ find default-name=ether24 ] disabled=yes
set [ find default-name=sfp-sfpplus1 ] disabled=yes
set [ find default-name=sfp-sfpplus2 ] disabled=yes
/interface vlan
add interface=bridge name=vlan99 vlan-id=99
/port
set 0 name=serial0
/interface bridge port
add bridge=bridge comment=defconf interface=ether1
add bridge=bridge comment=defconf interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
add bridge=bridge comment=defconf interface=ether6
add bridge=bridge comment=defconf interface=ether7
add bridge=bridge comment=defconf interface=ether8
add bridge=bridge comment=defconf interface=ether9
add bridge=bridge comment=defconf interface=ether10
add bridge=bridge comment=defconf interface=ether11
add bridge=bridge comment=defconf interface=ether12
add bridge=bridge comment=defconf interface=ether13
add bridge=bridge comment=defconf interface=ether14
add bridge=bridge comment=defconf interface=ether15
add bridge=bridge comment=defconf interface=ether16
add bridge=bridge comment=defconf interface=ether17
add bridge=bridge comment=defconf interface=ether18
add bridge=bridge comment=defconf interface=ether19
add bridge=bridge comment=defconf interface=ether20
add bridge=bridge comment=defconf interface=ether21
add bridge=bridge comment=defconf interface=ether22
add bridge=bridge comment=defconf interface=ether23
add bridge=bridge comment=defconf interface=ether24
add bridge=bridge comment=defconf interface=sfp-sfpplus1
add bridge=bridge comment=defconf interface=sfp-sfpplus2
/interface bridge vlan
add bridge=bridge untagged=ether1,ether2 vlan-ids=1
add bridge=bridge tagged=ether1,ether2 vlan-ids=10
add bridge=bridge tagged=ether1,ether2 vlan-ids=20
add bridge=bridge tagged=ether1,ether2 vlan-ids=30
add bridge=bridge tagged=ether1,ether2 vlan-ids=40
add bridge=bridge tagged=ether1,ether2 vlan-ids=50
add bridge=bridge tagged=ether1,ether2 vlan-ids=90
add bridge=bridge tagged=ether1,ether2,bridge vlan-ids=99
add bridge=bridge tagged=ether1,ether2 vlan-ids=100
/ip address
add address=10.40.41.211/24 comment=TP15-bringup-vlan1 interface=bridge \
network=10.40.41.0
add address=10.40.99.11/24 comment=TP15-mgmt-target interface=vlan99 network=\
10.40.99.0
/ip route
add comment=TP15-bringup dst-address=0.0.0.0/0 gateway=10.40.41.1
/ip service
set ftp disabled=yes
set ssh address=10.40.0.0/16
set telnet disabled=yes
set www address=10.40.0.0/16
set api address=10.40.0.0/16
set api-ssl disabled=yes
/system identity
set name=crs326-core
/system routerboard settings
set enter-setup-on=delete-key

View File

@@ -0,0 +1,314 @@
# 2025-09-05 02:45:12 by RouterOS 7.19.5
# software id = 4W04-URHT
#
# model = CRS326-24G-2S+
# serial number = HKA0AREXJFM
/interface bridge
set [find name=bridge] admin-mac=04:F4:1C:B4:17:76 auto-mac=no vlan-filtering=yes
/interface ethernet
set [ find default-name=sfp-sfpplus1 ] disabled=yes
set [ find default-name=sfp-sfpplus2 ] disabled=yes
/interface wireguard
add comment="TP10 Multi-Site VPN Hub (FM/DW spokes)" disabled=yes \
listen-port=51821 mtu=1412 name=wg-hub
/interface vlan
add comment=MAIN interface=bridge name=vlan10 vlan-id=10
add comment=INFRA interface=bridge name=vlan20 vlan-id=20
add comment=IOT interface=bridge name=vlan30 vlan-id=30
add comment=MEDIA interface=bridge name=vlan40 vlan-id=40
add comment=UNTRUSTED interface=bridge name=vlan50 vlan-id=50
add comment=GUEST interface=bridge name=vlan90 vlan-id=90
add interface=bridge name=vlan99 vlan-id=99
add comment=WAN interface=bridge name=vlan100 vlan-id=100
/interface list
add comment=TP15 name=WAN
add comment=TP15 name=LAN
/ip pool
add name=pool-v10 ranges=10.40.10.100-10.40.10.200
add name=pool-v20 ranges=10.40.20.100-10.40.20.200
add name=pool-v30 ranges=10.40.30.100-10.40.30.250
add name=pool-v40 ranges=10.40.40.100-10.40.40.200
add name=pool-v50 ranges=10.40.50.100-10.40.50.200
add name=pool-v90 ranges=10.40.90.100-10.40.90.200
add name=pool-v99 ranges=10.40.99.100-10.40.99.200
/ip dhcp-server
add address-pool=pool-v10 comment=MAIN disabled=yes interface=vlan10 \
lease-time=1d name=dhcp-v10
add address-pool=pool-v20 comment=INFRA disabled=yes interface=vlan20 \
lease-time=1d name=dhcp-v20
add address-pool=pool-v30 comment=IOT disabled=yes interface=vlan30 \
lease-time=1d name=dhcp-v30
add address-pool=pool-v40 comment=MEDIA disabled=yes interface=vlan40 \
lease-time=1d name=dhcp-v40
add address-pool=pool-v50 comment=UNTRUSTED disabled=yes interface=vlan50 \
lease-time=1d name=dhcp-v50
add address-pool=pool-v90 comment=GUEST disabled=yes interface=vlan90 \
lease-time=12h name=dhcp-v90
add address-pool=pool-v99 comment=MGMT disabled=yes interface=vlan99 \
lease-time=1d name=dhcp-v99
/port
set 0 name=serial0
/interface bridge port
set [find interface=ether2] pvid=40
set [find interface=ether3] pvid=40
set [find interface=ether5] pvid=40
/interface bridge vlan
add bridge=bridge untagged=ether1,ether2 vlan-ids=1
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=10
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=20
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=30
add bridge=bridge tagged=ether1,ether4,ether8 untagged=ether2,ether3,ether5 \
vlan-ids=40
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=50
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=90
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=99
add bridge=bridge tagged=ether1 untagged=ether16 vlan-ids=100
/interface list member
add interface=vlan100 list=WAN
add interface=vlan10 list=LAN
add interface=vlan20 list=LAN
add interface=vlan30 list=LAN
add interface=vlan40 list=LAN
add interface=vlan50 list=LAN
add interface=vlan90 list=LAN
add interface=vlan99 list=LAN
/interface wireguard peers
add allowed-address=10.101.0.0/24 endpoint-address=\
abxhutfgsid9snmy.myfritz.net endpoint-port=52476 interface=wg-hub name=fm \
public-key="dzRY0lnnUygijChWe5wXZmXPeNcbdALpqBptA3fyiVE="
add allowed-address=10.95.10.0/24 interface=wg-hub name=dw public-key=\
"FqYZLztQ/qME5VDie5QLGH++5299WJiE1dPpQnPbzUw="
/ip address
add address=10.40.41.211/24 comment=TP15-bringup-vlan1 interface=bridge \
network=10.40.41.0
add address=10.40.99.11/24 comment=TP15-mgmt-target interface=vlan99 network=\
10.40.99.0
add address=10.40.10.1/24 comment="L3 SVI VLAN10" disabled=yes interface=\
vlan10 network=10.40.10.0
add address=10.40.20.1/24 comment="L3 SVI VLAN20" disabled=yes interface=\
vlan20 network=10.40.20.0
add address=10.40.30.1/24 comment="L3 SVI VLAN30" disabled=yes interface=\
vlan30 network=10.40.30.0
add address=10.40.40.1/24 comment="L3 SVI VLAN40" disabled=yes interface=\
vlan40 network=10.40.40.0
add address=10.40.50.1/24 comment="L3 SVI VLAN50" disabled=yes interface=\
vlan50 network=10.40.50.0
add address=10.40.90.1/24 comment="L3 SVI VLAN90" disabled=yes interface=\
vlan90 network=10.40.90.0
add address=10.40.99.1/24 comment="Mgmt SVI (VLAN99)" disabled=yes interface=\
vlan99 network=10.40.99.0
/ip dhcp-client
add comment="TP15 WAN Liwest (Arris)" disabled=yes interface=vlan100 \
use-peer-dns=no
/ip dhcp-server lease
add address=10.40.10.196 client-id=1:f2:62:4c:e1:af:9 comment=iPhone \
disabled=yes mac-address=F2:62:4C:E1:AF:09 server=dhcp-v10
add address=10.40.20.10 comment=nas-bf disabled=yes mac-address=\
90:09:D0:58:20:F9 server=dhcp-v20
add address=10.40.30.150 client-id=1:fc:ee:11:3:32:26 comment=\
"ingenic-3226 / Ender3V3KE-3226" disabled=yes mac-address=\
FC:EE:11:03:32:26 server=dhcp-v30
add address=10.40.10.82 client-id=1:56:71:6c:22:e6:a9 comment=Mac disabled=\
yes mac-address=56:71:6C:22:E6:A9 server=dhcp-v10
add address=10.40.30.180 client-id=1:e4:bc:96:1f:b2:81 comment=\
"espressif / Airfryer" disabled=yes mac-address=E4:BC:96:1F:B2:81 server=\
dhcp-v30
add address=10.40.30.202 comment=shelly-s22_kueche_steckdose3-2 disabled=yes \
mac-address=A0:85:E3:C8:65:34 server=dhcp-v30
add address=10.40.30.203 comment=shelly-s23_dieleug-wohnzimmer_licht \
disabled=yes mac-address=AC:15:18:7B:62:20 server=dhcp-v30
add address=10.40.30.204 comment=shelly-s24_bad_spiegelschrank disabled=yes \
mac-address=14:33:5C:D8:2D:7C server=dhcp-v30
add address=10.40.30.205 comment=shelly-s25_bad_lichtschalter disabled=yes \
mac-address=98:A3:16:79:38:50 server=dhcp-v30
add address=10.40.30.206 comment=shelly-s20_kueche_steckdosen2 disabled=yes \
mac-address=98:A3:16:7C:5F:EC server=dhcp-v30
add address=10.40.30.207 comment=shelly-s21_kueche_steckdosen4 disabled=yes \
mac-address=20:6E:F1:01:F9:F8 server=dhcp-v30
add address=10.40.30.208 comment=shelly-s1_weihnachten_kueche disabled=yes \
mac-address=E4:B0:63:D7:C7:A4 server=dhcp-v30
add address=10.40.30.209 comment=shelly-s2_weihnachten_terrasse disabled=yes \
mac-address=28:37:2F:36:F4:7C server=dhcp-v30
add address=10.40.30.210 comment=shelly-s3_weihnachten_kinderzimmer disabled=\
yes mac-address=E4:B0:63:E4:EF:7C server=dhcp-v30
add address=10.40.30.211 comment=shelly-s4_kueche_mikrowelle disabled=yes \
mac-address=E4:B0:63:E4:0F:30 server=dhcp-v30
add address=10.40.30.212 comment=shelly-s5_kueche_backofen disabled=yes \
mac-address=D8:85:AC:0C:5C:C8 server=dhcp-v30
add address=10.40.30.213 comment=shelly-s6_kueche_kuehlschrank disabled=yes \
mac-address=D0:CF:13:D8:18:FC server=dhcp-v30
add address=10.40.30.214 comment=shelly-s7_kueche_tiefkuehlschrank disabled=\
yes mac-address=D0:CF:13:D9:94:E8 server=dhcp-v30
add address=10.40.30.215 comment=shelly-s8_kueche_geschirrspueler disabled=\
yes mac-address=E4:B0:63:FA:FD:E0 server=dhcp-v30
add address=10.40.30.216 comment=shelly-s9_wohnzimmer_sideboard disabled=yes \
mac-address=E8:F6:0A:61:88:08 server=dhcp-v30
add address=10.40.30.217 comment=shelly-s10_bad_sonos disabled=yes \
mac-address=E4:B0:63:FC:57:E4 server=dhcp-v30
add address=10.40.30.218 comment=shelly-s11_kinderzimmer_sonos disabled=yes \
mac-address=E4:B0:63:FA:6C:00 server=dhcp-v30
add address=10.40.30.219 comment=shelly-s12_dieleug_steckdosen disabled=yes \
mac-address=48:F6:EE:C8:E6:AC server=dhcp-v30
add address=10.40.30.220 comment=shelly-s13_arbeitszimmer_technik disabled=\
yes mac-address=48:F6:EE:DD:6A:F4 server=dhcp-v30
add address=10.40.30.221 comment=shelly-s14_schlafzimmer_bett disabled=yes \
mac-address=E4:B0:63:FC:59:48 server=dhcp-v30
add address=10.40.30.222 comment=shelly-s15_technik_pve disabled=yes \
mac-address=E4:B0:63:FA:D5:34 server=dhcp-v30
add address=10.40.30.223 comment=shelly-s16_wohnzimmer_steckdosen disabled=\
yes mac-address=10:20:BA:FA:F5:40 server=dhcp-v30
add address=10.40.30.224 comment=shelly-s17_bad_steckdosen disabled=yes \
mac-address=10:20:BA:FB:6D:64 server=dhcp-v30
add address=10.40.30.225 comment=shelly-s18_kueche_steckdosen1 disabled=yes \
mac-address=48:F6:EE:CC:16:E4 server=dhcp-v30
add address=10.40.30.226 comment=shelly-s19_kueche_steckdosen3 disabled=yes \
mac-address=10:20:BA:FB:70:FC server=dhcp-v30
add address=10.40.30.227 comment="SwitchBot-floor-lamp / switchbot-floorlamp" \
disabled=yes mac-address=B8:F8:62:09:F2:04 server=dhcp-v30
add address=10.40.30.228 comment=\
"Twinkly-2CA789 / Twinkly_Weihnachtsgirlande" disabled=yes mac-address=\
98:F4:AB:2C:A7:88 server=dhcp-v30
add address=10.40.30.230 comment=Withings_waage disabled=yes mac-address=\
00:24:E4:40:2A:72 server=dhcp-v30
add address=10.40.30.231 comment=Withings_blutdruck disabled=yes mac-address=\
A4:7E:FA:18:2C:64 server=dhcp-v30
add address=10.40.30.232 comment=pve-homematic-raspi-ccu disabled=yes \
mac-address=BC:24:11:8E:0A:57 server=dhcp-v30
add address=10.40.30.233 comment=shelly-s26_bad_luefter disabled=yes \
mac-address=98:A3:16:7A:A3:54 server=dhcp-v30
add address=10.40.30.236 comment=lichterkette disabled=yes mac-address=\
A4:F0:0F:5F:D0:EC server=dhcp-v30
add address=10.40.30.237 comment=lichterkette-mini disabled=yes mac-address=\
24:DC:C3:9B:89:64 server=dhcp-v30
add address=10.40.30.241 comment=NukiSmartlock disabled=yes mac-address=\
28:DB:A7:09:7B:54 server=dhcp-v30
add address=10.40.30.244 comment=NukiBridge disabled=yes mac-address=\
24:62:AB:B1:63:F4 server=dhcp-v30
add address=10.40.30.5 comment="P750W / P750W" disabled=yes mac-address=\
4C:EB:BD:E3:25:F2 server=dhcp-v30
add address=10.40.30.8 comment="DTUBI-414392337823 / DTUBI-414392337823" \
disabled=yes mac-address=54:F2:9F:12:51:F0 server=dhcp-v30
add address=10.40.40.11 comment=tv disabled=yes mac-address=70:AF:24:B8:C9:86 \
server=dhcp-v40
add address=10.40.40.191 client-id=1:34:7e:5c:32:37:96 comment=SonosZP \
disabled=yes mac-address=34:7E:5C:32:37:96 server=dhcp-v40
add address=10.40.40.192 client-id=1:34:7e:5c:32:33:b8 comment=SonosZP \
disabled=yes mac-address=34:7E:5C:32:33:B8 server=dhcp-v40
add address=10.40.40.193 client-id=1:78:28:ca:80:2a:f6 comment=SonosZP \
disabled=yes mac-address=78:28:CA:80:2A:F6 server=dhcp-v40
add address=10.40.40.194 client-id=1:48:a6:b8:14:fe:d0 comment=SonosZP \
disabled=yes mac-address=48:A6:B8:14:FE:D0 server=dhcp-v40
add address=10.40.40.195 client-id=1:78:28:ca:82:16:c2 comment=SonosZP \
disabled=yes mac-address=78:28:CA:82:16:C2 server=dhcp-v40
add address=10.40.40.196 client-id=1:48:a6:b8:16:38:ae comment=SonosZP \
disabled=yes mac-address=48:A6:B8:16:38:AE server=dhcp-v40
add address=10.40.40.197 client-id=1:48:a6:b8:14:fe:f2 comment=SonosZP \
disabled=yes mac-address=48:A6:B8:14:FE:F2 server=dhcp-v40
add address=10.40.40.198 comment="SonosZP / SonosTerrasse" disabled=yes \
mac-address=78:28:CA:D2:0D:AC server=dhcp-v40
add address=10.40.40.199 client-id=1:48:a6:b8:b:63:10 comment=SonosZP \
disabled=yes mac-address=48:A6:B8:0B:63:10 server=dhcp-v40
add address=10.40.40.200 client-id=1:48:a6:b8:69:69:7b comment=SonosZP \
disabled=yes mac-address=48:A6:B8:69:69:7B server=dhcp-v40
add address=10.40.40.201 client-id=1:94:9f:3e:49:59:ee comment=SonosZP \
disabled=yes mac-address=94:9F:3E:49:59:EE server=dhcp-v40
/ip dhcp-server network
add address=10.40.10.0/24 dns-server=10.40.10.1 domain=bf.lan gateway=\
10.40.10.1
add address=10.40.20.0/24 dns-server=10.40.20.1 domain=bf.lan gateway=\
10.40.20.1
add address=10.40.30.0/24 dns-server=10.40.30.1 domain=bf.lan gateway=\
10.40.30.1
add address=10.40.40.0/24 dns-server=10.40.40.1 domain=bf.lan gateway=\
10.40.40.1
add address=10.40.50.0/24 dns-server=10.40.50.1 domain=bf.lan gateway=\
10.40.50.1
add address=10.40.90.0/24 dns-server=10.40.90.1 domain=bf.lan gateway=\
10.40.90.1
add address=10.40.99.0/24 dns-server=10.40.99.1 domain=bf.lan gateway=\
10.40.99.1
/ip dns
set allow-remote-requests=yes mdns-repeat-ifaces=\
vlan10,vlan20,vlan40,vlan30,vlan90 servers=1.1.1.1 use-doh-server=\
https://px35ynlol3.cloudflare-gateway.com/dns-query verify-doh-cert=yes
/ip dns static
add address=10.40.99.1 comment="core = GW/Router" name=router.lan type=A
add address=10.40.99.3 comment="ap1 = reiner AP" name=ap1.bf.lan type=A
add address=10.40.99.2 comment="ap2 = reiner AP" name=ap2.bf.lan type=A
add address=10.40.99.1 comment="crs326-core (L3)" name=core.bf.lan type=A
add address=10.40.99.12 comment=crs326-branch name=branch.bf.lan type=A
add address=10.40.20.167 name=macmini.bf.lan type=A
add address=10.40.20.100 name=pve.bf.lan type=A
add address=10.40.20.173 name=pve-mcp.bf.lan type=A
add address=10.40.20.10 name=nas.bf.lan type=A
add address=10.40.20.126 name=docker.bf.lan type=A
add address=10.40.20.20 name=platform-pg.bf.lan type=A
/ip firewall filter
add action=accept chain=forward comment="defconf: accept est,rel,untracked" \
connection-state=established,related,untracked
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
connection-state=established,related hw-offload=yes
add action=drop chain=forward comment="defconf: drop invalid" \
connection-state=invalid
add action=drop chain=forward comment="defconf: drop WAN !dstnat" \
connection-nat-state=!dstnat in-interface-list=WAN
add action=accept chain=forward comment="TP10: allow from WG spokes (FM/DW)" \
in-interface=wg-hub
add action=accept chain=forward comment="TP10: allow to WG spokes (FM/DW)" \
out-interface=wg-hub
add action=accept chain=forward comment="TP5: MAIN->MEDIA" in-interface=\
vlan10 out-interface=vlan40
add action=accept chain=forward comment="TP5: MEDIA->MAIN" in-interface=\
vlan40 out-interface=vlan10
add action=accept chain=forward comment="TP5: INFRA->MEDIA" in-interface=\
vlan20 out-interface=vlan40
add action=accept chain=forward comment="TP5: MEDIA->INFRA" in-interface=\
vlan40 out-interface=vlan20
add action=accept chain=forward comment="TP5: GUEST->MEDIA" in-interface=\
vlan90 out-interface=vlan40
add action=accept chain=forward comment="TP5: MEDIA->GUEST" in-interface=\
vlan40 out-interface=vlan90
add action=accept chain=input comment=TP10-seal-est connection-state=\
established,related,untracked
add action=drop chain=input comment=TP10-seal-inv connection-state=invalid
add action=accept chain=input comment="TP10: WG hub listen" dst-port=51821 \
protocol=udp
add action=accept chain=input comment=TP10-seal-dhcp dst-port=68 \
in-interface-list=WAN protocol=udp
add action=accept chain=input comment=TP10-seal-icmp protocol=icmp
add action=accept chain=input comment=TP10-seal-lan in-interface-list=LAN
add action=drop chain=input comment=TP10-seal-wandrop in-interface-list=WAN
add action=accept chain=input comment="TP5: mDNS in vlan10" dst-port=5353 \
in-interface=vlan10 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan40" dst-port=5353 \
in-interface=vlan40 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan20" dst-port=5353 \
in-interface=vlan20 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan30" dst-port=5353 \
in-interface=vlan30 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan90" dst-port=5353 \
in-interface=vlan90 protocol=udp
/ip firewall nat
add action=accept chain=srcnat comment=\
"TP4: no-NAT inter-VLAN (vor masquerade)" dst-address=10.40.0.0/16
add action=masquerade chain=srcnat comment="defconf: masquerade WAN" \
out-interface-list=WAN
/ip hotspot profile
set [ find default=yes ] html-directory=hotspot
/ip route
add comment=TP15-bringup dst-address=0.0.0.0/0 gateway=10.40.41.1
add comment="TP10: FM spoke -> wg-hub" dst-address=10.101.0.0/24 gateway=\
wg-hub
add comment="TP10: DW spoke -> wg-hub" dst-address=10.95.10.0/24 gateway=\
wg-hub
/ip service
set ftp disabled=yes
set ssh address=10.40.0.0/16
set telnet disabled=yes
set www address=10.40.0.0/16
set api address=10.40.0.0/16
set api-ssl disabled=yes
/system identity
set name=crs326-core
/system routerboard settings
set enter-setup-on=delete-key

View File

@@ -0,0 +1,360 @@
# 2025-09-05 02:45:12 by RouterOS 7.19.5
# software id = 4W04-URHT
#
# model = CRS326-24G-2S+
# serial number = HKA0AREXJFM
/interface bridge
add admin-mac=04:F4:1C:B4:17:76 auto-mac=no comment=defconf name=bridge \
vlan-filtering=yes
/interface ethernet
set [ find default-name=ether3 ] disabled=yes
set [ find default-name=ether4 ] disabled=yes
set [ find default-name=ether5 ] disabled=yes
set [ find default-name=ether6 ] disabled=yes
set [ find default-name=ether7 ] disabled=yes
set [ find default-name=ether8 ] disabled=yes
set [ find default-name=ether9 ] disabled=yes
set [ find default-name=ether10 ] disabled=yes
set [ find default-name=ether11 ] disabled=yes
set [ find default-name=ether12 ] disabled=yes
set [ find default-name=ether13 ] disabled=yes
set [ find default-name=ether14 ] disabled=yes
set [ find default-name=ether15 ] disabled=yes
set [ find default-name=ether16 ] disabled=yes
set [ find default-name=ether17 ] disabled=yes
set [ find default-name=ether18 ] disabled=yes
set [ find default-name=ether19 ] disabled=yes
set [ find default-name=ether20 ] disabled=yes
set [ find default-name=ether21 ] disabled=yes
set [ find default-name=ether22 ] disabled=yes
set [ find default-name=ether23 ] disabled=yes
set [ find default-name=ether24 ] disabled=yes
set [ find default-name=sfp-sfpplus1 ] disabled=yes
set [ find default-name=sfp-sfpplus2 ] disabled=yes
/interface wireguard
add comment="TP10 Multi-Site VPN Hub (FM/DW spokes)" disabled=yes \
listen-port=51821 mtu=1412 name=wg-hub
/interface vlan
add comment=MAIN interface=bridge name=vlan10 vlan-id=10
add comment=INFRA interface=bridge name=vlan20 vlan-id=20
add comment=IOT interface=bridge name=vlan30 vlan-id=30
add comment=MEDIA interface=bridge name=vlan40 vlan-id=40
add comment=UNTRUSTED interface=bridge name=vlan50 vlan-id=50
add comment=GUEST interface=bridge name=vlan90 vlan-id=90
add interface=bridge name=vlan99 vlan-id=99
add comment=WAN interface=bridge name=vlan100 vlan-id=100
/interface list
add comment=TP15 name=WAN
add comment=TP15 name=LAN
/ip pool
add name=pool-v10 ranges=10.40.10.100-10.40.10.200
add name=pool-v20 ranges=10.40.20.100-10.40.20.200
add name=pool-v30 ranges=10.40.30.100-10.40.30.250
add name=pool-v40 ranges=10.40.40.100-10.40.40.200
add name=pool-v50 ranges=10.40.50.100-10.40.50.200
add name=pool-v90 ranges=10.40.90.100-10.40.90.200
add name=pool-v99 ranges=10.40.99.100-10.40.99.200
/ip dhcp-server
add address-pool=pool-v10 comment=MAIN disabled=yes interface=vlan10 \
lease-time=1d name=dhcp-v10
add address-pool=pool-v20 comment=INFRA disabled=yes interface=vlan20 \
lease-time=1d name=dhcp-v20
add address-pool=pool-v30 comment=IOT disabled=yes interface=vlan30 \
lease-time=1d name=dhcp-v30
add address-pool=pool-v40 comment=MEDIA disabled=yes interface=vlan40 \
lease-time=1d name=dhcp-v40
add address-pool=pool-v50 comment=UNTRUSTED disabled=yes interface=vlan50 \
lease-time=1d name=dhcp-v50
add address-pool=pool-v90 comment=GUEST disabled=yes interface=vlan90 \
lease-time=12h name=dhcp-v90
add address-pool=pool-v99 comment=MGMT disabled=yes interface=vlan99 \
lease-time=1d name=dhcp-v99
/port
set 0 name=serial0
/interface bridge port
add bridge=bridge comment=defconf interface=ether1
add bridge=bridge comment=defconf interface=ether2 pvid=40
add bridge=bridge comment=defconf interface=ether3 pvid=40
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5 pvid=40
add bridge=bridge comment=defconf interface=ether6
add bridge=bridge comment=defconf interface=ether7
add bridge=bridge comment=defconf interface=ether8
add bridge=bridge comment=defconf interface=ether9
add bridge=bridge comment=defconf interface=ether10
add bridge=bridge comment=defconf interface=ether11
add bridge=bridge comment=defconf interface=ether12
add bridge=bridge comment=defconf interface=ether13
add bridge=bridge comment=defconf interface=ether14
add bridge=bridge comment=defconf interface=ether15
add bridge=bridge comment=defconf interface=ether16
add bridge=bridge comment=defconf interface=ether17
add bridge=bridge comment=defconf interface=ether18
add bridge=bridge comment=defconf interface=ether19
add bridge=bridge comment=defconf interface=ether20
add bridge=bridge comment=defconf interface=ether21
add bridge=bridge comment=defconf interface=ether22
add bridge=bridge comment=defconf interface=ether23
add bridge=bridge comment=defconf interface=ether24
add bridge=bridge comment=defconf interface=sfp-sfpplus1
add bridge=bridge comment=defconf interface=sfp-sfpplus2
/interface bridge vlan
add bridge=bridge untagged=ether1,ether2 vlan-ids=1
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=10
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=20
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=30
add bridge=bridge tagged=ether1,ether4,ether8 untagged=ether2,ether3,ether5 \
vlan-ids=40
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=50
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=90
add bridge=bridge tagged=ether1,ether4,ether8 vlan-ids=99
add bridge=bridge tagged=ether1 untagged=ether16 vlan-ids=100
/interface list member
add interface=vlan100 list=WAN
add interface=vlan10 list=LAN
add interface=vlan20 list=LAN
add interface=vlan30 list=LAN
add interface=vlan40 list=LAN
add interface=vlan50 list=LAN
add interface=vlan90 list=LAN
add interface=vlan99 list=LAN
/interface wireguard peers
add allowed-address=10.101.0.0/24 endpoint-address=\
abxhutfgsid9snmy.myfritz.net endpoint-port=52476 interface=wg-hub name=fm \
public-key="dzRY0lnnUygijChWe5wXZmXPeNcbdALpqBptA3fyiVE="
add allowed-address=10.95.10.0/24 interface=wg-hub name=dw public-key=\
"FqYZLztQ/qME5VDie5QLGH++5299WJiE1dPpQnPbzUw="
/ip address
add address=10.40.41.211/24 comment=TP15-bringup-vlan1 interface=bridge \
network=10.40.41.0
add address=10.40.99.11/24 comment=TP15-mgmt-target interface=vlan99 network=\
10.40.99.0
add address=10.40.10.1/24 comment="L3 SVI VLAN10" disabled=yes interface=\
vlan10 network=10.40.10.0
add address=10.40.20.1/24 comment="L3 SVI VLAN20" disabled=yes interface=\
vlan20 network=10.40.20.0
add address=10.40.30.1/24 comment="L3 SVI VLAN30" disabled=yes interface=\
vlan30 network=10.40.30.0
add address=10.40.40.1/24 comment="L3 SVI VLAN40" disabled=yes interface=\
vlan40 network=10.40.40.0
add address=10.40.50.1/24 comment="L3 SVI VLAN50" disabled=yes interface=\
vlan50 network=10.40.50.0
add address=10.40.90.1/24 comment="L3 SVI VLAN90" disabled=yes interface=\
vlan90 network=10.40.90.0
add address=10.40.99.1/24 comment="Mgmt SVI (VLAN99)" disabled=yes interface=\
vlan99 network=10.40.99.0
/ip dhcp-client
add comment="TP15 WAN Liwest (Arris)" disabled=yes interface=vlan100 \
use-peer-dns=no
/ip dhcp-server lease
add address=10.40.10.196 client-id=1:f2:62:4c:e1:af:9 comment=iPhone \
disabled=yes mac-address=F2:62:4C:E1:AF:09 server=dhcp-v10
add address=10.40.20.10 comment=nas-bf disabled=yes mac-address=\
90:09:D0:58:20:F9 server=dhcp-v20
add address=10.40.30.150 client-id=1:fc:ee:11:3:32:26 comment=\
"ingenic-3226 / Ender3V3KE-3226" disabled=yes mac-address=\
FC:EE:11:03:32:26 server=dhcp-v30
add address=10.40.10.82 client-id=1:56:71:6c:22:e6:a9 comment=Mac disabled=\
yes mac-address=56:71:6C:22:E6:A9 server=dhcp-v10
add address=10.40.30.180 client-id=1:e4:bc:96:1f:b2:81 comment=\
"espressif / Airfryer" disabled=yes mac-address=E4:BC:96:1F:B2:81 server=\
dhcp-v30
add address=10.40.30.202 comment=shelly-s22_kueche_steckdose3-2 disabled=yes \
mac-address=A0:85:E3:C8:65:34 server=dhcp-v30
add address=10.40.30.203 comment=shelly-s23_dieleug-wohnzimmer_licht \
disabled=yes mac-address=AC:15:18:7B:62:20 server=dhcp-v30
add address=10.40.30.204 comment=shelly-s24_bad_spiegelschrank disabled=yes \
mac-address=14:33:5C:D8:2D:7C server=dhcp-v30
add address=10.40.30.205 comment=shelly-s25_bad_lichtschalter disabled=yes \
mac-address=98:A3:16:79:38:50 server=dhcp-v30
add address=10.40.30.206 comment=shelly-s20_kueche_steckdosen2 disabled=yes \
mac-address=98:A3:16:7C:5F:EC server=dhcp-v30
add address=10.40.30.207 comment=shelly-s21_kueche_steckdosen4 disabled=yes \
mac-address=20:6E:F1:01:F9:F8 server=dhcp-v30
add address=10.40.30.208 comment=shelly-s1_weihnachten_kueche disabled=yes \
mac-address=E4:B0:63:D7:C7:A4 server=dhcp-v30
add address=10.40.30.209 comment=shelly-s2_weihnachten_terrasse disabled=yes \
mac-address=28:37:2F:36:F4:7C server=dhcp-v30
add address=10.40.30.210 comment=shelly-s3_weihnachten_kinderzimmer disabled=\
yes mac-address=E4:B0:63:E4:EF:7C server=dhcp-v30
add address=10.40.30.211 comment=shelly-s4_kueche_mikrowelle disabled=yes \
mac-address=E4:B0:63:E4:0F:30 server=dhcp-v30
add address=10.40.30.212 comment=shelly-s5_kueche_backofen disabled=yes \
mac-address=D8:85:AC:0C:5C:C8 server=dhcp-v30
add address=10.40.30.213 comment=shelly-s6_kueche_kuehlschrank disabled=yes \
mac-address=D0:CF:13:D8:18:FC server=dhcp-v30
add address=10.40.30.214 comment=shelly-s7_kueche_tiefkuehlschrank disabled=\
yes mac-address=D0:CF:13:D9:94:E8 server=dhcp-v30
add address=10.40.30.215 comment=shelly-s8_kueche_geschirrspueler disabled=\
yes mac-address=E4:B0:63:FA:FD:E0 server=dhcp-v30
add address=10.40.30.216 comment=shelly-s9_wohnzimmer_sideboard disabled=yes \
mac-address=E8:F6:0A:61:88:08 server=dhcp-v30
add address=10.40.30.217 comment=shelly-s10_bad_sonos disabled=yes \
mac-address=E4:B0:63:FC:57:E4 server=dhcp-v30
add address=10.40.30.218 comment=shelly-s11_kinderzimmer_sonos disabled=yes \
mac-address=E4:B0:63:FA:6C:00 server=dhcp-v30
add address=10.40.30.219 comment=shelly-s12_dieleug_steckdosen disabled=yes \
mac-address=48:F6:EE:C8:E6:AC server=dhcp-v30
add address=10.40.30.220 comment=shelly-s13_arbeitszimmer_technik disabled=\
yes mac-address=48:F6:EE:DD:6A:F4 server=dhcp-v30
add address=10.40.30.221 comment=shelly-s14_schlafzimmer_bett disabled=yes \
mac-address=E4:B0:63:FC:59:48 server=dhcp-v30
add address=10.40.30.222 comment=shelly-s15_technik_pve disabled=yes \
mac-address=E4:B0:63:FA:D5:34 server=dhcp-v30
add address=10.40.30.223 comment=shelly-s16_wohnzimmer_steckdosen disabled=\
yes mac-address=10:20:BA:FA:F5:40 server=dhcp-v30
add address=10.40.30.224 comment=shelly-s17_bad_steckdosen disabled=yes \
mac-address=10:20:BA:FB:6D:64 server=dhcp-v30
add address=10.40.30.225 comment=shelly-s18_kueche_steckdosen1 disabled=yes \
mac-address=48:F6:EE:CC:16:E4 server=dhcp-v30
add address=10.40.30.226 comment=shelly-s19_kueche_steckdosen3 disabled=yes \
mac-address=10:20:BA:FB:70:FC server=dhcp-v30
add address=10.40.30.227 comment="SwitchBot-floor-lamp / switchbot-floorlamp" \
disabled=yes mac-address=B8:F8:62:09:F2:04 server=dhcp-v30
add address=10.40.30.228 comment=\
"Twinkly-2CA789 / Twinkly_Weihnachtsgirlande" disabled=yes mac-address=\
98:F4:AB:2C:A7:88 server=dhcp-v30
add address=10.40.30.230 comment=Withings_waage disabled=yes mac-address=\
00:24:E4:40:2A:72 server=dhcp-v30
add address=10.40.30.231 comment=Withings_blutdruck disabled=yes mac-address=\
A4:7E:FA:18:2C:64 server=dhcp-v30
add address=10.40.30.232 comment=pve-homematic-raspi-ccu disabled=yes \
mac-address=BC:24:11:8E:0A:57 server=dhcp-v30
add address=10.40.30.233 comment=shelly-s26_bad_luefter disabled=yes \
mac-address=98:A3:16:7A:A3:54 server=dhcp-v30
add address=10.40.30.236 comment=lichterkette disabled=yes mac-address=\
A4:F0:0F:5F:D0:EC server=dhcp-v30
add address=10.40.30.237 comment=lichterkette-mini disabled=yes mac-address=\
24:DC:C3:9B:89:64 server=dhcp-v30
add address=10.40.30.241 comment=NukiSmartlock disabled=yes mac-address=\
28:DB:A7:09:7B:54 server=dhcp-v30
add address=10.40.30.244 comment=NukiBridge disabled=yes mac-address=\
24:62:AB:B1:63:F4 server=dhcp-v30
add address=10.40.30.5 comment="P750W / P750W" disabled=yes mac-address=\
4C:EB:BD:E3:25:F2 server=dhcp-v30
add address=10.40.30.8 comment="DTUBI-414392337823 / DTUBI-414392337823" \
disabled=yes mac-address=54:F2:9F:12:51:F0 server=dhcp-v30
add address=10.40.40.11 comment=tv disabled=yes mac-address=70:AF:24:B8:C9:86 \
server=dhcp-v40
add address=10.40.40.191 client-id=1:34:7e:5c:32:37:96 comment=SonosZP \
disabled=yes mac-address=34:7E:5C:32:37:96 server=dhcp-v40
add address=10.40.40.192 client-id=1:34:7e:5c:32:33:b8 comment=SonosZP \
disabled=yes mac-address=34:7E:5C:32:33:B8 server=dhcp-v40
add address=10.40.40.193 client-id=1:78:28:ca:80:2a:f6 comment=SonosZP \
disabled=yes mac-address=78:28:CA:80:2A:F6 server=dhcp-v40
add address=10.40.40.194 client-id=1:48:a6:b8:14:fe:d0 comment=SonosZP \
disabled=yes mac-address=48:A6:B8:14:FE:D0 server=dhcp-v40
add address=10.40.40.195 client-id=1:78:28:ca:82:16:c2 comment=SonosZP \
disabled=yes mac-address=78:28:CA:82:16:C2 server=dhcp-v40
add address=10.40.40.196 client-id=1:48:a6:b8:16:38:ae comment=SonosZP \
disabled=yes mac-address=48:A6:B8:16:38:AE server=dhcp-v40
add address=10.40.40.197 client-id=1:48:a6:b8:14:fe:f2 comment=SonosZP \
disabled=yes mac-address=48:A6:B8:14:FE:F2 server=dhcp-v40
add address=10.40.40.198 comment="SonosZP / SonosTerrasse" disabled=yes \
mac-address=78:28:CA:D2:0D:AC server=dhcp-v40
add address=10.40.40.199 client-id=1:48:a6:b8:b:63:10 comment=SonosZP \
disabled=yes mac-address=48:A6:B8:0B:63:10 server=dhcp-v40
add address=10.40.40.200 client-id=1:48:a6:b8:69:69:7b comment=SonosZP \
disabled=yes mac-address=48:A6:B8:69:69:7B server=dhcp-v40
add address=10.40.40.201 client-id=1:94:9f:3e:49:59:ee comment=SonosZP \
disabled=yes mac-address=94:9F:3E:49:59:EE server=dhcp-v40
/ip dhcp-server network
add address=10.40.10.0/24 dns-server=10.40.10.1 domain=bf.lan gateway=\
10.40.10.1
add address=10.40.20.0/24 dns-server=10.40.20.1 domain=bf.lan gateway=\
10.40.20.1
add address=10.40.30.0/24 dns-server=10.40.30.1 domain=bf.lan gateway=\
10.40.30.1
add address=10.40.40.0/24 dns-server=10.40.40.1 domain=bf.lan gateway=\
10.40.40.1
add address=10.40.50.0/24 dns-server=10.40.50.1 domain=bf.lan gateway=\
10.40.50.1
add address=10.40.90.0/24 dns-server=10.40.90.1 domain=bf.lan gateway=\
10.40.90.1
add address=10.40.99.0/24 dns-server=10.40.99.1 domain=bf.lan gateway=\
10.40.99.1
/ip dns
set allow-remote-requests=yes mdns-repeat-ifaces=\
vlan10,vlan20,vlan40,vlan30,vlan90 servers=1.1.1.1 use-doh-server=\
https://px35ynlol3.cloudflare-gateway.com/dns-query verify-doh-cert=yes
/ip dns static
add address=10.40.99.1 comment="core = GW/Router" name=router.lan type=A
add address=10.40.99.3 comment="ap1 = reiner AP" name=ap1.bf.lan type=A
add address=10.40.99.2 comment="ap2 = reiner AP" name=ap2.bf.lan type=A
add address=10.40.99.1 comment="crs326-core (L3)" name=core.bf.lan type=A
add address=10.40.99.12 comment=crs326-branch name=branch.bf.lan type=A
add address=10.40.20.167 name=macmini.bf.lan type=A
add address=10.40.20.100 name=pve.bf.lan type=A
add address=10.40.20.173 name=pve-mcp.bf.lan type=A
add address=10.40.20.10 name=nas.bf.lan type=A
add address=10.40.20.126 name=docker.bf.lan type=A
add address=10.40.20.20 name=platform-pg.bf.lan type=A
/ip firewall filter
add action=accept chain=forward comment="defconf: accept est,rel,untracked" \
connection-state=established,related,untracked
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
connection-state=established,related hw-offload=yes
add action=drop chain=forward comment="defconf: drop invalid" \
connection-state=invalid
add action=drop chain=forward comment="defconf: drop WAN !dstnat" \
connection-nat-state=!dstnat in-interface-list=WAN
add action=accept chain=forward comment="TP10: allow from WG spokes (FM/DW)" \
in-interface=wg-hub
add action=accept chain=forward comment="TP10: allow to WG spokes (FM/DW)" \
out-interface=wg-hub
add action=accept chain=forward comment="TP5: MAIN->MEDIA" in-interface=\
vlan10 out-interface=vlan40
add action=accept chain=forward comment="TP5: MEDIA->MAIN" in-interface=\
vlan40 out-interface=vlan10
add action=accept chain=forward comment="TP5: INFRA->MEDIA" in-interface=\
vlan20 out-interface=vlan40
add action=accept chain=forward comment="TP5: MEDIA->INFRA" in-interface=\
vlan40 out-interface=vlan20
add action=accept chain=forward comment="TP5: GUEST->MEDIA" in-interface=\
vlan90 out-interface=vlan40
add action=accept chain=forward comment="TP5: MEDIA->GUEST" in-interface=\
vlan40 out-interface=vlan90
add action=accept chain=input comment=TP10-seal-est connection-state=\
established,related,untracked
add action=drop chain=input comment=TP10-seal-inv connection-state=invalid
add action=accept chain=input comment="TP10: WG hub listen" dst-port=51821 \
protocol=udp
add action=accept chain=input comment=TP10-seal-dhcp dst-port=68 \
in-interface-list=WAN protocol=udp
add action=accept chain=input comment=TP10-seal-icmp protocol=icmp
add action=accept chain=input comment=TP10-seal-lan in-interface-list=LAN
add action=drop chain=input comment=TP10-seal-wandrop in-interface-list=WAN
add action=accept chain=input comment="TP5: mDNS in vlan10" dst-port=5353 \
in-interface=vlan10 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan40" dst-port=5353 \
in-interface=vlan40 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan20" dst-port=5353 \
in-interface=vlan20 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan30" dst-port=5353 \
in-interface=vlan30 protocol=udp
add action=accept chain=input comment="TP5: mDNS in vlan90" dst-port=5353 \
in-interface=vlan90 protocol=udp
/ip firewall nat
add action=accept chain=srcnat comment=\
"TP4: no-NAT inter-VLAN (vor masquerade)" dst-address=10.40.0.0/16
add action=masquerade chain=srcnat comment="defconf: masquerade WAN" \
out-interface-list=WAN
/ip hotspot profile
set [ find default=yes ] html-directory=hotspot
/ip route
add comment=TP15-bringup dst-address=0.0.0.0/0 gateway=10.40.41.1
add comment="TP10: FM spoke -> wg-hub" dst-address=10.101.0.0/24 gateway=\
wg-hub
add comment="TP10: DW spoke -> wg-hub" dst-address=10.95.10.0/24 gateway=\
wg-hub
/ip service
set ftp disabled=yes
set ssh address=10.40.0.0/16
set telnet disabled=yes
set www address=10.40.0.0/16
set api address=10.40.0.0/16
set api-ssl disabled=yes
/system identity
set name=crs326-core
/system routerboard settings
set enter-setup-on=delete-key

View File

@@ -0,0 +1,119 @@
#!/usr/bin/env python3
"""Export ap1-Daten, die im crs326-core Cutover-Fenster gebraucht werden.
Ausgaben (ohne Secrets im stdout):
- routeros/ap1-leases-export.json : alle DHCP-Leases (static + dynamic)
- routeros/ap1-wg-hub.privkey : wg-hub private-key (nur diese Zeile)
- routeros/ap1-cutover-summary.txt : menschliche Zusammenfassung
Quelle: ap1 via REST (10.40.10.1), Creds aus ~/.claude.json (mikromcp-env).
"""
import base64
import json
import os
import pathlib
import sys
import urllib.request
import urllib.error
AP1_REST = "http://10.40.10.1/rest" # VLAN10 Mgmt-IP (ap1-Mgmt nur via VLAN10)
CLAUDE_JSON = pathlib.Path.home() / ".claude.json"
OUT_DIR = pathlib.Path(__file__).resolve().parent
def load_ap1_creds():
cfg = json.loads(CLAUDE_JSON.read_text())
env = cfg.get("mcpServers", {}).get("mikromcp", {}).get("env", {})
user = env.get("ROUTER_AP1_USER") or env.get("ROUTER_USER")
pw = env.get("ROUTER_AP1_PASS") or env.get("ROUTER_PASS")
if not user or not pw:
raise SystemExit("ROUTER_AP1_USER/PASS nicht in ~/.claude.json mikromcp.env gefunden")
return user, pw
def rest_get(path, user, pw):
url = f"{AP1_REST}{path}"
auth = base64.b64encode(f"{user}:{pw}".encode()).decode()
req = urllib.request.Request(url, headers={
"Authorization": f"Basic {auth}",
"Accept": "application/json",
})
try:
with urllib.request.urlopen(req, timeout=20) as resp:
raw = resp.read()
return json.loads(raw) if raw else []
except urllib.error.HTTPError as e:
sys.stderr.write(f"!! GET {url} -> {e.code} {e.read().decode()[:500]}\n")
raise
def main():
user, pw = load_ap1_creds()
print(f"ap1 REST {AP1_REST} (User: {user})")
# 1) DHCP-Leases
leases = rest_get("/ip/dhcp-server/lease", user, pw)
leases_path = OUT_DIR / "ap1-leases-export.json"
leases_path.write_text(json.dumps(leases, indent=2))
print(f" DHCP-Leases: {len(leases)} -> {leases_path}")
# 2) WG-Hub privkey (field may be redacted; fallback to script-run)
wg = rest_get("/interface/wireguard", user, pw)
hub = next((i for i in wg if i.get("name") == "wg-hub"), None)
privkey = ""
if hub:
privkey = hub.get("private-key") or ""
if not privkey:
# REST listet privkey manchmal nicht; über system/script ausgeben lassen
script = ':put [/interface/wireguard/get [find name="wg-hub"] private-key]'
try:
run_resp = rest_post("/system/script/run", {"source": script}, user, pw)
# output format variiert
privkey = str(run_resp).strip().strip('"')
except Exception as e:
sys.stderr.write(f" WG-Privkey-Fallback fehlgeschlagen: {e}\n")
wg_path = OUT_DIR / "ap1-wg-hub.privkey"
if privkey and privkey != "<<<none>>>":
wg_path.write_text(privkey + "\n")
print(f" WG-Hub Privkey -> {wg_path} ({len(privkey)} chars)")
else:
print(f" WARN: WG-Hub Privkey nicht ermittelt -> {wg_path} nicht geschrieben")
# 3) Zusammenfassung
summary = [
f"ap1 Cutover-Export vom {os.popen('date -Iseconds').read().strip()}",
f"DHCP-Leases gesamt: {len(leases)}",
f" statisch (dynamic=no): {sum(1 for l in leases if str(l.get('dynamic')).lower() == 'false')}",
f" dynamisch: {sum(1 for l in leases if str(l.get('dynamic')).lower() != 'false')}",
f"WG-Hub private-key erfasst: {'ja' if privkey else 'nein'}",
"",
"Nächste Schritte im Cutover-Fenster:",
"1. ap1-leases-export.json filtern: nur dynamic=no, server-Namen auf core dhcp-v10..v99 mappen.",
"2. ap1-wg-hub.privkey in core-Config einsetzen (ersetzt <<< AP1_WG_HUB_PRIVKEY >>>).",
"3. Generate Intended Config für crs326-core erneut laufen lassen -> Nautobot-Deployment.",
]
summary_path = OUT_DIR / "ap1-cutover-summary.txt"
summary_path.write_text("\n".join(summary) + "\n")
print(f" Summary -> {summary_path}")
def rest_post(path, data, user, pw):
url = f"{AP1_REST}{path}"
auth = base64.b64encode(f"{user}:{pw}".encode()).decode()
body = json.dumps(data).encode()
req = urllib.request.Request(url, data=body, headers={
"Authorization": f"Basic {auth}",
"Content-Type": "application/json",
"Accept": "application/json",
}, method="POST")
try:
with urllib.request.urlopen(req, timeout=20) as resp:
raw = resp.read()
return json.loads(raw) if raw else {}
except urllib.error.HTTPError as e:
sys.stderr.write(f"!! POST {url} -> {e.code} {e.read().decode()[:500]}\n")
raise
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""Holt crs326-core intended config aus Nautobot, setzt WG-Privkey,
fügt ap1 static leases hinzu, speichert als tp15-core-cutover-intended.rsc.
"""
import json
import pathlib
import re
import urllib.request
NAUTOBOT_URL = "http://10.40.20.30:8080"
TOKEN_PATH = pathlib.Path(__file__).parent.parent / "docs" / "nas-vlan20" / "stacks" / "210-nautobot.yml"
OUT = pathlib.Path(__file__).with_name("tp15-core-cutover-intended.rsc")
LEASES_RSC = pathlib.Path(__file__).with_name("ap1-leases-to-core.rsc")
PRIVKEY_PATH = pathlib.Path(__file__).with_name("ap1-wg-hub.privkey")
def get_token():
text = TOKEN_PATH.read_text()
m = re.search(r"^NAUTOBOT_SUPERUSER_API_TOKEN=(.+)$", text, re.MULTILINE)
if not m:
raise SystemExit("NAUTOBOT_SUPERUSER_API_TOKEN not found")
return m.group(1).strip()
def main():
token = get_token()
req = urllib.request.Request(
f"{NAUTOBOT_URL}/api/plugins/golden-config/golden-config/?device=crs326-core",
headers={"Authorization": f"Token {token}", "Accept": "application/json"},
)
with urllib.request.urlopen(req) as resp:
data = json.loads(resp.read().decode())
config = data["results"][0]["intended_config"]
privkey = PRIVKEY_PATH.read_text().strip()
if "<<< AP1_WG_HUB_PRIVKEY >>>" not in config:
raise SystemExit("placeholder missing in intended config")
config = config.replace("<<< AP1_WG_HUB_PRIVKEY >>>", privkey)
leases = LEASES_RSC.read_text()
# Entferne Kommentarblock-Lease-Datei, damit nur Befehle bleiben
lease_lines = [line for line in leases.splitlines() if line and not line.startswith("#")]
# Füge Leases vor dem WG-HUB-Block ein? Oder ans Ende. Ans Ende ist einfacher.
out = config.rstrip() + "\n\n# [9] ap1 static leases -> core (STAGING)" + "\n" + "\n".join(lease_lines) + "\n"
OUT.write_text(out)
print(f"{OUT} written ({len(out)} bytes)")
if __name__ == "__main__":
main()

37
routeros/fix-core-rsc.py Normal file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env python3
import re
src = "/Users/christophemsenhuber/dev/bf-network-r6/routeros/crs326-core-pre-cutover-20260806-073712.rsc"
dst = "/Users/christophemsenhuber/dev/bf-network-r6/routeros/crs326-core-pre-cutover-20260806-073712-fixed.rsc"
with open(src) as f:
lines = f.readlines()
out = []
i = 0
while i < len(lines):
line = lines[i]
if line.startswith("add admin-mac=04:F4:1C:B4:17:76 auto-mac=no comment=defconf name=bridge"):
out.append("set [find name=bridge] admin-mac=04:F4:1C:B4:17:76 auto-mac=no vlan-filtering=yes\n")
i += 1
while i < len(lines) and (lines[i].startswith(" ") or lines[i].strip().startswith("vlan-filtering")):
i += 1
continue
if re.match(r'set \[ find default-name=ether(3|4|5|6|7|8|9|1[0-9]|2[0-4]) \] disabled=yes', line):
i += 1
continue
if line.startswith("/interface bridge port"):
out.append(line)
i += 1
while i < len(lines) and not lines[i].startswith("/"):
i += 1
out.append("set [find interface=ether2] pvid=40\n")
out.append("set [find interface=ether3] pvid=40\n")
out.append("set [find interface=ether5] pvid=40\n")
continue
out.append(line)
i += 1
with open(dst, "w") as f:
f.writelines(out)
print("fixed rsc written to", dst)

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python3
"""Kopiert ein beliebiges .rsc auf crs326-core und importiert es via SSH.
Usage: python3 import-core-rsc.py <pfad/zur/datei.rsc> [--host 10.40.41.211]
Creds kommen aus ~/.claude.json (mcpServers.mikromcp.env) envPrefix CRS326_CORE_.
"""
import json
import os
import re
import subprocess
import sys
from pathlib import Path
CLAUDe_JSON = Path.home() / ".claude.json"
RSC_PATH = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else None
HOST = sys.argv[2] if len(sys.argv) > 2 and sys.argv[1] == "--host" else None
def usage():
print(__doc__, file=sys.stderr)
sys.exit(2)
if RSC_PATH is None:
usage()
if not RSC_PATH.exists():
sys.exit(f"Datei nicht gefunden: {RSC_PATH}")
if HOST is None:
HOST = "10.40.41.211"
# Creds aus Claude-Settings laden
env = json.loads(CLAUDe_JSON.read_text())["mcpServers"]["mikromcp"]["env"]
get = lambda key, default=None: env.get(key, default)
user = get("CRS326_CORE_USER", "admin")
pw = get("CRS326_CORE_PASS")
if not pw:
sys.exit("CRS326_CORE_PASS fehlt in ~/.claude.json")
# Remote-Dateiname: alphanumerisch + Unterstrich/Punkt/Minus
remote_name = re.sub(r"[^A-Za-z0-9_.-]", "_", RSC_PATH.name)
def ssh_cmd(remote_command: str) -> list:
return [
"sshpass", "-p", pw,
"ssh",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
"-o", "LogLevel=ERROR",
f"{user}@{HOST}",
remote_command,
]
def run_silent(cmd: list):
r = subprocess.run(cmd, capture_output=True, text=True)
if r.returncode != 0:
out = (r.stdout + r.stderr).replace(pw, "***")
raise SystemExit(f"SSH-Befehl fehlgeschlagen (rc={r.returncode}):\n{out}")
return r
# 1) Eventuell vorhandene alte Remote-Datei entfernen
run_silent(ssh_cmd(f"/file/remove [find name=\"{remote_name}\"]; :delay 500ms"))
# 2) SCP
scp = [
"sshpass", "-p", pw,
"scp",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
"-o", "LogLevel=ERROR",
str(RSC_PATH),
f"{user}@{HOST}:/{remote_name}",
]
r = subprocess.run(scp, capture_output=True, text=True)
if r.returncode != 0:
out = (r.stdout + r.stderr).replace(pw, "***")
raise SystemExit(f"SCP fehlgeschlagen (rc={r.returncode}):\n{out}")
# 3) Import — mit verbose, damit wir die Zeile sehen, wenn ein Fehler auftritt
import_cmd = f"/import file-name={remote_name} verbose=yes"
res = subprocess.run(ssh_cmd(import_cmd), capture_output=True, text=True)
out = (res.stdout + res.stderr).replace(pw, "***")
if res.returncode != 0:
raise SystemExit(f"Import fehlgeschlagen (rc={res.returncode}):\n{out}")
print(out)
print(f"OK: {RSC_PATH.name} importiert auf {HOST} als /{remote_name}")

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Push nautobot/mikrotik_routeros.j2 to the bf-golden-config Gitea repo.
Reads Gitea token from ~/.secrets/credentials.env (GITEA_ACCESS_TOKEN).
"""
import base64
import json
import pathlib
import re
import urllib.request
REPO = "https://gitea.emsenhuber.net/api/v1/repos/admin/bf-golden-config"
FILE = "jinja_templates/mikrotik_routeros.j2"
TOKEN_PATH = pathlib.Path.home() / ".secrets/credentials.env"
def get_token():
text = TOKEN_PATH.read_text()
m = re.search(r"^GITEA_ACCESS_TOKEN=(.+)$", text, re.MULTILINE)
if not m:
raise SystemExit("GITEA_ACCESS_TOKEN not found")
return m.group(1).strip()
def main():
token = get_token()
src = pathlib.Path(__file__).parent.parent / "nautobot" / "mikrotik_routeros.j2"
content = src.read_text()
# fetch current SHA
req = urllib.request.Request(
f"{REPO}/contents/{FILE}?ref=main",
headers={"Authorization": f"token {token}"},
)
with urllib.request.urlopen(req) as resp:
meta = json.loads(resp.read().decode())
sha = meta["sha"]
payload = {
"content": base64.b64encode(content.encode()).decode(),
"sha": sha,
"message": "TP15: WG-HUB private key + ap1 cutover lease prep",
"branch": "main",
}
req2 = urllib.request.Request(
f"{REPO}/contents/{FILE}",
data=json.dumps(payload).encode(),
headers={
"Authorization": f"token {token}",
"Content-Type": "application/json",
},
method="PUT",
)
with urllib.request.urlopen(req2) as resp:
print(resp.status, json.loads(resp.read().decode()).get("commit", {}).get("id", "?"))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""Lädt eine .rsc-/Script-Datei per RouterOS REST API auf crs326-core hoch
und führt sie als /system/script aus.
Usage: python3 rest-core-script.py <pfad/zur/datei.rsc> [--host 10.40.41.211]
"""
import json
import sys
import urllib.request
from pathlib import Path
CLAUDe_JSON = Path.home() / ".claude.json"
if len(sys.argv) < 2:
print(__doc__, file=sys.stderr)
sys.exit(2)
src_path = Path(sys.argv[1]).resolve()
host = "10.40.41.211"
if len(sys.argv) > 2 and sys.argv[2] == "--host" and len(sys.argv) > 3:
host = sys.argv[3]
if not src_path.exists():
sys.exit(f"Datei nicht gefunden: {src_path}")
env = json.loads(CLAUDe_JSON.read_text())["mcpServers"]["mikromcp"]["env"]
user = env.get("CRS326_CORE_USER", "admin")
pw = env.get("CRS326_CORE_PASS")
if not pw:
sys.exit("CRS326_CORE_PASS fehlt in ~/.claude.json")
base_url = f"http://{host}/rest"
script_name = f"tp15_{src_path.stem}"
source = src_path.read_text()
def api(path, body=None, method="POST"):
url = base_url + path
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(url, data=data, method=method)
req.add_header("Content-Type", "application/json")
import base64
req.add_header("Authorization", "Basic " + base64.b64encode(f"{user}:{pw}".encode()).decode())
try:
with urllib.request.urlopen(req, timeout=30) as resp:
return resp.status, resp.read().decode()
except urllib.error.HTTPError as e:
return e.code, (e.read().decode() or e.reason)
def api_get(path):
url = base_url + path
req = urllib.request.Request(url)
import base64
req.add_header("Authorization", "Basic " + base64.b64encode(f"{user}:{pw}".encode()).decode())
with urllib.request.urlopen(req, timeout=30) as resp:
return resp.status, resp.read().decode()
# [1] Altes Script mit gleichem Namen entfernen
print(f"Suche ggf. altes Script '{script_name}' ...")
status, body = api_get("/system/script")
if status == 200:
try:
for item in json.loads(body):
if item.get("name") == script_name:
print(f"Entferne altes Script id={item.get('.id')} ...")
api("/system/script/remove", {"id": item[".id"]})
break
except Exception:
pass
# [2] Script anlegen
print(f"Erstelle Script '{script_name}' ({len(source)} Zeichen) ...")
status, body = api("/system/script/add", {"name": script_name, "source": source})
print(f"add -> HTTP {status}: {body[:400]}")
if status >= 400:
sys.exit("Script konnte nicht angelegt werden.")
try:
created = json.loads(body)
except json.JSONDecodeError:
created = {}
script_id = created.get(".id")
# [3] Script ausführen
if script_id:
print(f"Starte Script id={script_id} ...")
status, body = api("/system/script/run", {"id": script_id})
print(f"run -> HTTP {status}: {body[:2000]}")
else:
# Try to find by name
print("Suche Script-ID per Name ...")
status, body = api_get(f"/system/script?name={script_name}")
print(f"getall -> HTTP {status}: {body[:800]}")
print("OK: REST-Aufrufe abgeschlossen")

79
routeros/restore-core.py Normal file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/env python3
"""Stelle das crs326-core Backup vom Cutover-Stand wieder her.
Creds aus ~/.claude.json (mikromcp-env, CRS326_CORE_*).
Backup-Datei wird per SCP hochgeladen und /system backup load ausgefuehrt.
"""
import json
import pathlib
import subprocess
import sys
CORE_IP = "192.168.88.1"
BACKUP = "crs326-core-pre-cutover-20260806-073712.backup"
CLAUDE_JSON = pathlib.Path.home() / ".claude.json"
OUT_DIR = pathlib.Path(__file__).resolve().parent
def load_core_creds():
cfg = json.loads(CLAUDE_JSON.read_text())
env = cfg.get("mcpServers", {}).get("mikromcp", {}).get("env", {})
user = env.get("CRS326_CORE_USER") or env.get("ROUTER_USER")
pw = env.get("CRS326_CORE_PASS") or env.get("ROUTER_PASS")
if not user or not pw:
raise SystemExit("CRS326_CORE_USER/PASS nicht in ~/.claude.json mikromcp.env gefunden")
return user, pw
def ssh_cmd(user, pw, remote_command):
return [
"sshpass", "-p", pw,
"ssh",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{CORE_IP}",
remote_command,
]
def scp_cmd(user, pw, local_file, remote_file):
return [
"sshpass", "-p", pw,
"scp",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
str(local_file),
f"{user}@{CORE_IP}:{remote_file}",
]
def run_silent(cmd, pw):
r = subprocess.run(cmd, capture_output=True, text=True)
if r.returncode != 0:
out = (r.stdout + r.stderr).replace(pw, "***")
raise SystemExit(f"Befehl fehlgeschlagen (rc={r.returncode}):\n{out}")
return r
def main():
local_backup = OUT_DIR / BACKUP
if not local_backup.exists():
raise SystemExit(f"{local_backup} fehlt")
user, pw = load_core_creds()
print(f"crs326-core Restore via SSH {user}@{CORE_IP}")
print(f" Lade {BACKUP} hoch ...")
run_silent(scp_cmd(user, pw, local_backup, BACKUP), pw)
print(f" Spiele Backup zurueck ...")
run_silent(ssh_cmd(user, pw, f'/system backup load name="{BACKUP}" password=""'), pw)
print(" Backup geladen, Router rebootet.")
print(" Warte auf Wiederverbindung an 10.40.41.211 ...")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,36 @@
# TP15 — Bereinigt den halb-importierten Zustand auf crs326-core,
# damit die korrigierte Cutover-Config sauber neu importiert werden kann.
# Alle entfernten Objekte werden vom korrigierten tp15-core-cutover-intended.rsc
# wieder angelegt (disabled=yes).
:log info "TP15-cleanup: start"
# [1] Interface-Lists (incl. Members werden kaskadiert entfernt)
:if ([:len [/interface/list/find name="WAN"]] > 0) do={
/interface/list/remove [find name="WAN"]
}
:if ([:len [/interface/list/find name="LAN"]] > 0) do={
/interface/list/remove [find name="LAN"]
}
# [2] Staged GW-IPs
:if ([:len [/ip/address/find comment~"L3 SVI VLAN"]] > 0) do={
/ip/address/remove [find comment~"L3 SVI VLAN"]
}
# [3] Staged WAN DHCP-Client
:if ([:len [/ip/dhcp-client/find comment~"TP15 WAN"]] > 0) do={
/ip/dhcp-client/remove [find comment~"TP15 WAN"]
}
# [4] DHCP-Pools (keine Server referenzieren sie, Import blieb vor dhcp-server stehen)
:if ([:len [/ip/pool/find name~"^pool-v"]] > 0) do={
/ip/pool/remove [find name~"^pool-v"]
}
# [5] DHCP-Server/Network-Einträge
:if ([:len [/ip/dhcp-server/network/find address~"^10\\.40\\."]] > 0) do={
/ip/dhcp-server/network/remove [find address~"^10\\.40\\."]
}
:log info "TP15-cleanup: done"