IPv6 deprecated lease time / IPv6 connection issues

I'm running pihole in a docker/synology setup, including DHCP, and it works just fine besides a weird behavior with IPv6 leases. The issue that I'm experiencing is that IPv6 leases have a 0 preferred lifetime, thus on the client the address become immediately "deprecated" and changes pretty fast.
The effects of this behavior is several failed connections reported by browsers or other applications.
I noticed that logs of avahi were reporting very often changes in IPv6 address for the wifi interface (the one controlled by pihole dhcp).
The issue is well described here:
https://github.com/lathiat/avahi/issues/41
Looking at my 10-custom.conf I found

dhcp-option=option6:dns-server,[::]
dhcp-range=::100,::1ff,constructor:eth0,ra-names,slaac,64,3600
ra-param=*,0,0

that seems ok, but removing the 3600 at the end, i.e. making it like
dhcp-range=::100,::1ff,constructor:eth0,ra-names,slaac,64
the preferred time for the allocated IPv6 address changed from 0 (deprecated) to something like
valid_lft 2355sec preferred_lft 2355sec
and the connection issues no longer happened.
I don't know if removing the 3600 fixed value and relying on the default is the right move, so I'm asking here if this is a know behavior and how to deal best with it.

The IPv6 range is meant to be solely a way to advertise Pi-hole's DNS capability to IPv6 network segments.

Pi-hole is not designed or intended to be a DHCPv6 server.

Not sure to understand the point. My situation is that I'm using a pretty standard pi.hole setup, and that is causing problems on the network. If pi.hole is not designed to be a ipv6 dhcpserver, what is the point of showing in the GUI "IPv6 SLAAC+RA". What is the suggestion, disabling IPv6 on pihole completely?

is somewhat contradicted by

So far, you've just disclosed your custom configuration.

As was requested by the template, please upload a debug log and share the token, so we can be aware of your entire Pi-hole configuration.

That said, I do not see how the shared configuration and your reported change of it would contribute to your observation. Effectively, you've only replaced your previous one-hour lifetime by dnsmasq's one-day default.

As lifetime is configured to a value well above 0 seconds, this would make it unlikely that your observation is caused by your configuration.

Nominally, in order to have dnsmasq announce a zero lifetime, setting that to an explicit value of deprecated would be required.

Note that dnsmasq (Pi-hole's DNS and DHCP server embedded in pihole-FTL) is just handling the interface identifier portion of an IPv6 address.

It is your router that controls your network's IPv6 prefixes.

Did you check how often those would change, how often your router would advertise them, and how long they would be valid for?

EDIT:
Some output from ip -6 address would also be helpful.
That would allow to check which IPv6 addresses are affected (and whether that would include actual adresses from your configured DHCPv6 range).

Good points, let me dig thru and collect some more data

So, first, token is https://tricorder.pi-hole.net/9VGdTQdi/
Then I have a wireshark screenshot where you can see the packet received. Please note that the source is pi.hole container (mac_address: fa:b1:00:c0:a7:71)


Additionally, here is the ip -6 addr output

and this is the avahi view of the event:
avahi
Please note that data has been collected in different moments, (in the space of few minutes anyway).
The 10-custom.conf reference was a mistake on my side, it actually contains only

addn-hosts=/etc/pihole/custom.list
local=/lan/

Your debug log suggests that your DHCPv6 configuration is standard, except your removal of the lifetime. Note that Pi-hole may overwrite that setting on updates or configuration changes.

Together with your IP addresses, your analysis output seems normal at first glance, but I note that you've inspected solely Pi-hole's RAs, instead of those of your router.

Your wireshark screenhot shows an inspected RA prefix 200xxx4e19::/64, and your IP address screenshot suggests that prefix would have been deprecated due to a new GUA prefix 200xxx4e43::/64.

A client won't use a deprecated address to initiate communication, but it will be able to receive communication until its valid_lft has expired, so it is normal that these addresses still stay attached to an interface.

Note that one of the active GUA addresses with that new GUA prefix has been handed out from your Pi-hole's configured DHCPv6 range (as ::1e4 falls into ::100 to ::1ff), but there is no such address for the deprecated prefix, suggesting that dnsmasq is correctly handling those DHCPv6 leases.

As far as the prefix is concerned:
It seems unusual that a deprecated prefix would be part of an RA, but dnsmasq does not create prefixes, it rather derives the prefixes from addresses of its configured network interfaces.

Note that this wouldn't trigger a connected client to create a deprecated address - that client would already have deprecated that address when your router announced the prefix change.

But it seems possible that your mDNS software would somehow react to that RA for a deprecated prefix, though that may not tell us yet whether that's a potential misbehaviour of mDNS or of dnsmasq.

Please, also have a look at your router's RAs and check them for that type of prefix.
radvdump may be easier to use for extracting that information:

sudo apt install radvdump

Then just run

sudo radvdump

and wait for a while until the RAs fill your screen (that may take a few minutes).

I'll try to reproduce your observation by forcing a prefix change and monitoring my router's RAs, and I'll also check if a newly joining client would pick up that deprecated prefix (which may put the ball in dnsmasq's field).

