OpenWrt Forum Archive

Topic: Dynamic IPv6 traffic rules

The content of this topic has been archived on 14 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hey,

My ISP provides a dynamic IPv6 prefix, addresses are allocated to my devices via SLAAC.

Is there a way to update my firewall traffic rule when the IP address of my server changes? Also what is the best way to update my DDNS with the server's IPv6 address, through the GUI I don't see a way to pick the IPv6 address from a specific device.

I hope to hear back,
Thanks smile

Was discussed before.
Short version : openwrt does not support dynamic ipv6 prefixes well. Need manual script work-arounds
Devices will accumulate obsolete prefixes and use ipv6 source addresses no more routed.

Firewall is reloaded on interface up/down. Of course its not possible to use static ips in rules when they change. If you need it then you have to write your own firewall include script

(Last edited by bolvan on 12 Dec 2016, 09:27)

ddns-scripts support to select network, interface or url to detect your current local ipv4 and ipv6.
Inside LuCI select the "advanced" tab.

You could try to recreate equivalent firewall rules based on source and destination interface names instead of IP addresses. If you need to differentiate between public and ULA addresses, in some cases using 2000::/3 for matching any public address would be enoughly safe.

The last trick is really writing a custom script that auto reloads with the firewall like bolvan said.

I have not tried yet but matching a specific host with dynamic prefix seems to be possible with the method described here:
http://blog.dupondje.be/?p=17

Thanks for the posts folks!

So, looks like script writing might have to be a thing.

I have previously tried using the IPv6 address with parts of the MAC address inside for the firewall rules, but couldn't get it to work properly. I've only had it working with the external IP address in there.

As for DDNS, I will look into serving a page with the public address on for the router to access!

Finally decided to do something about this, thought I should share for anyone who has the same issue!

Here is my script: LINK

I have a page on my web-server that shows it's current IPv6 address, the script reads it and sets the firewall rule accordingly. You could do the same or as it mentions, you could also get your current IPv6 address from an nslookup of your DDNS or whatever.

Set a cronjob for the script, depending on how important IPv6 is to your server depends on how often you'll want it to run of course.

EDIT: No need for a web-page containing IP address anymore! I have updated the script to get the IPv6 address from the ip neighbor command using MAC address smile

(Last edited by Callumpy on 27 Feb 2017, 04:17)

Hi everybody,

Here's my contribution for the subject:

I wrote a script that brings many advances to managing SLAAC IPv6 addresses, local DNS host names and dynamic prefixes within the OpenWrt environment. It is called ip6neigh, because its main purpose is to maintain a local hosts file in sync with the router's neighbors table.

An automated installation procedure is available at the project's page on GitHub: https://github.com/AndreBL/ip6neigh

If you read the sample config file you'll see that there's an option for ip6neigh to run an user firewall script while supplying the script with the current ipv6 prefixes.

It also has the ability to easily get the public ipv6 address for any host in the internal network based on its DHCP name, and subsequently using this address to setup firewall rules or feeding an external DDNS service.

André

AndreL wrote:

Hi everybody,

Here's my contribution for the subject:

I wrote a script that brings many advances to managing SLAAC IPv6 addresses, local DNS host names and dynamic prefixes within the OpenWrt environment. It is called ip6neigh, because its main purpose is to maintain a local hosts file in sync with the router's neighbors table.

An automated installation procedure is available at the project's page on GitHub: https://github.com/AndreBL/ip6neigh

If you read the sample config file you'll see that there's an option for ip6neigh to run an user firewall script while supplying the script with the current ipv6 prefixes.

It also has the ability to easily get the public ipv6 address for any host in the internal network based on its DHCP name, and subsequently using this address to setup firewall rules or feeding an external DDNS service.

André

Very nice! Way more elegant and reliable than my solution.

I'll be setting this up later, thank you!

Hi Callumpy,

Since the ip6neigh documentation does not contain an example on creating dynamic firewall rules yet, I'll provide an example tutorial here for accepting HTTP (port 80) connections that are bound to a local server. This assumes that outbound IPv6 connectivity is already working.

