Fixing IPv6 on UniFi guest wireless network
My UniFi home network (some APs, some switches, whole lotta devices) is split between the trusted and guest WLANs.
Since I don’t want my corp devices on the trusted WLAN1, they sit on the guest WLAN. And up until recently, the IPv6 support wasn’t working on the guest network due to the way UniFi Cloud Key configures it.
The root cause for the issue is that the Ethernet bridge tables configured on the APs completely block IPv6 from reaching the guest network3:
$ ebtables -t nat -L # [...] Bridge chain: GUESTIN, entries: 17, policy: ACCEPT # [...] -p IPv6 -j DROP # [...] Bridge chain: GUESTOUT, entries: 6, policy: ACCEPT # [...] -p IPv6 -j DROP # [...]
The solution is – to add a bunch of stanzas allowing IPv6 and stateless IPv6
autoconfig to work. By prepending the necessary
ebtables entries, that punch
the appropriately sized hole, to the Eth bridge config.
In order for it to sustain device restarts and reconfigs, it is advisable not to fight the UniFi ecosystem.
Therefore, two things are needed:
Add router’s MAC to “Excepted devices” under broadcast/multicast filtering
7.2.94 UniFi controller this is done in
Settings (wheel) →
In the picture above I’ve added
addresses to the excepted devices. Only the MAC of your router suffices here.
In the background what happens is that UniFi AP will then attempt to call:
iwpriv athX bcfiltenable 0 iwpriv athX add_bcfiltmac aa:bb:cc:dd:ee:ff iwpriv athX add_bcfiltmac ff:ee:dd:cc:bb:aa iwpriv athX bcfiltenable 1
during interface initialization4. Presumably to exempt these macs from the broadcast filter.
Modify Ethernet bridge tables to allow IPv6
For this second part, GUI has no power here™. And ssh-ing into the Cloud Key is necessary.
# don't call home (unrelated to this post, but good to have) config.system_cfg.1=system.analytics.anonymous=disabled # to enable IPv6 on the guest network config.system_cfg.2=ebtables.105.cmd=-t nat -I GUESTOUT 1 -p IPv6 -s aa:bb:cc:00:00:00/ff:ff:ff:00:00:00 -j ACCEPT config.system_cfg.3=ebtables.101.cmd=-t nat -I GUESTIN 1 -p IPv6 -d aa:bb:cc:00:00:00/ff:ff:ff:00:00:00 -j ACCEPT config.system_cfg.4=ebtables.102.cmd=-t nat -I GUESTIN 2 -p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type router-solicitation -j ACCEPT config.system_cfg.5=ebtables.103.cmd=-t nat -I GUESTIN 3 -p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type neighbour-advertisement -j ACCEPT config.system_cfg.6=ebtables.104.cmd=-t nat -I GUESTIN 4 -p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type neighbour-solicitation -j ACCEPT
aa:bb:cc:dd:ee:ff is the router, I – just like Mic – used just
a prefix of the entire MAC address, as I don’t think it hurts anything)
This will cause the provisioning system to first execute these rules (and then
add the default ones, including the infamous
-p IPv6 -j DROP). But given that
the rules above allow communication with the router (to and from) and then a few
selected ICMP messages to make the stateless autoconfig, it punches just the
right hole for the IPv6 to start working.
Obviously after this is all saved, you need to re-provision all the APs.
After that, you can use
ebtables -t nat -L to verify the changes took place.
That, plus the fact IPv6 should be working now.
Wow, from a few lines in a gist to a novel. In under an hour and half. Not bad.
In all seriousness, why isn’t IPv6 working on the guest network on UniFi out of the box? I don’t know. Fortunately, there is a workaround.
I’m not particularly keen on the plethora of corp-operated spyware that is force-installed (and unavoidable) on all corp machines. ↩
Not that there’s anything wrong with the gist; it’s just that it lacks a bunch of context. So either you know what
config.propertiesfile is and where it should be located, or you’d be lost. ↩
I mean, yes, that’s one possible way of dealing with IPv6 configuration. Thank you, UniFi. ↩
The curiosity that it seems to be failing on the current firmware version with
Interface doesn't accept private ioctl...<CR>add_bcfiltmac (8BFD): Bad addressis a cherry I shall leave for some other time. ↩
Mysterious… because try finding official documentation for it. C’mon, I’ll wait. ↩
Because my UniFi “Site” is creatively named
default, the location has
defaultas the last directory name. YMMV. If you can’t find it,
find / -type d -name sitesor even
find / -name system.propertiesmight help locate the unifi data root. ↩