[solved] Stale DHCPv6 leases under Network -> DHCP and DNS

I have all LAN IPV4 hosts with a static lease so that I can reach them in a predictable manner from one another, by name.

I am aware that I cannot exactly replicate that situation with IPV6 since the prefix is outside my control (he.net gives me a /48) but I am fine with that: as long as I can somehow indirectly map each MAC to a name, I don't care what the actual address is.

What is really driving me up the wall is that the router somehow has a different /128 address for the hosts while the hosts all have multiple /64 addresses.

Given that I have the usual mix of Linux and Android hosts, plus the occasional Windows guest, how should I configure dnsmasq on the router? I'd rather not change anything on the hosts themselves, just like for IPV4.

Here are the configs:

/etc/config/dhcp (I removed most of the hosts, leaving just the two I am using for tests)

config dnsmasq
        option domainneeded '1'
        option filterwin2k '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local 'EDITED'
        option domain 'EDITED'
        option expandhosts '1'
        option authoritative '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.auto'
        option nonegcache '1'
        option localservice '0'
        option nonwildcard '0'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

config dhcp 'lan'
        option interface 'lan'
        option start '2'
        option limit '100'
        option leasetime '24h'
        option dhcpv6 'server'
        option ra 'server'
        option ra_management '1'
        option force '1'

config host
        option name 'mononoke'
        option ip 'x.y.z.4'
        option mac 'xx:xx:xx:xx:xx:02'

config host
        option name 'clarisse'
        option ip 'x.y.z.8'
        option mac 'xx::xx:xx:xx:3d xx:xx:xx:xx:xx:6c'

/etc/config/network:

config interface 'lan'
        option ifname 'EDITED'
        option type 'bridge'
        option proto 'static'
        option ipaddr 'EDITED'
        option netmask '255.255.255.0'
        option ipv6 '1'
        list ip6class 'he_1_nyc'
        option ip6hint '2'
        option ip6assign '64'
        option stp '1'

Interesting bit I just noticed: the Linux hosts all have the wrong address, while the Android ones simply are not listed at all in DHCPv6

one way: use /etc/ethers ( and related dnsmasq option )

#readethers	boolean	0	-Z	Read static lease entries from  /etc/ethers, re-read on SIGHUP

another way: adapt something like this to populate dnsmasq A records;
( excerpt from ipv4 script )

#!/bin/sh

while read timeS maC iP namE maC2; do
	echo "$iP $namE"
	#ADDandorREMOVE A RECORD or SETUP STATIX-RESERVO
	sleep 1
done < dhcp6.leases #(/var/hosts/odhcpd)

service reload
exit
#schedule every 5-10mins in cron or trigger in /etc/dnsmasq.conf on lease

another way - most "official"

##########################################
#in /etc/dnsmasq.conf
#dhcp-script=/bin/updateDUID.sh
##########################################
#/bin/updateDUID.sh https://ashus.ashus.net/thread-175.html
#!/bin/sh
for I in $(uci show dhcp|awk -F '(\\[|\\]|\\.|=)' '{if ($2=="@host" && $5=="name") print $6}'); do
    NAME=$(echo -ne $I | sed -r "s/'//g")
    DUID=$(cat /var/hosts/odhcpd |awk -F ' '  "{if (\$1 == \"#\" && \$5 == \"$NAME\") print \$3 }"|head -n 1)
    ID=$(uci show dhcp|awk -F '(\\[|\\]|\\.|=)' "{if (\$2==\"@host\" && \$6==\"$I\") print \$3}")
        if [ "$DUID" != "0000000000000000000000000000" ]; then
                echo Found: $NAME = $DUID
                uci set dhcp.@host[$ID].duid=$DUID # Set DUID
        fi
done
echo Commiting changes; uci commit; killall -HUP odhcpd

Thanks, I'll have a look at ethers, there is no dhcp6.leases file anywhere (perhaps /var/hosts/odhcpd)

are they in /tmp/dhcp.leases too?

Nnnnope, the IPV6 leases live in another file, the one I mentioned.

1 Like

But it's static - I think you misunderstand the issue.

  • Android clients do not use stateful connection, hence they do not use DHCPv6.
  • It seems you want only DHCPv6 - be sure to disable stateless connections, and be mindful - Android clients will not get an IPv6 address
3 Likes

That is not at all... unlikely :smiley:
I have a fair amount of confusion in my head regarding IPV6.

