Wandering Thoughts archives

2016-11-26

What I did to set up IPv6 on my wireless network so it really worked

A couple of months ago I hacked together an IPv6 configuration for my home wireless network, which I wrote up in What I did to set up IPv6 on my wireless network. Today I completely ripped that configuration apart and put something back together again that does IPv6 totally differently and almost certainly rather better. In the process I discovered all sorts of mistakes I'd made the first time around, mistakes that I'm going to document for your amusement and my education.

The direct cause of completely changing my IPv6 setup around is that I have a Chromebook hanging around here at the moment. When it failed to talk to my IPv6 DHCP server, I knew I had some work to do, especially when the reason for this turned out to be that Android and ChromeOS don't do DHCP6 at all. So I started trying to make SLAAC work and things started falling over in ways that were familiar to me from my first attempt, except that this time I kept digging because I didn't have a choice.

There were some semi-minor things that were broken. To start with, my Unbound DNS server wasn't listening on the fe80:: link-local address I'd told the DHCP6 server to tell clients about, and even if it had been I had forgotten to tell it that it should allow clients in my IPv6 network block. As far as I can tell, Unbound silently ignores link-local addresses; I had to configure it to use my real IPv6 address (and to allow clients). This was actually a distraction, since all the clients were doing IPv6 lookups through the IPv4 DNS server IP that they were getting from plain (IPv4) DHCP, but when you're tcpdumping traffic and you see failed DNS lookups, well. Next, despite not acting as a router, my DSL router still was doing DHCP6. This can't have helped IPv6 life on my little network segment.

(I detected this through reports from radvd when I was fiddling its settings in an attempt to get things to work.)

The big problem turned out to be me shooting myself in my foot by deciding in my first attempt to use a subset /68 network prefix instead of my full /64. It turns out that radvd's complaint about 'enp7s0 prefix length should be: 64' that I mentioned in the postscript in my first attempt actually meant 'SLAAC requires a /64 and you told me to advertise SLAAC, so that's not going to work too well here'. Only once I stumbled over a Cisco web page (of all things) that mentioned this in passing did the light dawn.

(It didn't help that I didn't realize that my original radvd configuration enabled SLAAC, by saying 'AdvAutonomous on'. Nothing actually did SLAAC with that configuration because of the /68 versus /64 issue, but it was there latent in my settings.)

Now, the thing about SLAAC is that machines doing SLAAC will use IPv6 addresses from all over your /64. So very soon I noticed that I had set the IPv6 subnet for my Ethernet interface to /68 to match my radvd (and DHCP6) settings, which no longer covered all of the IPv6 SLAAC addresses I was going to see. After widening that to /64, I discovered my next configuration mistake, which was the subnet length on my IPv6 address configured on my DSL PPPoE link; for reasons lost in the depths of history, it had been configured with a /64 subnet length instead of being set to be a single IPv6 address. This appears to have caused all inbound IPv6 traffic for anything except my Linux machine to just quietly get thrown away (I assume because of routing confusion).

(I believe this worked in the past because my /68 internal interface was a more specific route than my /64 PPPoE link. When I widened the internal interface to a /64, they became equal and things got broken.)

After I found and fixed that, at last everything worked for both iOS and Android (well, ChromeOS, but Android too). Everything got SLAAC addresses, hosts were now doing DNS lookups to me over IPv6 (and having it work), and the iOS device was still doing DHCP6. But with SLAAC working for everyone, all that my DHCP6 was really doing was giving the DHCP6-capable hosts another IPv6 address, which they might or might not even use. So I decided I didn't care about the ability to ping my iOS device over IPv6 and turned off dhcpd6.

(I wound up configuring RDNSS in radvd in order to get the Android side of things to theoretically be happy with life. The practical results of this seem mixed; iOS and an Android device will do IPv6 DNS lookups, but the Chromebook doesn't.)

I have mixed feelings about SLAAC IPv6 addresses, but life is what it is. If I want to support Android and ChromeOS devices using IPv6 on my home wireless network (and I do), I don't have a choice.

(If I do per-client IPv6 filtering, I guess I'll do it based on MAC instead of IPv6 address. Probably I'll decide it's too much work and just apply blanket rules to all IPv6 traffic to 'inside' machines.)

Sidebar: my new radvd.conf, more or less

interface enp7s0
{
    AdvSendAdvert on;

    # AdvManagedFlag makes hosts try DHCP6 for
    # additional addresses.
    AdvManagedFlag on;
    # Get other stuff from DHCP6 (too).
    # Implied by AdvManagedFlag; we're
    # being explicit.
    # See RFC 2462 section 5.2
    AdvOtherConfigFlag on;

    prefix 2001:1928:1:7:f000::/64
    {
        AdvOnLink on;
        # Enable SLAAC
        AdvAutonomous on;
    };

    RDNSS 2001:1928:1:7:f000::[...]
    {
    };
};

In theory I could turn off AdvManagedFlag and AdvOtherConfigFlag. I'm keeping them in (for now) to reduce the configuration changes needed if I decide to re-enable IPv6.

linux/QuickWirelessIPv6SetupII written at 01:54:32; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.