Expose your home server to the public

Preface

So one of questions I’ve ran into is how to expose your home server to public internet, and using a cheap VPS server, and utilise it’s IP address as your external IP address. This way you are not exposing your home IP address and it provides a nice layer of abstraction.

For those more concerned what kind of information the VPS provider will be able to see. The traffic that is coming from port 443 would be encrypted with via HTTPS protocol. Only thing they will see if the wireguard private key of the server and your local machine’s public key. And data coming to/from your home instance is still encrypted.

What kind of VPS to use?


As the requirements for the VPS server go – it needs to be able to load the wireguard kernel module, and run one of the latest distributions. I usually prefer KVM based VPS servers. Second thing you would consider is the location of the VPS and network speed. It should be relatively close to your location so the latency is lower. And network. Well, at least 100 Mbit connection should do fine. But you know what kind of things you want to have made public via this method, so I’ll let you do the math.

What do we want to achieve?

infrastructure diagram of exposing home server via Wireguard


Some of the terms and services we’re going to mention in this article:
– Wireguard
– SSL certificate (Let’s Encrypt or a purchased one)
– iptables

Wireguard

To set up wireguard VPN you can do it manually, or use something like Netmaker which makes creating wireguard networks/meshes easy.
What you will setup, is a connection between two servers. The beauty of Wireguard, apart that it runs as part of the kernel, and not userspace, that there basically isn’t a server/client model.
Once you establish a connection between two servers, they just send packets to each other to determine if they can communicate. There isn’t a master server trough which all the traffic flows.

One improvement here – you can add wireguard key rotation if you are worried about using stale keys.

Let’s Encrypt

Let’s Encrypt doesn’t need a special introduction, they provide free SSL certificates for a domain, or wildcard SSL certificates where your *.domain.tld can be covered. Most importantly to manage the SSL certificates for few popular web servers, there is certbot that makes provisioning SSL certificates super easy, along their renewal.

First step

Once you have your VPS server up and running, and assuming that you have secured SSH access ( disable password auth, allow only SSH key access, generate a strong personal key) is setting up Wireguard on the machine.
Make sure that net.ipv4.ip_forward=1 is enabled, you can do:

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p 
Bash

Second step

On your home machine prepare the web server to be loaded with SSL certificates, verify that all works before you go into connecting the dots. Make sure, once you have setup the Wireguard connection, you

VPS – iptables setup to enable forwarding

Change the $HOME_SERVER_IP variable with the wireguard IP address of your home machine:

iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination $HOME_SERVER_IP:443
iptables -t nat -A POSTROUTING -j MASQUERADE
Bash

If you want to flush IP tables rules:

iptables -t nat -F
Bash

And that is it. With the iptables setup, port 443 would be forwarded to your home sever IP address over wireguard tunnel and the actual SSL/TLS termination would happen on your local machine.

Bonus

Adjust the A record for your domain or domains that you want to serve off your local, and since we are living in 2023 at the moment, SNI is available and you can host multiple SSL certificates on a single IP address.

Hope you enjoyed this article.