1) Start by installing ip6neigh as explained in the project's page https://github.com/AndreBL/ip6neigh . Preferably, create a static DHCP config for your server in /etc/config/dhcp with the SLAAC option set as explained in https://github.com/AndreBL/ip6neigh/blo … onfig/dhcp . This will make sure that your server's non-temporary IPv6 addresses will be always known to ip6neigh.

2) Edit /etc/firewall.user and add lines:

#ip6neigh
ip6tables -N wan6_forwarding
ip6tables -A forwarding_wan_rule -s 2000::/3 -d 2000::/3 -j wan6_forwarding

3) Edit /etc/config/firewall and right after

config include
        option path '/etc/firewall.user'

add these two lines:

config include
        option path '/tmp/etc/firewall.ip6neigh'

4) Create your custom dynamic firewall script /root/ip6neigh_rules.sh using this template:

#!/bin/sh

#Initialize the dynamic firewall script
FW_SCRIPT='/tmp/etc/firewall.ip6neigh'
echo "ip6tables -F wan6_forwarding" > $FW_SCRIPT

#Create new rules for dynamic IPv6 addresses here. Example for accepting TCP connections on port 80 on a local server that identifies itself as 'Webserver' through DHCP.
echo "ip6tables -A wan6_forwarding -d $(ip6neigh address Webserver.PUB 1) -p tcp --dport 80 -j ACCEPT" >> $FW_SCRIPT

#Run the generated temp firewall script
/bin/sh "$FW_SCRIPT"

5) Add your /root/ip6neigh_rules.sh script to ip6neigh config file /etc/config/ip6neigh

list fw_script '/root/ip6neigh_rules.sh'

6) Restart the OpenWrt firewall and ip6neigh:

/etc/init.d/firewall restart
ip6neigh restart

7) Wait a minute and check if the rules were successfully created:

root@OpenWrt:~# ip6tables -L wan6_forwarding
Chain wan6_forwarding (1 references)
target     prot opt source               destination
ACCEPT     tcp      anywhere             Webserver.PUB.lan     tcp dpt:www

(Last edited by AndreL on 27 Feb 2017, 20:42)

Although dynamic firewall rules are cool, they really aren't needed.

Since you are using SLAAC, the last 64 bits are static, and therefore you create a traffic rule which just filters on the last 64bits. Then it doesn't matter what prefix the ISP gives you.

# filter lower 64bits (allowing for dynamic prefixes) - http://blog.dupondje.be/?p=17
ip6tables -I INPUT -d ::a3a3:beff:fe89:93af/::ffff:ffff:ffff:ffff -j ACCEPT

So I have the dynamic firewall script working, only to realise that my Device.PUB.lan address isn't the one the device is using, it's actually using one listed under Device.TMP.PUB.lan

Also sometimes it doesn't list my public address on there at all sad

I've tried to rename my device, it's currently Unknown-xxx, by putting the config in the dhcp file, but it doesn't appear to work.

Thanks

EDIT: I use a cronjob on my server to update my DDNS, so it's updating my DDNS to the temp address whereas the firewall is being updated to the actual public address.

I've temporarily just set the firewall to use the TMP address, but there are sometimes multiple so there's a chance they will be wrong.

(Last edited by Callumpy on 28 Feb 2017, 13:54)

cvmiller wrote:

Although dynamic firewall rules are cool, they really aren't needed.

Since you are using SLAAC, the last 64 bits are static, and therefore you create a traffic rule which just filters on the last 64bits. Then it doesn't matter what prefix the ISP gives you.

# filter lower 64bits (allowing for dynamic prefixes) - http://blog.dupondje.be/?p=17
ip6tables -I INPUT -d ::a3a3:beff:fe89:93af/::ffff:ffff:ffff:ffff -j ACCEPT

I'm not entirely sure what you mean by this. When my IP addresses change there doesn't appear to be any level of static to them at all.

Callumpy wrote:

So I have the dynamic firewall script working, only to realise that my Device.PUB.lan address isn't the one the device is using, it's actually using one listed under Device.TMP.PUB.lan