Adding to the confusion, one host (raspi running raspbian, afaik equivalent to wthat is now debian "oldstable") has a /128 which matches the DNS entry. The two Debian/testing machines have outdated entries.

If I understand you correctly, you're telling me that there is no way I can achieve my goal without some kind of intervention on the hosts if I still want every host to have an IPV6 address and a corresponding DNS entry.

If it helps, internally it would be perfectly acceptable for me if the entries in the DNS were those directly derived from the MAC address (SLAAC, is that it?). I wouldn't be answering queries from outside the network, of course.

By default dnsmasq manages DHCPv4 and odhcpd manages DHCPv6:

Static DHCPv6 leases are issued based on DUID:

2 Likes

Thanks, I'll have a look at the docs you linked, do some testing and come back when I have results.

For now, one question: how do I handle devices with multiple interfaces? I have two laptops, one W10 and one Linux, which have static IPV4 leases mapping both MACs (wired and wifi) to the same name, under the (reasonable for me) assumption that they're not going to be used concurrently.

What do you have to handle, then?

(Besides, most OSes handle this by changing the routing metric on the wired versus wireless interfaces.)

2 Likes

router-side, this:

config host
option name 'laptop'
option ip 'x.y.z.5'
option mac 'mac1 mac2'

client-side, either the cable is plugged in or I switch the wifi off. I could probably just let it be and ignore the extra address I get, sure, but it doesn't change the fact I need to list both MACs for the same lease if I want either of them to get the same hostname.

Add the duid and hostid options according to the wiki.

2 Likes

So, here are the new bits from /etc/config/dhcp:

config host                                          
        option name 'desktop'
        option ip 'x.y.z.4'
        option mac 'mac'      
        option hostid '4'                            
        option duid '0004blahblahblahdesktop'

config host                                      
        option name 'laptop'              
        option mac 'mac1 mac2'  
        option ip 'x.y.z.8'            
        option hostid '8'                        
        option duid '0004blahblahblahlaptop'

config host                                               
        option name 'raspi'                    
        option mac 'mac1 mac2'  
        option ip 'x.y.z.14'      
        option hostid '14'       
        option duid '0001blahblahblahraspi' 
  • Debian (on desktop and laptop) creates type 4 DUIDs (option "Stable privacy" for "address generation" in NetworkManager seems to be the default when I create a new connection).
  • Raspbian creates type 1 DUIDs, no idea how to change it but it doesn't really matter, especially now.

Problem is, even after stopping multiple times dnsmasq, clearing the caches on clients and restarting....
only the raspi answers ping6 from the router and apparently it is not even using the correct hostid, since the last part of the address is ::514 (/128) instead of ::0014

Disabling the privacy extensions (tested on laptop) only removes the additional temporary addresses but the main one is still different and unknown. I guess I need to find out why the clients behave the way they do.

Oh and... how do I even handle Android devices? I thought of using "config domain" entries as if they were truly static addresses, instead of merely predictable, but this keyword does not support IPV6 according to the docs.

I had a look at this but it seems no longer needed: LUCI has a field for DUIDs

1 Like

Housekeeping:

  • I split the part related to Android devices in another post
  • I'm asking in the Debian IPV6 list for help, will update this post with the solution

NetworkManager specifically relies on the parameters addr-gen-mode and ip6-privacy:
https://developer.gnome.org/NetworkManager/stable/nm-settings.html#id-1.2.7.4.19

addr-gen-mode should apply to slaac addresses only, as I understand it; I tried changing the mode and reconnecting: different addresses but here the issue is that the lease is requested, obtained and then ignored. I've also tried disabling PE and nothing changed.

I'll call it a day, I've fixed PE on the raspi and the hostnames for Android devices... I don't have to learn everything TODAY :smiley:

1 Like

In the case of the laptop, the culprit was "ferm" (firewall): once I stopped it, it worked fine.... I'll need to punch a hole for dhcpv6.
My mistake here was taking the "solicit" message as confirmation that all was nominal, while there has to be a "request" as well. Once I saw in /var/log/messages that each dchp6 session was timing out, that was a huge clue. I'll see if the desktop is also timing out, though I don't recall ever installing any firewall there.

One thing I don't really understand yet is how the "hostid" works: if I set it to '0008', I'd expect the last group of the address to be ::8 but it's something else. This happened with the raspi, too, so it might just be me missing the point.

desktop now works, too, must have finally cleared the right lease file :smiley:

fun fact, the address is just what I expected, the hostid mistery deepens :slight_smile: