I'm using IPv6, and I love it. I've assigned IPv6 addresses to machines behind my router, and have enabled some traffic rules. I've also used one of the networks from the /56 I get from my ISP for the Wireguard peer network.
But I'm looking at switching ISPs, which obviously will get me a new prefix. But even without that change, in theory, I could get a new prefix at any time. And if I did, all of that stuff would break because the firewall traffic rules and Wireguard interface address and peers all GUAs assigned to them.
So, other than writing some code to find all of the places that I know of that need to be updated when a prefix changes, and change everything using uci commands: how is this supposed to be managed on OpenWRT?
Is there a way to propagate a prefix change? Is there maybe a package? I haven't found anything. I'm just wondering if this is a use case that has been considered, and I'm just missing it.
The OpenWrt firewall allows "negative netmasks", making the firewall rule prefix-agnostic. The wiki calls this "dynamic prefix forwarding". Then if you want to open the firewall to allow access to an internal host from the global Internet, you only need to specify the suffix and not the whole GUA. You can use static DHCP leases to assign a specific suffix to the host. All of this should work even in the face of changing GUA prefixes.
With regards to Wireguard, I'm using unique local addresses to address hosts inside the internal network. By default, OpenWrt generates a random ULA /48 prefix on first boot and advertises that ULA prefix in addition to the ISP-assigned GUA prefix. So all hosts inside your OpenWrt network have both ULA and GUAs.
Here's an operational overview of how I do this in practice:
I randomly generate a single /48 ULA prefix for all the networks I administer. Use a site like unique-local-ipv6.com to generate one for yourself. For this example, I pick fd20:4c26:c7b4::/48
For each site, pick a /56 out of the /48 prefix. For example:
Site 1: fd20:4c26:c7b4:0100::/56
Site 2: fd20:4c26:c7b4:0200::/56
A travel router counts as a site: fd20:4c26:c7b4:fe00::/56
Each site is managed by an OpenWrt router with their assigned ULA prefix. You can set this in LuCI → Network → Interfaces → Global network options.
Each site has a Wireguard interface setup. Other sites are set as peers. The allowed IPs of each peer site is simply the ULA prefix of that site. There are different Wireguard toplogies you can use here.
For "road warrior" Wireguard peers that are on networks I can't control, I lump them all under a single "site" such as fd20:4c26:c7b4:ff00::/56. Then I assign a /128 out of this /56 for each road warrior peer. For example:
Phone: fd20:4c26:c7b4:ff00::1000/128
Laptop: fd20:4c26:c7b4:ff00::1001/128
Once this is all set up, then ULA addressing will "just work" within these networks. Then you don't ever have to worry about a changing GUA prefix, as far as Wireguard is concerned.
Thanks, I had missed the negative netmasks. That is great.
As for the Wireguard, I had seen in the docs to use ULA addresses. The issue I think I have is that I want my roving devices to have the option to route all their traffic out through the VPN, not just split-tunneling to access local resources. That would work with the IPv4 addresses, because OpenWRT would NAT the outgoing traffic and know that the incoming needs to go back to the VPN. But with IPv6, it seemed that the addresses used on the tunnel devices needed to be actual GUAs, so that they could actually route out and back (since I'm not intending to do any NAT66 on the IPv6 side). Does that make sense? Maybe I'm wrong here.
No, you're not wrong, and this does makes sense. The fundamental problem is that IPv6 address autoconfiguration relies on the Neighbor Discovery Protocol (NDP), which requires multicast addressing. Wireguard doesn't really support multicasting, and I have yet to see a de facto solution for this. Some possible ways around this:
Run a script on the roving devices that periodically contacts the OpenWrt router for prefix information and reconfigure the interface as required. Basically do what NDP does but "out-of-band" without multicasting.
Run a layer 2 tunnel such as VXLAN through the layer 3 Wireguard tunnel. This transports entire Ethernet frames through the tunnel, so NDP should "just work" at the cost of extra overhead for every packet.
Use some kind of NDP proxy so roving devices appear on the same link as non-roving devices.
Assign ULAs to the roving devices as I've described before and use network prefix translation (NPTv6). While it is a form of NAT, the mapping is one-to-one which has far less problems than one-to-many NAT as used in IPv4.
Have your roving devices connect to an OpenWrt travel router and let the router take care of this on behalf of the devices. Of course, the router itself needs to implement some kind of solution for itself, but you'd only need to do this once (and OpenWrt is far more amenable to this than smartphones).
If I was you, I would try suggestion #1. I personally haven't tried it but it looks like the path of least resistance. Do note that most solutions I've described (including #1) requires that the ISP gives you a prefix smaller than /64. ISPs seem to default to giving you a /64, but you can tell OpenWrt's DHCP client to request a smaller prefix like /56.