I collected some more info.
Wireshark capture of IPv6 type 134:


Here pihole can be seen sending out quite a lot of RA (mac ending in a7:71) and the router sends out way less advertising (mac ending in 1e:88)
Now, looking inside those packets via radvdump:
Router:

#
# radvd configuration generated by radvdump 2.19
# based on Router Advertisement from fe80::1
# received by interface wlp4s0
#

interface wlp4s0
{
	AdvSendAdvert on;
	# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
	AdvManagedFlag off;
	AdvOtherConfigFlag on;
	AdvReachableTime 0;
	AdvRetransTimer 0;
	AdvCurHopLimit 255;
	AdvDefaultLifetime 180;
	AdvHomeAgentFlag off;
	AdvDefaultPreference high;
	AdvLinkMTU 1492;
	AdvSourceLLAddress on;

	prefix 200XXXXXXXX:4e00::/64
	{
		AdvValidLifetime 604800;
		AdvPreferredLifetime 86400;
		AdvOnLink on;
		AdvAutonomous on;
		AdvRouterAddr off;
	}; # End of prefix definition


	prefix fd25:9580:877:1::/64
	{
		AdvValidLifetime 1814400;
		AdvPreferredLifetime 604800;
		AdvOnLink on;
		AdvAutonomous on;
		AdvRouterAddr off;
	}; # End of prefix definition

}; # End of interface definition
#

Apparently, all prefixes has AdvPreferredLifetime that is non-zero, even though is is different between local and external prefix. This makes sense, as the router will change the external range (200X) every 24h

now, pihole adv:

#
# radvd configuration generated by radvdump 2.19
# based on Router Advertisement from fe80::f8b1:ff:fec0:a771
# received by interface wlp4s0
#

interface wlp4s0
{
	AdvSendAdvert on;
	# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
	AdvManagedFlag on;
	AdvOtherConfigFlag on;
	AdvReachableTime 0;
	AdvRetransTimer 0;
	AdvCurHopLimit 64;
	AdvDefaultLifetime 0;
	AdvHomeAgentFlag off;
	AdvDefaultPreference medium;
	AdvLinkMTU 1492;
	AdvSourceLLAddress on;

	prefix 200XXXXXXXX:4e00::/64
	{
		AdvValidLifetime 3600;
		AdvPreferredLifetime 3575;
		AdvOnLink on;
		AdvAutonomous on;
		AdvRouterAddr off;
	}; # End of prefix definition


	prefix fd25:9580:877:1::/64
	{
		AdvValidLifetime 3600;
		AdvPreferredLifetime 3575;
		AdvOnLink on;
		AdvAutonomous on;
		AdvRouterAddr off;
	}; # End of prefix definition


	prefix 200XXXXXXX:4e43::/64
	{
		AdvValidLifetime 3586;
		AdvPreferredLifetime 0;
		AdvOnLink on;
		AdvAutonomous on;
		AdvRouterAddr off;
	}; # End of prefix definition


	prefix 200XXXXXXXX:4e19::/64
	{
		AdvValidLifetime 3586;
		AdvPreferredLifetime 0;
		AdvOnLink on;
		AdvAutonomous on;
		AdvRouterAddr off;
	}; # End of prefix definition


	RDNSS 200XXXXXX:f8b1:ff:fec0:a771
	{
		AdvRDNSSLifetime 3600;
	}; # End of RDNSS definition

}; # End of interface definition

