
Enable IPV6 on your inbound Wireguard VPN
First of all a word of caution: I’m by no means an ipv6 expert, still learning as I go and yes ipv6 is rather complex!! Probably one of the main reasons a 100% pure ipv6 internet connection is still something we are all waiting for 😀
To get this all of this going for myself I followed some tutorials and needed a lot of patience before I finnaly got it working for myself. In the end it really wasn’t that hard, just needed to get everything just correct I guess 🙂
Now concering ipv6 two things are required: You probably need native ipv6 on your internet connection, second your ISP has to provide you with a large engough ipv6 prefix to be able to asign different ipv6 subnets on your network. From what I understand of this a /56 prefix is the very least for this to work in an easy way. I was lucky with my very decent provider that provides me with a /48 ipv6 prefix, so I was good to go. Also you need to be able to add an ipv6 route on your ISP router should you use one (in my case the Wireguard host is not directly connected to the internet but behind a router). They provide me with a decent rented Fritz!box router at 2.5 euros extra a month, so that I also got covered. Finnally a second word of caution: ipv6 has no notion of network address translation, so we need to actually route all traffic and your road warriors are upon succesfully providing them with an ipv6 address directly connected to the internet, that is unless you have a router that filters such traffic. With my Fritz!box for example I have to map router ports to an internal ipv6 address if I want to open anything inbound to the internet. Before that I had a Zyxell that had no such feature so I got security by obscurity 🙂 So be aware of this! Yes ipv6 addresses are hard to guess that is true, but if you have open ports on your clients anybody with ipv6 can connect to them. So always use your OSes firewall at the very least 🙂
Personnaly I use podman on a Linux PC to run Wireguard. I won’t go through how to setup this, IMHO there are more then enough guides out there so I’ll assume you already got that working just fine, only ipv4 only. Probably with a 10.0.0.x ipv4 address on your on the road clients.
Online I read you need extra software on the host to get the ipv6 addresses behind your host routed but in my case this wasn’t true. Guess podman takes care of the first part: making the real ipv6 addresses in the podman network reachable via the main ipv6 connection of the host. I did need to add a route to the wireguard ipv6 addresses on both my host and router though. Looks logical to me: both host, podman and the router have absolutely no knowledge of the ipv6 subnet I created within Wireguard so that one I had to explictly add to both host and router. More about that later.
So lets say your ipv6 subnet is 1111:2222:3333::/48, first you make a subnet for podman lets’s say 1111:2222:3333:100::/64 and second one for wireguard let’s say 1111:2222:3333:101::/64. You can create a podman network using a quadlet template ore by issueing podman network create
whatever has your preference. You do need to provide your wireguard container with a dedicated ipv6 address within the 1111:2222:3333:100::/64 subnet though, otherwise it would be hard to add routes on the host. So use for example 1111:2222:3333:100::2/128 for the wireguard container. Your road warrios should then get 1111:2222:3333:101::2/128 and so on, 1111:2222:3333:101::1/128 is the wireguard server as seen from the clients.
To make the podman network routable all I needed to do was add this sysctl snippet: net.ipv6.conf.all.forwarding=1
And finally you need to add ipv6 routing inside wireguard by adding this to your wireguard’s config PostUp command:
; ip6tables -A FORWARD -i %i
-j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT
And remove that in the PostDown:
; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT
That is apart form the ipv4 rules that already should be there.
Now on to the routing the wireguard ipv6 subnet part form your host and router. I’ll assume you start wireguard as a systemd service, personnaly I run this container rootfull, so adding a route during it’s startup is easy for me. Just add to the systemd unit:
ExecStartPost=/usr/sbin/ip -6 route add 1111:2222:3333:101::/64 via 1111:2222:3333:100::2 metric 10
On your router you should also add a route to 1111:2222:3333:101::/64 but this time via the ipv6 address of your host. It’s probably easier to do this if you use nmcli
to fix your host’s ipv6 address!
For me that was all I needed to do to enable ipv6 on my wireguard connections I use when I’m not home and be able to enjoy the same level of connectivity as back home 🙂