my ISP gives me a new prefix with every new connection.
Therefore I do not have a static IPv6 address, that I could use in my firewall rules.
Is there a way to have the firewall automatically extended the IPv6 address by the current prefix, so I only put the interface identifier into the firewall rule?
If not, what is the correct IPv6 way to protect all IPv6 network from incoming connections but open one system?
Here is what I tried so far. Rule 10 should open my system for incoming connections.
0 ;;; Accept limited ICMP from everywhere
chain=input action=accept protocol=icmpv6 limit=50/5s,5:packet log=no
1 chain=input action=drop protocol=icmpv6 log=no
2 ;;; Accept "established and related"
chain=input action=accept connection-state=established,related log=no log-prefix=""
3 ;;; Accept everything from LAN
chain=input action=accept in-interface=LAN log=no
4 ;;; Accept DHCP from WAN
chain=input action=accept protocol=udp in-interface=WAN dst-port=546 log=no
5 ;;; Drop the rest
chain=input action=drop log=no
6 ;;; Forward limited ICMP from everywhere
chain=forward action=accept protocol=icmpv6 limit=50/5s,5:packet log=no log-prefix=""
7 chain=forward action=drop protocol=icmpv6 log=no
8 ;;; Forward "established and related"
chain=forward action=accept connection-state=established,related log=no log-prefix=""
9 ;;; Forward anything to WAN
chain=forward action=accept out-interface=WAN log=no
10 ;;; Open system for incoming traffic
chain=forward action=accept dst-address=::46e:c43c:2d14:b979/128 log=no
11 ;;; Drop the rest
chain=forward action=drop log=no
I implemented it the way, that each rule in the IPv6 firewall that has a magic ID “(PrEfIx)” in the comment get’s updated by my script.
The script is run by the DHCPv6 client whenever it renews it’s IPv6 pool that I named “WAN-pool6”.
Here is my script. It’s the first one I wrote. Maybe unstable or could be done better:
# find current IPv6 prefix from pool "WAN-pool6"
:local poolPrefix [/ipv6 pool get [/ipv6 pool find name="WAN-pool6"] prefix];
:local wanPrefix [:pick $poolPrefix 0 [:find $poolPrefix "::" 0]];
/log debug ("IPv6 WAN prefix= " . $wanPrefix);
# find all rules with magic ID (PrEfIx)
:foreach ruleIndex in [/ipv6 firewall filter find comment~"(PrEfiX)"] do= {
# get current IPv6 prefix for that rule
:local addr [/ipv6 firewall filter get $ruleIndex dst-address];
:local pos1 [:find $addr ":" 0];
:local pos2 [:find $addr ":" $pos1];
:local pos3 [:find $addr ":" $pos2];
:local pos4 [:find $addr ":" $pos3];
:local rulePrefix [:pick $addr 0 $pos4];
# get IPv6 interface ID for rule
:local ruleID [:pick $addr ($pos4 + 1) [:find $addr "/" 0]];
# get IPv6 prefix length for rule
:local rulePlen [:pick $addr ([:find $addr "/" 0] + 1) 255];
/log debug ("IPv6 rule " . $ruleIndex . ", prefix=" . $rulePrefix . ", interface ID=" . $ruleID . ", prefix length=" . $rulePlen);
# if different, update rule to WAN IPv6 prefix
:if ($wanPrefix != $rulePrefix) do= {
:local ret [/ipv6 firewall filter set "$ruleIndex" dst-address="$wanPrefix:$ruleID/$rulePlen"];
/log info ("Changed IPv6 rule " . $ruleIndex . " to dst-address=$wanPrefix:$ruleID/$rulePlen");
}
}
I know I’m a couple months late on this, but I have a solution that works pretty well. I’m using an IPv6-compatible dynamic DNS service called DUIADNS. One of the things they have is an IPv6 for LAN feature, where you can map hostnames to MAC addresses, and those DNS AAAA get updated by a client on the local network based on what IPv6 addresses go with which MAC addresses. They didn’t have an IPv6 for LAN client for Mikrotik, but I wrote a working one. I’m going to be tweaking it based on their feedback, and then sharing it.
Then, I create an address list using the device’s hostname, which gets resolved (I’m not sure on how often? I think it’s based on TTL? Maybe someone else knows the answer to this… I’m still a Mikrotik newb). Use the address list in the firewall rule, and there you go. Dynamic rules.
Hello, I’ve been trying to find a solution for this and came across this topic.
Just thinking, wouldn’t it be easier for the script (and maybe on the resources?) to make use firewall address lists? And use those address lists in the rules?
Instead for the script to search through firewall rules it would only search some entries on firewall address lists (entries either marked with a specific comment as I saw above or I don’t know.)
I’ll try to mess with this on my own these days.
I guess the script above from mangelo3690 could be adapted for this and maybe simplified. (Thanks for that btw.)
Any help appreciated.
Presuming you need this address to be externally findable and so you have used a DynDNS service to register the address, you can use the address list with that same DNS name and it will automatically change when the DNS entry has been updated to the new address.
In that case you don’t need any script at all for the address change (only a script for the registration at the DynDNS service, but that likely will go onto the system you want to make accessible)