OpenVPN: Assign IPv6 addresses to remote site devices from IPv6 prefix received at local site via DHCPv6-PD

I would like to create a setup where a remote network tunnels its internet traffic through an OpenVPN tunnel such that it accesses the internet via the local WAN connection. For IPv4 this is relatively straightforward. I'm trying to figure out if it's possible for IPv6.

Site A (local)
OpenWrt router receives IPv6 address and prefix via DHCPv6-PD from the ISP. It is running an OpenVPN server.

Site B (remote)
OpenWrt router connects to Site A with an OpenVPN tunnel.

I would like for devices at Site B to receive IPv6 addresses with the prefix obtained by Site A and access the internet through Site A's connection via the VPN tunnel. Is this possible? Everything I've seen shows statically configured IPv6 ranges on the OpenVPN configuration, but I'm getting a dynamic prefix from my ISP.

Alternative solutions I see are using a private IPv6 prefix for Site B, routing that through OpenVPN, and using NAT6 at Site A to get a public IP. Another option would be to use a TAP interface with OpenVPN to bridge Site A and B at Layer 2 so they get their IPv6 address from the DHCPv6 server at Site A.

Neither of those solutions are ideal, is there anything I missed?

OK, so your IA_PD is being routed through "Site A" -- so, as I understand it, you're not changing the routing as far as upstream is concerned. You "just" need to either hard-code the static route on Site A for the addresses in the IA_PD to be an appropriate "Site B" address, or script it so that it adapts to any potential changes in the assigned IA_PD.

I do something topologically similar (most of the IPv6 addresses are "behind" another router relative to the one receiving the DHCP assignments), but have found that I can get the same IA_PD "forever" so have never scripted it.


If I were to script it, the DHCP hooks would be where I would do so. Remember that you might need to modify your firewall rules as well, if you have things locked down to prohibit all but "your" addresses.

For the reference:

It's completely possible to delegate private IPv6-pool and use NAT6 for internet access.
But better solution would be to split public IPv6-pool into 2 prefixes, one of them routed to LAN and another to VPN.

Is it really dynamic and changes over time?
I mean it could be bound to the MAC-address so considered as static.

1 Like

I use a self-generated DUID (DUID-UUID, or "Type 4") so that even if I change hardware, the DHCPv6 server sees me as "the same" with the same interface ID and DUID.

I'd avoid NAT6, even NPT6, if at all possible. Last I checked, Linux didn't easily support NPT6 and, while it makes sense for large organizations making upstream connectivity changes during the transition, it seems like overkill for a home user, especially if their prefix is reasonably stable.

1 Like

How big is the prefix you get? If it's a /60 or /56 or something like that you're all set, you just sub delegate one of your prefixes to the tunnel.

If your isp stupidly gives you only one /64 then it's a different story.

My ISP has a customer service router that gives out /64 but you can request multiples.

Luckily I do get a /56, so that makes things a little easier. How do I inform odhcpd that I'm manually taking some of that address space and assigning to VPN clients? Is that even necessary? It looks like it assigns a /60 to my local LAN, so can I assume it will always just take the first /60 for that?

That's a good question. I need to watch it over time to see if/how often it changes.

In general, it sounds like the suggestion is that my prefix is probably more stable than I realize. If that's the case, do I just treat it like a static prefix and hardcode it in all of my configurations? If it does change due to power outage or something else I just go back in and manually modify everything with the new prefix?

One "hint" as to how stable your prefix will be is the lease you get for it. From Comcast, CA, US, my IPv6 lease is good for 284610 seconds, a little over three days. If my power is out for that long, I've got bigger things to worry about :wink:

In writing my scripts, I use a variable for the IA_NA and IA_PD prefix wherever possible, just to make it easier if something ever changes. Something like sed would be a fallback with config that doesn't handle variables (such as UCI).

I think in Luci you would create a new interface and assign it to the VPN physical device then set the ipv6 assignment length to 64 and you'll get a separate subnet for that interface. I'm not sure how this interacts with openvpn though. Hopefully it passes the router adverts?

Good for you.
It's common practice to provide /64-prefixes for subnets.
So use any IPv6 CIDR calculator to split the pool:

Set up downstream configuration for LAN-interface:

You need to hardcode it in the VPN-server and remote DHCPv6-server configurations.
LAN-interface can pull settings dynamically.
In the worst case you can even create the script that will change VPN-server configuration dynamically.

I may not have been clear, I want to route a whole subnet over the VPN tunnel. Devices at Site B (other than the router) should know nothing about the VPN. The DHCPv6 server at Site B has no way to communicate with the one at Site A to determine what prefix to use, so I would have to hardcode that, right? I would also need to hardcode the route-ipv6 and iroute-ipv6 OpenVPN config options and update them in case of a prefix change, right?

Sounds right, yes

Site A:

  • Gets the IA_NA on its "public" interface
  • Gets its default route from DHCPv6 (or RAs, depending on software and configuration)
  • Has static route for IA_PD 2xxx::/56 through the VPN link (which seems like it would be IPv4, as Site B doesn't have an independently routed IPv6 address)

Site B:

  • Has a default route through the VPN link
  • Has a blackhole route for the entire IA_PD 2xxx::/56 ("unreachable" might be helpful until you get the config working as you expect)
  • Allocates one or more 2xxx::/64 on various interfaces
  • May assign one of the allocated prefixes to its interface, or may just use link-local, depending on your desires and implementing software
  • Has specific routes for the allocated 2xxx::/64 via the appropriate interfaces (which "override" the generic blackhole route)

Yep, looks like several places.
I think it's still possible to catch VPN-interface status change, pull subnet from that interface, increment it and push to the DHCPv6.
However it's not worth the effort and fault tolerance is questionable, so I would hardcode it.

1 Like