Here for many advertised prefixes AdvPreferredLifetime is non-zero (3600 as configured it seems), but for 200XXXXXXXX:4e19::/64 and prefix 200XXXXXXX:4e43::/64 this field is set to zero, and I wonder why. interestingly, 200XXXXXXXX:4e00::/64 is set to 3600. I wonder why pihole (dnsmasq) does this kind of advertising. Can't find the logic, but I'm not expert in any way about IPv6 :slight_smile:

Thank you for looking into your router's RAs as well.

In the meantime, I was also able to trigger Pi-hole's dnsmasq to advertise a deprecated prefix by forcing my router to switch its GUA prefix.

My observation differs from yours, as I had the chance to observe the complete evolution of RAs during the prefix replacement process.

Router-RA **before** prefix change, GUA prefix ends in`:f900`
#
# radvd configuration generated by radvdump 2.17
# based on Router Advertisement from fe80::464e:6dff:fe24:68ac
# received by interface eth0
#

interface eth0
{
        AdvSendAdvert on;
        # Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
        AdvManagedFlag on;
        AdvOtherConfigFlag on;
        AdvReachableTime 0;
        AdvRetransTimer 0;
        AdvCurHopLimit 255;
        AdvDefaultLifetime 0;
        AdvHomeAgentFlag off;
        AdvDefaultPreference medium;
        AdvLinkMTU 1492;
        AdvSourceLLAddress on;

        prefix 2a02:1c24:7d39:f900::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 3600;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        prefix fd08:bce3:1a6a:9c08::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 3600;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        route 2a02:1c24:7d39:f900::/56
        {
                AdvRoutePreference medium;
                AdvRouteLifetime 1800;
        }; # End of route definition


        route fd08:bce3:1a6a:9c08::/64
        {
                AdvRoutePreference medium;
                AdvRouteLifetime 1800;
        }; # End of route definition

}; # End of interface definition
Router-RA upon requesting prefix change, with prefix lifetime set to zero

The prefix is getting deprecated as its AdvPreferredLifetime becomes 0, and the corresponding route has been withdrawn:

#
# radvd configuration generated by radvdump 2.17
# based on Router Advertisement from fe80::464e:6dff:fe24:68ac
# received by interface eth0
#

interface eth0
{
        AdvSendAdvert on;
        # Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
        AdvManagedFlag on;
        AdvOtherConfigFlag on;
        AdvReachableTime 0;
        AdvRetransTimer 0;
        AdvCurHopLimit 255;
        AdvDefaultLifetime 0;
        AdvHomeAgentFlag off;
        AdvDefaultPreference medium;
        AdvLinkMTU 1492;
        AdvSourceLLAddress on;

        prefix 2a02:1c24:7d39:f900::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 0;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        prefix fd08:bce3:1a6a:9c08::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 3600;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        route fd08:bce3:1a6a:9c08::/64
        {
                AdvRoutePreference medium;
                AdvRouteLifetime 1800;
        }; # End of route definition

}; # End of interface definition
Router-RA as the new prefix (`:f300`) becomes active, still including the deprecated one (`:f900`):
#
# radvd configuration generated by radvdump 2.17
# based on Router Advertisement from fe80::464e:6dff:fe24:68ac
# received by interface eth0
#

interface eth0
{
        AdvSendAdvert on;
        # Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
        AdvManagedFlag on;
        AdvOtherConfigFlag on;
        AdvReachableTime 0;
        AdvRetransTimer 0;
        AdvCurHopLimit 255;
        AdvDefaultLifetime 1800;
        AdvHomeAgentFlag off;
        AdvDefaultPreference high;
        AdvLinkMTU 1492;
        AdvSourceLLAddress on;

        prefix 2a02:1c24:7917:f300::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 3600;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        prefix 2a02:1c24:7d39:f900::/64
        {
                AdvValidLifetime 7199;
                AdvPreferredLifetime 0;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        prefix fd08:bce3:1a6a:9c08::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 3600;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        route ::/0
        {
                AdvRoutePreference high;
                AdvRouteLifetime 1800;
        }; # End of route definition


        route 2a02:1c24:7917:f300::/56
        {
                AdvRoutePreference high;
                AdvRouteLifetime 1800;
        }; # End of route definition


        route fd08:bce3:1a6a:9c08::/64
        {
                AdvRoutePreference high;
                AdvRouteLifetime 1800;
        }; # End of route definition

}; # End of interface definition
Next regular router-RA doesn't contain deprecated prefix anymore
#
# radvd configuration generated by radvdump 2.17
# based on Router Advertisement from fe80::464e:6dff:fe24:68ac
# received by interface eth0
#

interface eth0
{
        AdvSendAdvert on;
        # Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
        AdvManagedFlag on;
        AdvOtherConfigFlag on;
        AdvReachableTime 0;
        AdvRetransTimer 0;
        AdvCurHopLimit 255;
        AdvDefaultLifetime 1800;
        AdvHomeAgentFlag off;
        AdvDefaultPreference high;
        AdvLinkMTU 1492;
        AdvSourceLLAddress on;

