If you’ve ever wanted to host your own sites on a Raspberry Pi in your house, but ran into complications with port forwarding, CG-NAT, blocked public ports, or other ISP nonsense, Wireguard Backhaul can fix this for you quickly and easily.
Wireguard Backhaul is my chosen strategy to host things on the public internet from my CG-NAT home internet connection. These tips will allow you to host things like websites, game servers, and anything else from your home, but still make them internet-accessible. Additionally, if you’d like to make your services accessible only to select people with the proper VPN profile*,* I’ll show you how.
Where to get it
Since this project is really just a list of instructions and some configuration files, there isn’t a central GitLab repo for it, just this post and this script: Tom’s Easy Wireguard Setup Script. Feel free to use and share this! All code is Public Domain and all written content is under CC-BY-4.0. This is all open-source goodness.
Instructions
Initial Setup
First, you’ll need something to host from your home network. This can be as simple or as complex as you’d like. For this example, I’ll be using nginx on a Debian virtual machine to host a site. I’ll start by showing how to host this site completely privately to those with a corresponding Wireguard profile, then I’ll show you how we can publish this to the public internet.
Next, you’ll need a cheap VPS. The Wireguard service and traffic-backhaul won’t take much CPU or RAM, but (maybe obviously?) will require bandwidth. If you pay by the gig for bandwidth on your VPS host and stream 24/7 8k 240FPS video streams, this will get expensive quickly. For websites and game servers, it’ll be cheap. I use Digital Ocean for my personal VPS needs and have been using their ~$5/month VPS with no issues.
VPS Setup
I chose the cheapest Digital Ocean VPS running the latest stable Debian image. After you get it launched, configure your VPS firewall and allow the following ports:
22/TCP - Open to your IP address only
(you can remove this rule once Wireguard is running)
51820/UDP - Allow All
80/TCP - Allow All (optional, for public website hosting)
443/TCP - Allow All (optional, for public website hosting)
Then ssh to it, install Vim, Git, Caddy, and Wireguard: apt install caddy wireguard git vim. I wrote a very simple script to help automate the creation of Wireguard profiles for game servers, its available here: https://github.com/samurailink3/TomsEasyWireguardSetupScript. Follow these commands to clone the script and set it up for convenient use in our Wireguard config folder:
cd /etc/wireguard
git clone https://codeberg.org/SamuraiLink3/TomsEasyWireguardSetupScript
ln -s TomsEasyWireguardSetupScript/install-wireguard.bash ./
Then, just run the script and follow the prompts: ./install-wireguard.bash
What is the public IP address of your server? <-- This is the public IP of your VPS
How many people need a VPN profile (including you)? <-- 2 (one for the server, one for your test client)
Restart the Wireguard service to pick up the new keys: systemctl restart wg-quick@wg0
Take a look at the files we generated: ls -l /etc/wireguard/wg0/
client_1.conf <-- Your home server wireguard config file.
client_1.priv <-- Ignore this. Your home server private key.
client_1.pub <-- Ignore this. Your home server public key.
client_2.conf <-- Your test client wireguard config file.
client_2.priv <-- Ignore this. Your test client private key.
client_2.pub <-- Ignore this. Your test client public key.
server.priv <-- Ignore this. Your VPS private key.
server.pub <-- Ignore this. Your VPS public key.
We only want the two *.conf files, those contain all the information Wireguard needs to make a connection.
Wireguard Testing
Let’s make sure Wireguard is working properly. First, make sure the machine you’re on now has Wireguard installed. Then copy out client_2.conf and load it into your Wireguard client.
Once the Wireguard tunnel is activated, you can run ping 10.11.12.1 and should see responses. If you don’t, make sure your firewall is configured to allow 51820/UDP and restart the Wireguard service if you missed that step.
Server Setup and Private Hosting
On your home network server, make sure you have Wireguard installed and install the client_1.conf profile. Once Wireguard is configured and started, ping 10.11.12.1 to make sure everything is hooked up correctly.
By default, most webservers will listen on 0.0.0.0 (essentially “every configured interface on this machine”). We can isolate services to specific Wireguard IP addresses by specifying that in the config file. This is both cleaner and more expandable because we can host multiple Wireguard tunnels on this machine, each with their own underlying web services.
Here’s a snippet of the nginx config showing how this is done:
server {
listen 10.11.12.2:80 default_server;
...
So now, nginx will only listen on our configured Wireguard IP address. If we had multiple Wireguard tunnels configured, we’d just use that IP address instead.
Now, if both your server and test client are connected to the Wireguard network, you can click on http://10.11.12.2/ and see that the default nginx page is loaded. When you disable Wireguard on your test client and try to access the site, it times out. This means you now have a fully-private website, accessible over the internet to anyone you give a Wireguard profile to. This can be extremely helpful when hosting services for your family and friends, but don’t want the wider internet to have access.
If you want to make this even easier for your users, you can add a DNS record to point a domain name to 10.11.12.2 . The DNS records are public, so don’t leak information by naming your site super-secret-stuff.example.com. You can even use Let’s Encrypt and a DNS-01 challenge to add HTTPS to this internal site. For a more practical example, check out Rom Browser.
But what if you do want to make it public on the internet?
Public Hosting with the Wireguard Backhaul
Luckily, making your site publicly-accessible is pretty quick and simple!
SSH to your VPS and configure Caddy: vim /etc/caddy/Caddyfile
https://public.example.com {
reverse_proxy 10.11.12.2:80
}
Then restart the service: systemctl restart caddy
In this config file, we’ve instructed Caddy to host an HTTPS site on public.example.com. Every request made to this server is then passed to our home server over Wireguard (that’s the 10.11.12.2 address). So the request starts here at our Wireguard Backhaul VPS, then is proxied over the Wireguard tunnel to our home network server, where the request is actually responded to. The cherry on top is because this is using Caddy, we get automatic HTTPS courtesy of Let’s Encrypt.
And… that’s it! Really, its a simple as that. It does cost some money to have a publicly-accessible VPS to hook into, but you can easily spend the bare-minimum on the VPS, then more efficiently spend money on local hardware that does the real work of hosting. I’ve been using this for a few months and have moved nearly all of my cloud-based hosting to this model, saving a pile of money. Hopefully it works for you!
