OpenWrt Forum Archive

Topic: Giving local DNS names to IPv6 SLAAC addresses

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

Edit: Link to the release post: https://forum.openwrt.org/viewtopic.php … 27#p354627
   

Hi folks.

I'd like to share a shell script I've been working on. The purpose of the script is to automatically generate and update a hosts file giving local DNS names to IPv6 addresses that IPv6 enabled devices took via SLAAC mechanism. It works for both fixed host part and temporary addresses. It also works with dynamic public prefix, which is the case where I use it. My ISP changes the prefix at least once every 48 hours. I'm not sure if it will work in every IPv6 configuration. I'm using it with native IPv6 with prefix delegation from the ISP.

There are at least two situations where I think having this set up is useful:
1) When you need to trace some network activity through tcpdump or Realtime Connections page on LuCI and there are lots of IPv6 addresses there and you don't know who/what they belong to.
2) When you are accessing your LAN hosts remotely through VPN. Even if the local and remote IPv4 subnets conflicts you can use IPv6 ULA addresses to connect to your services. It's much easier if the ULAs have names.

The script will watch for changes in IPv6 neighbors table in realtime and will look into the DHCPv4 leases file /tmp/dhcp.leases for a host which has the same MAC address. It will then copy the same host name set by dnsmasq  for the IPv6 address. The name will have custom labels appended to it depending on the scope and type of the address (link-local, ULA, public, EUI-64 generated, temporary).

The installation procedure and code is at:

https://github.com/AndreBL/ip6neigh/

André.

(Last edited by AndreL on 20 Mar 2017, 16:37)

An interesting approach. If I understand what you are doing, then it is self-contained on the OpenWRT router.

I use an external DNS server, which contain static (SLAAC) addresses and names. I wrote a IPv6 auto discovery script to discover IPv6 hosts on the link, which I use to keep my external DNS up to date. But not everyone wants to run a separate DNS server.

https://github.com/cvmiller/v6disc

Do you have a github (or equivalent) repo one could pull from to give your script a try?

Yes, it is self-contained. It will create and update a temporary hosts file in /tmp/hosts/ and send a signal to dnsmasq process asking it to reload the hosts files when changes have been made.

This will make every IPv6 address in the LAN segment to have an associated name in the local network. Reverse queries to the addresses will also return the corresponding names. I did this because I think with IPv6 it's not practical to a LAN admin to deal with numbers anymore. Even if it's just a home or small office network because each host will have several IPv6 addresses, some with the prefix part being variable because of ISP dynamic prefix and the host part also being variable because of temporary addresses. No more easy to read and remember numbers like 10.0.0.5.

