I have been "about to do IPv6 at home" for roughly a decade. The standard is older than some of my colleagues. The excuse was always the same: everything works on IPv4, NAT hides the mess, and there is no obvious day where the lack of v6 actually bites. So it sat on the list, just below "tidy the cable run" and just above "label the patch panel".
What finally moved it was nothing dramatic. My ISP had quietly been handing out a proper /56 prefix for a while, I just had never asked the router to use it. A wet Sunday and a vague sense of guilt did the rest.
The first surprise was that the WAN side mostly just worked. The router pulled a prefix over DHCPv6-PD and lit up a global address without much fuss. The second surprise, the one that ate the afternoon, was the LAN side. Getting addresses onto the LAN is easy. Getting them onto the LAN in a way that is predictable, that survives a prefix change, and that does not silently expose every device to the open internet, is the actual work.
A few things I wish someone had told me before I started, rather than after:
- Prefix delegation size matters. A /56 gives you 256 /64s to carve into subnets. A single /64 from the ISP would have left me stuck, because you really do want one /64 per VLAN and SLAAC expects it.
- SLAAC and DHCPv6 are not the same argument you think they are. I run SLAAC with RA for general devices and reserve static addresses for the handful of things I actually point DNS at. Trying to do DHCPv6-only on a network full of Android devices is a fight you will lose, because Android still refuses to do DHCPv6.
- Your prefix can change. Mine is not formally static. So anything I hardcode by full address is a hostage to the next time the ISP re-delegates. I now reference internal hosts by name and let the AAAA records track, rather than pinning addresses in configs.
The part that genuinely matters, and the part people skip, is the firewall. On IPv4 your home network hides behind NAT almost by accident. Every device has a private address and nothing inbound reaches it unless you forward a port. With IPv6 every device has a globally routable address. There is no NAT doing you accidental favours. If your firewall default is "allow", you have just put your fridge, your printer and that one IoT plug with the firmware from 2017 directly on the internet.
So the rule is short and non-negotiable: default-deny inbound on the v6 firewall, allow established and related, and open only what you actually mean to. On my edge that looks roughly like this:
# allow return traffic
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# allow internal -> internet
ip6tables -A FORWARD -i lan0 -o wan0 -j ACCEPT
# allow ICMPv6 (do NOT block this wholesale, v6 needs it)
ip6tables -A FORWARD -p ipv6-icmp -j ACCEPT
# default
ip6tables -P FORWARD DROP
That ICMPv6 line is the one people get wrong. On IPv4 you can be fairly cavalier about dropping ICMP. On IPv6 you cannot: path MTU discovery, neighbour discovery and a pile of other essentials ride on ICMPv6, and blocking it wholesale gives you the worst kind of bug, the intermittent one where some sites load and some hang.
Was it worth it? Honestly, for day-to-day browsing, no human at home has noticed a thing, which is exactly the point. The wins are quieter. Direct addressing to internal hosts without port-forward gymnastics. No CGNAT weirdness on the handful of things that still get tripped up by it. And the small, slightly smug satisfaction of running ping6 ipv6.google.com from the sofa and watching it answer.
The label still is not on the patch panel. One thing at a time.