High Speed Home VPN
Monday 03 February 2025
Background
As I've written about before, I run a lot of services in my homelab that I use both to make life easier in the case of Home Assistant and power my hobbies, such as analysing data from the race bike. While I do have some of these services facing the internet, that's usually my most used services, as well as ones I want others to be able to access. For the most part, I try to keep services separated from the internet wherever possible. I also have a few services, like my SMB file shares where it simply makes no sense to expose them to the internet. This is a pretty standard case for where to use a VPN. However, for personal use, I'm not a fan of the VPN workflow, especially on mobile devices.
The Problems
Originally, I set up a pretty standard OpenVPN instance on my PfSense router, and connected to it whenever I needed to access something at home. This worked, but had one major flaw, speed. My home internet connection is a fairly antiquated by today's standards VDSL connection capable of ~100 Mbps download and ~20 Mbps upload. This is fine for me, even working from home in the Tech industry. That is, as long as I'm in the house. When you introduce a VPN into a non-symmetric connection like this, you are effectively always limited by the lowest speed. Think about downloading a file from the internet, using a remote device connected to the VPN. The file is pulled from a server, through the VPN. At this stage it is limited by the 100 Mbps download, no issues yet. However, it now needs to go back out to the remote client, where it is now limited by the 20 Mbps upload. The same applies in reverse for uploads, effectively turning any connection into one capped at 20 Mbps in both directions. Not much fun.
To make matters worse, I'd decided after moving more services back in house, such as my Git repositories, that all my devices should always, as much as possible, act as if they were at home. I wanted full access to all my stuff, regardless of if I'm sat in my home office, or on a 3G connection in the middle of nowhere. A nice idea, but destroyed by my slow home internet, and the issue described above. That brings us to:
My Solution
It took a while, but I eventually came up with an idea, one that's a lot easier to show in the form of a diagram:
Essentially, this chains together two OpenVPN instances. One running in DigitalOcean that can achieve Internet speeds of around 1 Gbps in both directions, and another running at home. After a few hours trying to remember how Linux routing worked, I had things set up so that my client device would connect to OpenVPN on the DigitalOcean server, and could route out to the internet through the high-speed connection. Specific subnets however, would get sent down the second VPN tunnel to my home router, where they get routed to their final destination (if the firewall allows).
This setup also allows some flexibility. I no longer need to run a complicated DNS-Over-TLS setup, and can instead simply point my devices DNS at my local DNS server. Their requests get routed like any other traffic, giving me PiHole wherever I happen to be.
Minor Downside
Sadly, this isn't perfect. My DigitalOcean box is in LON-1 which I believe is an Equinix data centre. As such, some services (most notably Amazon Prime Video) will decide you're a bot and refuse to let you access the service until you drop the VPN. Also be prepared to see plenty of Capchas.
One workaround I've been employing for the former issue is this, excellent unofficial OpenVPN app which allows me to whitelist certain apps to bypass the VPN.
While I'm no cyber-security expert, it feels amiss not to mention that if you don't need to access resources on a private, or otherwise restricted network, you probably don't need a VPN. Most of the modern internet is already encrypted, so using a VPN will do very little to improve privacy, or security. This video by Tom Scott is a great starting point to understanding this.