Also sometimes it doesn't list my public address on there at all sad

I've tried to rename my device, it's currently Unknown-xxx, by putting the config in the dhcp file, but it doesn't appear to work.

Thanks

EDIT: I use a cronjob on my server to update my DDNS, so it's updating my DDNS to the temp address whereas the firewall is being updated to the actual public address.

I've temporarily just set the firewall to use the TMP address, but there are sometimes multiple so there's a chance they will be wrong.

Hi Callumpy,

We have multiple problems to address here.

It appears that the OS of the host that runs your server is using a combination of IPv6 technologies that is designed to make the IPv6 addresses hard to be discovered or guessed. Those are the Privacy Extensions (generates temporary addresses) and Semantically Opaque Interface Identifiers (IIDs), which is supposed to generate static addresses but unfortunately it has not been defined with dynamic prefixes in mind. So in practice it will produce a public address that will also change completely everytime your ISP changes the prefix.

I'd say that this is the worst (most difficult) IPv6 setup for running a server, but it is not your fault. In fact it is the ISP that screws up almost everything by implementing a dynamic prefix. If it is possible, I'd change the server config to not use Semantically Opaque IIDs, or disable Privacy Extensions (temp addr) or use managed (DHCPv6) addresses.

Currently, ip6neigh cannot differentiate between a temporary address and a semantically opaque one, so both are labeled as TMP addresses. If you want to go further trying to workaround this, your approach to use  Device.TMP.PUB.lan for getting the address is correct. But periodically the host will generate new temporary addresses and the old ones will become unusable. That is why disabling privacy extensions could help, leaving only the opaque address on the link.

The reason for the Unknown-XXX name is probably because your server is not using DHCPv4 nor DHCPv6 for getting addresses, but may have manually configured addresses instead. It is easily solved by adding a static entry in /etc/config/dhcp. If it did not work, I could help you to figure out why. The worst thing to happen is your host also using a random MAC address, which is unlikely.

By the way, what platform/OS do you use for this server ?

André

Callumpy wrote:

EDIT: I use a cronjob on my server to update my DDNS, so it's updating my DDNS to the temp address whereas the firewall is being updated to the actual public address.

I've temporarily just set the firewall to use the TMP address, but there are sometimes multiple so there's a chance they will be wrong.

Hi Callumpy,

So you had success getting your public address listed as Device.PUB.lan ?

If so, your OS is not using opaque addresses as I suspected, which is a good thing for your need. And this way you could use DDNS scripts on the router to update the external AAAA record with the same address that is listed as Device.PUB.lan.

This is what need to be added/changed in the DDNS scripts config file, under the config service 'xxxxx' section:

option ip_source 'script'
option ip_script '/usr/bin/ip6neigh address Device.PUB.lan 1'

Edit: added full path.

André

(Last edited by AndreL on 28 Feb 2017, 22:28)

AndreL wrote:
Callumpy wrote:

EDIT: I use a cronjob on my server to update my DDNS, so it's updating my DDNS to the temp address whereas the firewall is being updated to the actual public address.

I've temporarily just set the firewall to use the TMP address, but there are sometimes multiple so there's a chance they will be wrong.

Hi Callumpy,

So you had success getting your public address listed as Device.PUB.lan ?

If so, your OS is not using opaque addresses as I suspected, which is a good thing for your need. And this way you could use DDNS scripts on the router to update the external AAAA record with the same address that is listed as Device.PUB.lan.

This is what need to be added/changed in the DDNS scripts config file, under the config service 'xxxxx' section:

That should fix it, I'll try it out when I get back home.

To answer your previous thread, it's a Ubuntu machine, and the IPv4 is set static .1.100 whereas the IPv6 is obviously dynamic. I tried putting an option in the dhcp config with the MAC address and a name but it didn't work.
option ip_source 'script'
option ip_script 'ip6neigh address Device.PUB.lan 1'

André

AndreL wrote:
Callumpy wrote:

