Skip to content

Instantly share code, notes, and snippets.

@brandon1024
Last active March 15, 2025 10:54
Show Gist options
  • Save brandon1024/d90de96b0558adafe5e16c7f71b685cf to your computer and use it in GitHub Desktop.
Save brandon1024/d90de96b0558adafe5e16c7f71b685cf to your computer and use it in GitHub Desktop.
Mikrotik RouterOS: IPv6 Dynamic Prefix Delegation - Automatic Firewall Address List Synchronization
#
# 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;
};
#
# 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