Last active
March 15, 2025 10:54
-
-
Save brandon1024/d90de96b0558adafe5e16c7f71b685cf to your computer and use it in GitHub Desktop.
Mikrotik RouterOS: IPv6 Dynamic Prefix Delegation - Automatic Firewall Address List Synchronization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# mikrotik-dhcpv6-trigger.script - trigger IPv6 address list synchronization | |
# | |
# This script triggers a script named 'dynamic_prefix_update', passing a new ipv6 prefix obtained | |
# from a DHCPv6 server. Simply copy into the 'script' section of your DHCPv6 client. | |
if (1=$"pd-valid") do={ | |
/delay 5 | |
:global DHCPV6PREFIX $"pd-prefix"; | |
/system script run dynamic_prefix_update; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# mikrotik-dyn-ipv6-fw-update.script - automatically update IPv6 firewall address lists on prefix changes | |
# | |
# This script synchronizes firewall address lists whenever a new IPv6 prefix is delegated from your ISP. | |
# Whenever a DHCPv6 client obtains a new prefix, this script scans through the address list and synchronizes | |
# address list items with hosts found through neighbor discovery based on their MAC addresses. | |
# | |
# Mikrotik routers don't provide a mechanism for maintaining firewall rules in a dynamic prefix delegation | |
# scenario, which is common in Dual Stack or DS-Lite network configurations. This script helps keep your | |
# firewall rules up to date, even after being assigned new prefixes. | |
# | |
# Setup: | |
# | |
# To use this script, first create IPv6 firewall address list items with the comment | |
# | |
# :auto: dyn-prefix-update "<MAC>" | |
# | |
# where <MAC> is the MAC address of the hosts network interface. For example: | |
# | |
# [user@MikroTik] > ipv6 firewall address-list print where list=dyn-prefix | |
# Columns: LIST, ADDRESS, CREATION-TIME | |
# # LIST ADDRESS CREATION-TIME | |
# ;;; :auto: dyn-prefix-update "48:4D:7E:D3:AA:2A" | |
# 13 dyn-prefix 2001:a62:144e:7890:4a4d:7eff:fed3:aa2f/128 2025-03-13 21:20:55 | |
# | |
# Then, add this script. Use the name 'dynamic_prefix_update'. | |
# | |
# Finally, update your DHCPv6 client with a small script to trigger this automation: | |
# | |
# if (1=$"pd-valid") do={ | |
# /delay 5 | |
# :global DHCPV6PREFIX $"pd-prefix"; | |
# /system script run dynamic_prefix_update; | |
# }; | |
# | |
# Assuming you have a firewall rule that uses your address list, it'll be updated automatically. | |
# Here's a sample rule that allows inbound Wireguard traffic: | |
# | |
# /ipv6 firewall filter | |
# add action=accept chain=forward comment="wireguard @ 51820" dst-address-list=dyn-prefix dst-port=51820 in-interface-list=WAN protocol=udp | |
:global DHCPV6PREFIX; | |
:local commenttag ":auto: dyn-prefix-update"; | |
# pick out a quoted string from arg 1 | |
:local EXTRACTQUOTE do={ | |
:local start [:find $1 "\"" 0]; | |
:local end [:find $1 "\"" $start]; | |
:if ($start>=0 && $end>$start) do={ | |
:return [:pick $1 ($start+1) $end]; | |
}; | |
:return ""; | |
}; | |
/ipv6 firewall address-list; | |
:foreach addrlist in=[find comment~"$commenttag"] do={ | |
:local listname [get number=$addrlist list]; | |
:local macaddr [$EXTRACTQUOTE [get number=$addrlist comment]]; | |
:local oldddr [get number=$addrlist address]; | |
:if (0=[:len $macaddr]) do={ | |
:log warning "[dynamic_prefix_update] address list entry marked for update but does not name a MAC address in comment section"; | |
} else={ | |
:local neighboraddrs [/ipv6 neighbor find mac-address=$macaddr]; | |
:foreach addr in=$neighboraddrs do={ | |
:local neighboraddr [/ipv6 neighbor get number=$addr address]; | |
:if ($neighboraddr in $DHCPV6PREFIX) do={ | |
:log info "[dynamic_prefix_update] new ipv6 address assigned to dhcpv6 client; updating firewall address list [list: '$listname', mac: $macaddr, old: $oldddr, new: $neighboraddr]"; | |
set number=$addrlist address=$neighboraddr; | |
}; | |
}; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment