From eb61c1bae2ffad114e17393d91d86fb00d7ac8cd Mon Sep 17 00:00:00 2001 From: Hannah Isopod Date: Sat, 10 May 2025 03:03:58 -0600 Subject: Initialer commit Just remade the repo because I don't *need* need a comprehensive source history for my personal website and this is easier than getting filter-repo to work good --- .../index.php | 84 +++++++++++++++++++++ .../wireguard_logo.png | Bin 0 -> 12772 bytes 2 files changed, 84 insertions(+) create mode 100644 blog/posts/guide_self_host_safely_with_wireguard/index.php create mode 100644 blog/posts/guide_self_host_safely_with_wireguard/wireguard_logo.png (limited to 'blog/posts/guide_self_host_safely_with_wireguard') diff --git a/blog/posts/guide_self_host_safely_with_wireguard/index.php b/blog/posts/guide_self_host_safely_with_wireguard/index.php new file mode 100644 index 0000000..fcc7f05 --- /dev/null +++ b/blog/posts/guide_self_host_safely_with_wireguard/index.php @@ -0,0 +1,84 @@ + + + + + + Guide - Self-Host Safe(r)ly with WireGuard + + + + + + +

guide:

+

Self-Host Safe(r)ly with WireGuard

+ +

Warning: The information in this post is outdated and probably bad. I'd update it but I don't remember what I did. I'm pretty sure I had to circumvent UFW entirely. At any rate, probably don't do what I say to do here.

+

Preamble

+
+ Show preamble +

If you're like me, you don't like relying on other people for your online services, either because you don't want to give out your data unnecessarily, or just because you don't want to shell out for subscription services. You might be willing to host such services yourself, and you might even have access to spare hardware to do it on.

+

One critical issue arises, however: your home network. Maybe you're behind some weird impenetrable NAT setup you don't control, or maybe your IP address is dynamic and changes regularly, or maybe you just don't want to expose your home IP to the world. What then?

+

Luckily for us, there's a way to circumvent all that nonsense. A custom VPN like the one we'll be setting up today, hosted on an external server like a VPS, can punch through any weird home internet configuration while also swapping out your home IP address for a static one that you can feel safe exposing to the world.

+

That said, this isn't the be-all end-all for security. I don't claim to know everything about that, and there's probably something you're missing in that regard if you stop here. This is intended as a basic guide for exposing a machine in your home to the internet without messing with your home network or exposing your home IP address.

+

This guide borrows heavily from the landchad.net WireGuard guide, but while their one is geared toward running a VPN for your personal machine (complete with a tutorial on setting up a WebSocket tunnel), this one will focus specifically on forwarding incoming traffic from one server to another over the internet.

+

There are some reasons you'd want to do this instead of just hosting everything on the same VPS - in my case, I wanted to host a Minecraft server, and I had a spare computer at home that was better up to the task than anything for rent in my price range. WireGuard can run on pretty much anything; the cheapest tier on Vultr, DigialOcean or Linode will be more than sufficient.

+

Now on to the good stuff

+
+

This guide will take you through the process of setting up a WireGuard VPN connection between two machines running Linux, and configuring it to forward incoming web traffic from one to the other. It assumes you already have two servers set up running Linux (Ubuntu Server in my case, but any distro should suffice) with UFW configured and enabled, and know what ports you'll need.

+

The machine running your WireGuard server should be an external one exposed to the internet, such as a VPS, for maximum effect. For our purposes, this machine will be the "server", and the one you're forwarding traffic to will be the "client".

+

We'll be configuring WireGuard with a 172.16.0.1/24 virtual network and forwarding port 25565, the default for Minecraft, but any private IP range and port will do.

+

Installation

+

First, we'll install WireGuard on both machines:

+ $ apt install wireguard wireguard-tools +

And allow the port it uses in UFW:

+ $ ufw allow 51820 +

On the server

+

Uncomment this line in /etc/sysctl.d/99-sysctl.conf to enable IPv4 forwarding:

+ $ net.ipv4.ip_forward=1 +

And apply the change with this command:

+ $ sysctl -w net.ipv4.ip_forward=1 +

On the client

+