EDIT: I use a cronjob on my server to update my DDNS, so it's updating my DDNS to the temp address whereas the firewall is being updated to the actual public address.

I've temporarily just set the firewall to use the TMP address, but there are sometimes multiple so there's a chance they will be wrong.

Hi Callumpy,

So you had success getting your public address listed as Device.PUB.lan ?

If so, your OS is not using opaque addresses as I suspected, which is a good thing for your need. And this way you could use DDNS scripts on the router to update the external AAAA record with the same address that is listed as Device.PUB.lan.

This is what need to be added/changed in the DDNS scripts config file, under the config service 'xxxxx' section:

option ip_source 'script'
option ip_script 'ip6neigh address Device.PUB.lan 1'

André

That should fix it, I'll try it out when I get back home.

To answer your previous thread, it's a Ubuntu machine, and the IPv4 is set static .1.100 whereas the IPv6 is obviously dynamic. I tried putting an option in the dhcp config with the MAC address and a name but it didn't work.

Callumpy,

DHCPv6 does not use MAC addresses, but rather DUID (DHCP Unique ID). But I don't believe that will fix your problem, as you don't want the same IPv6 address applied to your Ubuntu machine, since the ISP is changing the prefix regularly.

ip6neigh can assign a DNS name to your Ubuntu machine, which can be used regardless of what prefix the ISP gives you. This names will work locally, but as stated earlier, you will need a DDNS solution for an external internet-accessible name.

Callumpy wrote:

To answer your previous thread, it's a Ubuntu machine, and the IPv4 is set static .1.100 whereas the IPv6 is obviously dynamic. I tried putting an option in the dhcp config with the MAC address and a name but it didn't work.

Hi Callumpy,

If the Interface Identifier (IID) part of your Device.PUB.lan address is the standard MAC-based EUI-64 (it contains the ff:fe sequence if the middle), this is the config I recommend for your /etc/config/dhcp:

config host
    option name    'ServerName'
    option mac    'xx:xx:xx:xx:xx:xx'
    option ip        '192.168.1.100'
    option dns    '1'
    option slaac    '1'

Restart dnsmasq and ip6neigh after doing any changes:

/etc/init.d/dnsmasq restart
ip6neigh restart

Check if the right IPv6 addresses and names appear in the first section of the list:

ip6neigh list

Thanks for all the responses, they're greatly appreciated! Interestingly I am 2 months away from finishing my degree in computer networks, yet I have so much to learn about IPv6. I have learned more from this thread and from playing around than I have from my university!

Anyway...

Currently my server has no xx.PUB.lan domain, it only has a .TMP.PUB.lan and a LL.lan.
This morning it did have a .PUB.lan domain which as you have previously mentioned contained part of the MAC address.

EDIT: From the machine locally using ip a I can see the IP address that was listed under the .PUB.lan domain earlier, but it's still not showing from a ip6neigh list on the router.

(Last edited by Callumpy on 28 Feb 2017, 21:04)

Callumpy wrote:

Thanks for all the responses, they're greatly appreciated! Interestingly I am 2 months away from finishing my degree in computer networks, yet I have so much to learn about IPv6. I have learned more from this thread and from playing around than I have from my university!

Anyway...

Currently my server has no xx.PUB.lan domain, it only has a .TMP.PUB.lan and a LL.lan.
This morning it did have a .PUB.lan domain which as you have previously mentioned contained part of the MAC address.

EDIT: From the machine locally using ip a I can see the IP address that was listed under the .PUB.lan domain earlier, but it's still not showing from a ip6neigh list on the router.

Hi Callumpy,

Thanks for the feedback. Good to know that you found your non-temporary GUA address, which is much more suitable for inbound connections than any temp address that you were previously using for this purpose.

Now adding the dhcp config that I wrote in the previous post and restarting ip6neigh will surely create a stable entry for this address under the "#Predefined hosts" section of ip6neigh list. Anything that depends on this entry (like the FW script and DDNS script) will become more reliable.

(Last edited by AndreL on 28 Feb 2017, 21:13)

AndreL wrote:
Callumpy wrote:

