Make your VPN work on ANY network
Published: July 7, 2020
Wireguard is the new VPN of choice in my house; setting it up was a breeze compared to OpenVPN that I'd been using. Wireguard is simple and just works. I have it running on everything including my 10Gig x86 OpenWRT router with it's glorious SFP+ Intel x520 card, my Android, an iPhone, my Dell laptop, and my MacBook Pro. Talk about cross-platform, This is it!
Making wireguard work perfectly when I'm not at home is a big priority for me.
Having successfully configured wireguard and tested it in a few locations, it worked great.... until I ran into a network that also used the same 10.0.0.0/24 subnet that I use for my primary home network. Therin lies the problem. How to make wireguard work for me everywhere without running into this type of conflict.
There are only 3 ranges of IPv4 addresses available for local networks. You've probably heard them called RFC 1918 networks.
- 10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
- 172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
- 192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
Most people are familiar with 192.168.0.0/16. It's commonly used in consumer grade hardware by default. Many small businesses also use it because they use consumer grade hardware too. Larger companies might choose to use the 10.0.0.0/8 network simply because it has an immense range of available addresses. The 172.16.0.0/12 networks are in my experience used much less frequently.
Fixing our conflicted subnet routing problem
We need to pick a subnet that is seldom used so we can avoid routing problems. Doing this is a four step process:
- Pick a Random VPN tunnel address range.
- Pick a Random LAN tunnel address range.
- Use the MOST SPECIFIC prefixes possible.
- Avoid using IP addresses likely to be used as a gateway on other networks.
Step 1/4: Picking a very uncommon IPv4 VPN Network Range
For our VPN, we want something uncommon. So I'll choose something in the 220.127.116.11/12 range. I also want to avoid even numbered networks because many network administrators like to use .10, .20, .30, etc. I'm going to choose 172.19.13.0/24 for my VPN. 19 is far enough from 172.16.0.0/16 which many admins would choose simply because it's the first available subnet in this RFC 1918 range. I choose 13 because it seems unlikely that someone else would pick it for their network. Also I love prime numbers.
For our example, I'm going to choose 172.19.13.0/24 for the range of IP addresses that we'll use for our Wireguard tunnels. In my configs, I'll pick one address for each device. For example:
- Router: 172.16.13.2/32
- Dell Laptop: 172.16.13.11/32
- MacBook: 172.16.13.14/32
- Android: 172.16.13.15/32
- iPhone: 172.16.13.16/32
Step 2/4: Picking an uncommon IPv4 LAN Network Range
In step 1, we picked out a small set of addresses to use in our network tunnel. This doesn't solve the larger problem which is this: Our LAN network conflicts with many other networks because it uses 10.0.0.0/24 or some other very common IPv4 address space. Let's pick a different subnet. I bet you already know what I'm going to do. We're going to reconfigure the LAN to use uncommon subnets too. For this, I'll pick 172.23.0.0/16 as my address space. For my primary LAN let's say I use 172.23.26.0/24.
Now I have my VPN running on 172.19.13.0/24 and my local LAN will be in 172.23.26.0/24. Most people would stop here. To make routing multiple networks easy, in wireguard (or any other VPN for that matter) they'd route 172.23.0.0/16 through the tunnel and everything works... usually. We do this in the wireguard configuration file by writing: AllowedIPs = 172.23.0.0/16
There is one more step we can take to make it even more likely that our VPN will succeed.
Step 3/4: The Secret SAUCE. Use the most specific prefixes possible
When routing occurs, the most specific prefix will always win. This means that the more specific you can be in your VPN prefixes, the better. Routing 172.23.0.0/16 is good, but routing 172.23.26.0/24 is better. Routing a single host such as 172.26.23.101/32 is best.
If we know we're only actually using 172.23.26.0/24, then we should create a route specifically for that instead of the full 172.23.0.0/16 range that we're planning to build our network in. So we change our AllowedIPs list to this: AllowedIPs = 172.23.26.0/24
We can go crazy here. If we know specific IP addresses that we want accessible, we can route those (and skip routing the /16 or the /24).
For sake of example:
- Server 1: 172.23.26.101/32
- Switch 1: 172.23.26.99/32
- Raspberry PI: 172.23.26.105/32
Our route list if we only want and need to use these devices could look like this:
AllowedIPs = 172.23.23.101/32, 172.23.26.99/32, 172.23.26.105/32
Very specific and unlikely to conflict EVEN if the network you're connected to happens to conflict with the address ranges you've chosen for your lan and vpn. I personally don't take it this far. I'm content to set AllowedIPs = 172.23.26.0/24. This will work perfectly unless I happen to be on someone else's 172.23.26.0/24 subnet. In that case, the more specific routes have a better chance to work because they're less likely to be in conflict.
Step 4/4: Avoid addresses that are likely to be used as the default gateway
If you really want your VPN to work anywhere there is one more step you can take. Avoid x.x.x.1 and x.x.x.254 and any other common addresses that a network administrator might have configured. You don't have to use 172.23.26.1 for your gateway. Pick a different address! Now if you happen to be on a network that manages to conflict with your carefully chosen vpn and lan networks, your very carefully chosen specific prefixes chosen in step 3 still have a good chance to work.
Avoiding conflicts for IPv6 is easy. Randomly generate at ULA Prefix instead of making up one yourself.
Thanks for reading. You can reach me by email. My name is greg, and you'll be able to guess my email from there... :)