We'll need to generate a public/private key pair for each machine on our VPN network. Do that now for our client like so:

+ $ sudo bash -c "umask 077 ; wg genkey > /etc/wireguard/client_priv.key"
$ sudo bash -c "wg pubkey < /etc/wireguard/client_priv.key > /etc/wireguard/client_pub.key"
+

This generates a private key for WireGuard and then generates a corresponding public key based on it. Our client's keys can now be found in /etc/wireguard/client_priv.key and /etc/wireguard/client_pub.key for our private and public keys respectively.

+

Back to the server

+

Now do the same for the server:

+ $ umask 077 ; wg genkey > /etc/wireguard/server_priv.key
$ wg pubkey < /etc/wireguard/server_priv.key > /etc/wireguard/server_pub.key
+

Our server's keys can now be found in /etc/wireguard/server_priv.key and /etc/wireguard/server_pub.key for our private and public keys respectively.

+

Now, create a WireGuard configuration file at /etc/wireguard/wg0.conf. wg0 will be the name of our network interface, you can name yours something else if you'd like.

+ [Interface]
Address = 172.16.0.1/24
ListenPort = 51820
PrivateKey =   #(server's private key goes here)
# Firewall rules
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Client #1 details
PublicKey =   #(client's public key goes here)
# Traffic to route to this client
AllowedIPs = 172.16.0.2/32
+

Paste the server's private key after PrivateKey = in [Interface] and the client's public key after PublicKey = in [Peer].

+

With this setup, our server will use the virtual local IP 172.16.0.1 and our client will use the IP 172.16.0.2. You can also add up to 254 more clients by duplicating the [Peer] block and and updating it with the respective public key and a new local IP address.

+

Now, enable and start the WireGuard service with

+ $ systemctl enable --now wg-quick@wg0.service +

wg0 being what we called our network interface before.

+

Back to the client

+

Create a WireGuard configuration file for our client at /etc/wireguard/myvpn.conf (you can replace myvpn with a different name if you so choose):

+ [Interface]
Address = 172.16.0.2/24
PrivateKey =   #(client's private key goes here)
# Optionally, set to your desired DNS server
# DNS = 9.9.9.9

[Peer]
PublicKey =   #(server's public key goes here)
# Endpoint (server) can be a domain name or IP address
Endpoint = (server's public IP goes here):51820
# Traffic to route to server
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
+

Make sure you use your server's public IP here. The PersistentKeepalive option is there because WireGuard closes the connection by default if no data comes through for a while and will only reopen it for the client, so here we send a KeepAlive packet every 25 seconds to prevent that in order to keep our client accessible from the internet.

+

Now we start WireGuard:

+ $ sudo wg-quick up myvpn +

myvpn being whatever you called your vpn before. Shut WireGuard down by typing down instead of up here. At this point, you should be able to ping the server (172.16.0.1) or any URL from the client and get a response.

+

Port Forwarding

+

Now we'll configure the firewall and port forwarding. This bit assumes you already have UFW configured and enabled. You can set it up now if necessary.

+

On the server

+

Allow forwarding for the ports you need:

+ $ ufw route allow proto tcp to 172.16.0.2 port 25565 +

25565 being your relevant port. Repeat this command as necessary.

+

Now we need to configure iptables. We can do this through UFW by adding the following onto the very end of the file /etc/ufw⁠/before.rules:

+ *nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -p tcp --dport 25565 -j DNAT --to-destination 172.16.0.2
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
+

Where 25565 is, again, your relevant port. Copy the -A PREROUTING line for every port you need.

+

Now restart UFW:

+ $ ufw reload +

On the client

+

Allow the relevant ports and restart UFW:

+ $ ufw allow 51820
$ ufw allow 25565
$ ufw reload
+

And you're done! At this point, your client should be accessible from the IP address of your server on the ports you forwarded.

+ + + diff --git a/blog/posts/guide_self_host_safely_with_wireguard/wireguard_logo.png b/blog/posts/guide_self_host_safely_with_wireguard/wireguard_logo.png new file mode 100644 index 0000000..aaa4e03 Binary files /dev/null and b/blog/posts/guide_self_host_safely_with_wireguard/wireguard_logo.png differ -- cgit v1.2.3