I also have another script that reads the generated hosts file and returns the globally routable address of a specific host (based on it's name) to DDNS scripts. So this script can be used to support updating DDNS entries for local computers in external servers whenever the ISP changes the prefix.

I don't have a Github account since I've not been engaged with development, but I can give it a try. For now I just copied and pasted the script in the first post.

This is the hosts file currently generated for my network. xxxx is obfuscation.

root@OpenWrt:/tmp/hosts# cat ip6neigh
#Predefined SLAAC addresses
fe80::c0fa:19df:9e4e:xxxx Chronos.LL.lan
fd32:197d:xxxx:xxxx:c0fa:19df:9e4e:xxxx Chronos.lan
2804:7f5:f080:xxxx:c0fa:19df:9e4e:xxxx Chronos.PUB.lan
fe80::f6f5:24ff:fe9e:xxxx MotoG-Andre.LL.lan
fd32:197d:xxxx:xxxx:f6f5:24ff:fe9e:xxxx MotoG-Andre.lan
2804:7f5:f080:xxxx:f6f5:24ff:fe9e:xxxx MotoG-Andre.PUB.lan
fe80::fae0:79ff:fe94:xxxx MotoX-Judith.LL.lan
fd32:197d:xxxx:xxxx:fae0:79ff:fe94:xxxx MotoX-Judith.lan
2804:7f5:f080:xxxx:fae0:79ff:fe94:xxxx MotoX-Judith.PUB.lan
fe80::a677:33ff:fe52:xxxx ChromeCast.LL.lan
fd32:197d:xxxx:xxxx:a677:33ff:fe52:xxxx ChromeCast.lan
2804:7f5:f080:xxxx:a677:33ff:fe52:xxxx ChromeCast.PUB.lan
fe80::853f:d955:674:xxxx Vostro.LL.lan
fd32:197d:xxxx:xxxx:853f:d955:674:xxxx Vostro.lan
2804:7f5:f080:xxxx:853f:d955:674:xxxx Vostro.PUB.lan
fe80::26c6:96ff:fe9b:xxxx Tablet-John.LL.lan
fd32:197d:xxxx:xxxx:26c6:96ff:fe9b:xxxx Tablet-John.lan
2804:7f5:f080:xxxx:26c6:96ff:fe9b:xxxx Tablet-John.PUB.lan
fe80::c4d7:e94:282d:xxxx Titanium.LL.lan
fd32:197d:xxxx:xxxx:c4d7:e94:282d:xxxx Titanium.lan
2804:7f5:f080:xxxx:c4d7:e94:282d:xxxx Titanium.PUB.lan

#Detected IPv6 neighbors
fd32:197d:xxxx:xxxx:d859:bf5b:473b:352e ChromeCast.TMP.lan
2804:7f5:f080:xxxx:5d3f:9a75:e2d4:53e0 Titanium.TMP.PUB.lan
2804:7f5:f080:xxxx:6d4c:d8e1:f144:6a5a ChromeCast.TMP.PUB.lan
fd32:197d:xxxx:xxxx:c521:1aa1:d9d5:9b6c MotoG-Andre.TMP.lan
2804:7f5:f080:xxxx:c521:1aa1:d9d5:9b6c MotoG-Andre.TMP.PUB.lan

root@OpenWrt:/tmp/hosts#

(Last edited by AndreL on 17 Dec 2016, 22:14)

The "#Predefined SLAAC addresses" part is generated based on additional options put in /etc/config/dhcp . Example below:

config host
        option name 'MotoG-Andre'
        option mac 'f4:f5:24:9e:xx:xx'
        option ip '10.0.0.21'
        option slaac '1' #<----- new option

config host
        option name 'Titanium'
        option mac '80:fa:5b:36:xx:xx'
        option ip '10.0.0.10'
        option slaac 'c4d7:e94:282d:xxxx' #<----- new option

In summary:

If slaac == '1' the script autogenerates the host part of the IPv6 address based on the MAC address (normal to most systems but NOT Windows).

If there's a host that uses SLAAC but does not generate it's host part based on MAC (this is the default Windows behavior: randomizeidentifiers=enabled) then you should write the expected host part instead of '1' .

The hosts that have the slaac option filled in /etc/config/dhcp will appear in the hosts file even if they are not currently connected to the network (e.g. they are powered off). Any other hosts that happen to connect to the network are automatically detected and put into the "#Detected IPv6 neighbors" part.

(Last edited by AndreL on 17 Dec 2016, 23:09)

AndreL,

Getting a github account is worth while. As it will also mean you will be using a revision controlled development environment (git). This means you can roll back, have versions, and so forth. Getting git setup is a bit of work if you have never done it before, github has some good tutorials when you set up a repo.

As of RFC 7217, more hosts will be using non MAC address-based IPv6 addresses. You may want to plan on that going forward. See my blog "Excuse me, your MAC is showing"
http://ipv6-net.blogspot.com/2016/12/ex … owing.html

Perhaps you could include your dependency shell script as well: ./lib/functions.sh

I agree that DNS is an excellent way to abstract addresses. Have you given thought to an IPv6-only network, and how your script would operate? I have a IPv6-only test network, but no DNS solution (yet).

Hi CVMiller,

Thank you for the feedback. The suggested RFC and your blog article are really good readings.

For RFC 7217 addresses I think the example where I specified the interface identifier as the value in the slaac option in /etc/config/dhcp would only work for ULA or link local addresses. The GUAs would be treated as temporary addresses because their interface identifier would change with the prefix and would not match a predefined value in /etc/config/dhcp. Still they would get a name in the "#Detected IPv6 neighbors" section like James-PC.TMP.PUB.lan. It would be wrong in the fact that these addresses are not meant to be temporary. But with ISP issuing dynamic prefix that changes every couple of days I think they would be as useful as the temporary addresses currently are.

The dependency shell script ./lib/functions.sh is part of OpenWrt. It deals with UCI configuration files parsing.

This script would not suit an IPv6 only network because it is borrowing names from DHCPv4 leases. Unless I can find an alternative source for the names it will not be a long term solution but a friendly workaround for current dual-stack setups instead.

AndreL,

You bring up a good point, if the ISP is changing the prefix, then for all intensive purposes a RFC 7217 address will be temporary.

As for IPv6-only, OpenWRT can "see" hostnames for DHCPv6 clients, but it doesn't appear to pick up the ones for my Macintoshes. I see the column for names in the Luci status page. I suspect there is a call that can be done to return the DHCPv6 table in JSON format, just haven't dug into it.

My auto discover script will use avahi (over IPv6) if available. It returns host names as well as IPv6 addresses. But not everything is running avahi (zeroconf) services. I haven't installed avahi on OpenWRT, although I do see the packages are available.

Now that I understand the dependency, let me give your script a try on my test network. I'll let you know how it goes.

CVMiller,

Picking up the names from DHCPv6 leases is a possibility. Just have to figure out how to grep the correct DUID in /tmp/hosts/odhcpd based on the MAC address that comes from the neighbors table and take the hostname from the same line. That would solve the problem for devices that have DHCPv6 clients in networks with managed addresses.

Unfortunately, there are many (mostly Android) devices around that don't implement DHCPv6 client and just use SLAAC. I have also noticed that SLAAC deals better with dynamic prefix. I wrote another script that uses radvd to deprecate the previous prefix each time my PPPoE session is restarted. This cleans up the previous stateless GUA addresses that persisted on the LAN devices but it does not clean up old GUAs that were obtained via DHCPv6 in Windows machines. In face of this problem I simply chose not to enable the managed address flag when I have dynamic prefix from the ISP. In this case I can't take any names from DHCPv6. sad

I'm not aware of how avahi and zeroconf works. What kind of names can be pulled from avahi ? Which client devices/OS support it ?

(Last edited by AndreL on 18 Dec 2016, 20:46)

AndreL wrote:

Picking up the names from DHCPv6 leases is a possibility. Just have to figure out how to grep the correct DUID in /tmp/hosts/odhcpd based on the MAC address that comes from the neighbors table and take the hostname from the same line.

Did this modification. Now it will first look into the DHCPv6 leases file. If it does not find a matching DUID for the neighbor's MAC address then it will look into the DHCPv4 leases file.

AndreL,

If you look at my v6disc documentation you can see what the output looks like.
https://github.com/cvmiller/v6disc

I make two calls to get the IPv6 address and name on the same line (see the later part of v6disc.sh)

-- Displaying avahi discovered hosts 
2001:470:1d:489:211:24ff:fee1:dbd8       halaconia.local
2001:470:1d:489::46f                     hau.local
fe80::129a:ddff:feae:8166                kukui.local
2001:470:1d:489:4459:8014:e3db:c8fe      xubuntu-VirtualBox.local

As to DHCPv6, there _may_ be away to shorted the DHCPv6 lease time on odhcpd. That would solve your old prefix problem on Windows, as the lease would expire much sooner than the current default (which is too long, IMHO). Actually, I see a DHCP4 lease time but not for DHCPv6.
https://wiki.openwrt.org/doc/techref/odhcpd

I'll open a feature request with the author.

Hi CVMiller.

I ran v6disc.sh on OpenWrt with avahi-utils installed. It found my Chromecast device IPv6 address but no hostname. Then I manually issued avahi-browse -at and it outputted a single line:

+ br-lan IPv4 Chromecast-ff1a5b88c6b1ecc5188c9d05ec7dxxxx   _googlecast._tcp     local

Looks like my network does not have any eligible IPv6 device to be discovered via mDNS protocol. Android and Windows 10 machines appear dead to it.

Hi AndreL,

Please send me an email (see my github page). I'd like to make some suggestions to your script.

Craig...

Hi Folks,

I’m glad to announce the first release of the ip6neigh Project on GitHub. The purpose of this OpenWrt/LEDE add-on script is to automatically create and maintain a hosts file for dnsmasq where every SLAAC address on the LAN will get an easy-to-memorize name. The hosts file is kept in sync with the router’s IPv6 neighbors table.

In the most typical cases, the name for the IPv6 address will be the DHCPv4 name for that same host, preceded by one or more DNS labels that identify the scope of the address. Examples: Laptop.lan (ULA), Laptop.TMP.GUA.lan (the temporary GUA).

Those who are currently managing a dual-stack LAN behind the router or want to start using IPv6 for the first time will benefit from knowing what addresses the IPv6 hosts have took via SLAAC and also getting to know the meaning of each one of them at a glance. Packet captures and LuCI Realtime Connections page will show names in place of the raw (and often confusing for beginners) IPv6 addresses.

Extra advanced features allow creating dynamic firewall rules for servers that get dynamic global prefix from the ISP and updating the server’s external DDNS record from a centralized point (the router), using ddns-scripts.

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

Many thanks to Craig Miller (cvmiller) for testing, documenting, technically discussing and encouraging the publication of the project.

Best regards,
André

The discussion might have continued from here.