SELFHOST.COMPUTER

WireGuard on a VPS: a private tunnel to your server

#wireguard#vpn#security

WireGuard on a VPS does two useful things. It gives you a private tunnel to your server, so admin panels and dashboards don't need to be on the public internet at all. And if you want, it works as your own VPN when you're on hotel or café Wi-Fi.

The setup is two small config files. This is for Debian or Ubuntu, and assumes you've done the basic hardening already.

Install and make keys

sudo -i
apt install wireguard
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
cat server.key server.pub

On your laptop, install WireGuard (there are apps for every OS) and generate a key pair there too. The app does it for you when you add an empty tunnel. You only ever copy public keys between machines.

Find your network interface

ip route | grep default

The word after dev is your public interface. It's often eth0, but some images use names like ens3. Use whatever yours says in the config below.

Server config

/etc/wireguard/wg0.conf:

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = CONTENTS_OF_server.key
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# laptop
PublicKey = LAPTOP_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32

Let the kernel forward traffic, and open the port:

echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/99-wireguard.conf
sysctl --system
ufw allow 51820/udp
systemctl enable --now wg-quick@wg0
wg show

Laptop config

[Interface]
PrivateKey = LAPTOP_PRIVATE_KEY
Address = 10.8.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = CONTENTS_OF_server.pub
Endpoint = YOUR_SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Turn it on and check your IP on any "what's my IP" site. It should show the server's address.

Full VPN or just the server?

AllowedIPs = 0.0.0.0/0 sends all your traffic through the server. If you only want to reach the server itself, change it to:

AllowedIPs = 10.8.0.0/24

Now only traffic for the tunnel goes through WireGuard, and normal browsing stays on your own connection. This is the mode I use day to day.

The real win: private admin panels

Once the tunnel is up, you can bind things to the WireGuard address instead of the public one. In Docker Compose:

ports:
  - "10.8.0.1:3001:3001"

That port only exists inside the tunnel. No login page facing the internet, no bots hammering it. I do this for Uptime Kuma, Portainer and every database UI.

One catch: WireGuard has to be running before Docker starts, or Docker can't bind to 10.8.0.1. Enabling wg-quick@wg0 as above handles that on boot. If a container still fails to start after a reboot, restart it once by hand.

More devices

Each phone or laptop gets its own key pair, its own [Peer] block on the server, and the next address: 10.8.0.3, 10.8.0.4 and so on. Restart the tunnel after editing:

sudo systemctl restart wg-quick@wg0

< all posts · netcup voucher codes

Keep reading