Thanks for all the responses, they're greatly appreciated! Interestingly I am 2 months away from finishing my degree in computer networks, yet I have so much to learn about IPv6. I have learned more from this thread and from playing around than I have from my university!

Anyway...

Currently my server has no xx.PUB.lan domain, it only has a .TMP.PUB.lan and a LL.lan.
This morning it did have a .PUB.lan domain which as you have previously mentioned contained part of the MAC address.

EDIT: From the machine locally using ip a I can see the IP address that was listed under the .PUB.lan domain earlier, but it's still not showing from a ip6neigh list on the router.

Hi Callumpy,

Thanks for the feedback. Good to know that you found your non-temporary GUA address, which is much more suitable for inbound connections than any temp address that you were previously using for this purpose.

Now adding the dhcp config that I wrote in the previous post and restarting ip6neigh will surely create a stable entry for this address under the "#Predefined hosts" section of ip6neigh list. Anything that depends on this entry (like the FW script and DDNS script) will become more reliable.

Cool, done just that and now the server shows up as Ubuntu-Server.PUB.lan as required. The .PUB.lan domain still shows the address containing the MAC (GUA).

I've edited the firewall script to contain Ubuntu-Server.PUB.lan, restarted firwall, DNS and ip6neigh and I can no longer connect to the server or infact even ping it through the GUA IP. I'm lost again now lol.

EDIT: On a good note, I have the DDNS running from the router again now, it successfully uses the GUA IP for my domain smile For whatever reason, I couldn't put the script directly into the script option like you showed, I had to make a file to point it to.

(Last edited by Callumpy on 28 Feb 2017, 22:09)

Callumpy wrote:

Cool, done just that and now the server shows up as Ubuntu-Server.PUB.lan as required. The .PUB.lan domain still shows the address containing the MAC (GUA).

I've edited the firewall script to contain Ubuntu-Server.PUB.lan, restarted firwall, DNS and ip6neigh and I can no longer connect to the server or infact even ping it through the GUA IP. I'm lost again now lol.

EDIT: On a good note, I have the DDNS running from the router again now, it successfully uses the GUA IP for my domain smile For whatever reason, I couldn't put the script directly into the script option like you showed, I had to make a file to point it to.

Hi Callumpy,

I tested the DDNS config here and found out why it did not work at first. DDNS scripts expects the full path of the script, so the line becomes:

option ip_script '/usr/bin/ip6neigh address Device.PUB.lan 1'

If the GUA is not responding, perhaps you should revisit the dynamic firewall rules on the router and any firewall rules you might also have set on the server computer itself.

AndreL wrote:
Callumpy wrote:

Cool, done just that and now the server shows up as Ubuntu-Server.PUB.lan as required. The .PUB.lan domain still shows the address containing the MAC (GUA).

I've edited the firewall script to contain Ubuntu-Server.PUB.lan, restarted firwall, DNS and ip6neigh and I can no longer connect to the server or infact even ping it through the GUA IP. I'm lost again now lol.

EDIT: On a good note, I have the DDNS running from the router again now, it successfully uses the GUA IP for my domain smile For whatever reason, I couldn't put the script directly into the script option like you showed, I had to make a file to point it to.

Hi Callumpy,

I tested the DDNS config here and found out why it did not work at first. DDNS scripts expects the full path of the script, so the line becomes:

option ip_script '/usr/bin/ip6neigh address Device.PUB.lan 1'

If the GUA is not responding, perhaps you should revisit the dynamic firewall rules on the router and any firewall rules you might also have set on the server computer itself.

Nothing has changed other than what is discussed in this thread.

root@Router:~# ip6tables -L wan6_forwarding
Chain wan6_forwarding (1 references)
target     prot opt source               destination         
ACCEPT     all      anywhere             Ubuntu-Server.PUB.lan

(Last edited by Callumpy on 28 Feb 2017, 22:37)

Also check if the GUA that ip6neigh is listing is really the same GUA you see in the server, so you did not mistype the MAC address or something.

The discussion might have continued from here.