        prefix 2a02:1c24:7917:f300::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 3600;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        prefix fd08:bce3:1a6a:9c08::/64
        {
                AdvValidLifetime 7200;
                AdvPreferredLifetime 3600;
                AdvOnLink on;
                AdvAutonomous off;
                AdvRouterAddr off;
        }; # End of prefix definition


        route ::/0
        {
                AdvRoutePreference high;
                AdvRouteLifetime 1800;
        }; # End of route definition


        route 2a02:1c24:7917:f300::/56
        {
                AdvRoutePreference high;
                AdvRouteLifetime 1800;
        }; # End of route definition


        route fd08:bce3:1a6a:9c08::/64
        {
                AdvRoutePreference high;
                AdvRouteLifetime 1800;
        }; # End of route definition

}; # End of interface definition

It is worth noting that - just as Pi-hole's dnsmasq - my router advertises the deprecated prefix, but only for a single complete cycle until after the new GUA prefix becomes active.

But dnsmasq continues to announce the deprecated prefix, as that will still be attached to the network interface of its hosts until its valid_lifetime expires.

So while dnsmasq does correctly advertise the deprecated prefix, it would do so for a much longer time than the router.

There are two parameters that would make this misbehaviour more obvious in your configuration:
Your router's AdvDefaultLifetime 180 is comparably short (180 seconds, where mine advertises 1,800 or 30 minutes - Pi-hole's dnsmasq's is always 0, to indicate that it isn't a router), and the retired GUA prefix has a comparably long AdvValidLifetime of 604,800 (a week, where mine is 7,200 (2 hours) - a week seems overly long for a deprecated IPv6 address to persevere).

Together, this would force those RAs to be issued considerably more often over a considerably longer period of time. So where I would hardly notice them, I can see how they can become a real nuisance for you.

And as your prefix's AdvPreferredLifetime is at 86,400 (or a day), that would mean that 6 additional deprecated addresses would potentially pile up on every network interface of every IPv6-capable client over the course of a week, before the first deprecated address would finally wither away.
Note, however, that this multitude of addresses would happen by virtue of your router's own RAs, regardless of Pi-hole coming into the mix.

You could try to quieten RAs a bit by adjusting those parameters - provided your router would expose the corresponding configuration options (mine doesn't).

Alternatively, you could consider to disable Pi-hole's IPv6 support.
This would require your router to still offer SLAAC and DHCPv6 services for your network, and you should also double-check that your router advertises one of your Pi-hole's stable IPv6 addresses.
That would have been just as important before, but now your router's RA becomes the only source of RDNSS messages.
The multitude of addresses would stay, but it seems your router wouldn't continue to advertise deprecated prefixes.

On first impulse, I do think that the observed behaviour is unintended and also undesirable, and probably should be addressed by dnsmasq.

I do think so because during my tests, I have verified that a client that was powered on well after the prefix change and freshly joined the network would indeed pick up the deprecated prefix and use that for constructing a deprecated IPv6 address.
This seems unnecessary, as I have a hard time imagining how a peer would have learned to talk to a deprecated address that never has seen active duty before.

Thanks for the very detailed answer, really informative. I'm still investigating this issue, it is indeed fun :slight_smile: Now I disabled RA/SLAAC on pi.hole as my router offers basically no control on IPv6, but addresses "deprecated" keeps popping up, so I would also investigate deeper on client side kernel/network (Linux 5.17.5) behavior, as I don't understand why the 200X deprecated addresses keeps popping up, even after removing them with ip -6 addr del, flushing neigh caches and disabling/enabling ipv6 with No advertising with preferred time = 0 arrives on the network interfaces.
I disable IPv6 on the host via proc filesystem and then reenable it, those deprecated addresses keeps appearing. I have very limited knowledge of IPv6, so please forgive me if I'm saying something naive.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.