When a VPN is the right answer
Use a VPN for anything that should only ever be reached by you and your household: Proxmox, a NAS admin page, SSH, the router’s own settings, a Pi‑hole you want to use on the go. The Home Assistant and Jellyfin phone apps work over a VPN too.
WireGuard needs your router to accept one incoming UDP port, so you need a public IPv4 address or working IPv6. If you are behind CGNAT, use a mesh VPN such as Tailscale instead – it builds on WireGuard but connects outwards.
Where to run it
- A small always‑on Linux machine – a Raspberry Pi, an old PC, a container or VM on your home server. This guide uses that.
- Your router, if it supports WireGuard. OpenWrt does, and so do many recent TP‑Link, ASUS, GL.iNet and Fritz!Box models. That saves the port forward, because the router is the endpoint.
- Home Assistant OS has a community WireGuard app, handy if HA is your only always‑on box.
Containers
If you run it in a Proxmox LXC container, WireGuard uses the host’s kernel module, which is already present in current Proxmox kernels.
1. Set up the server
sudo -i # the rest of this guide runs as root
apt update
apt install wireguard iptables qrencode
# keys for the server and for your first device (a phone)
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee phone.key | wg pubkey > phone.pub
cat server.pub phone.pubFind the name of the network interface that connects to your LAN with ip -br addr (often eth0, enp1s0 or end0). Then create the server configuration. The VPN uses its own small range, 10.8.0.0/24, which must not overlap your LAN.
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <contents of server.key>
# let VPN clients reach the LAN, and hide them behind this machine's LAN address
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
[Peer]
# phone
PublicKey = <contents of phone.pub>
AllowedIPs = 10.8.0.2/32chmod 600 /etc/wireguard/wg0.conf
systemctl enable --now wg-quick@wg0
wg show2. Forward the port and add a name
- Give the WireGuard machine a fixed LAN address in your router’s DHCP settings.
- Forward UDP 51820 to it. Not TCP – WireGuard only uses UDP. Router‑specific steps: BT, Virgin Media, Sky, TP‑Link.
- Keep a name pointed at your public IP with dynamic DNS. On the same Linux box, the cron job from the start guide does it: it updates
home.yourname.uk.appevery five minutes using your uk.app DDNS token.
3. Add your phone
Write the phone’s configuration on the server, then show it as a QR code for the WireGuard app to scan:
[Interface]
Address = 10.8.0.2/32
PrivateKey = <contents of phone.key>
# optional: use your Pi-hole or router for DNS while connected
DNS = 192.168.1.2
[Peer]
PublicKey = <contents of server.pub>
Endpoint = home.yourname.uk.app:51820
# only home traffic goes through the tunnel ("split tunnel")
AllowedIPs = 10.8.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25qrencode -t ansiutf8 < /etc/wireguard/phone.conf
shred -u /etc/wireguard/phone.key /etc/wireguard/phone.conf # once scannedChange 192.168.1.0/24 to your own LAN range. To send all the phone’s traffic through home – useful on untrusted Wi‑Fi – use AllowedIPs = 0.0.0.0/0, ::/0 instead. For each extra device, repeat with a new key pair, the next address (10.8.0.3, …) and a new [Peer] on the server, then run sudo systemctl restart wg-quick@wg0.
Avoid clashing address ranges
Many hotel, café and office networks use 192.168.1.0/24 or 192.168.0.0/24 too. If your home LAN uses the same range, the phone can’t tell which one you mean. If you can, move your home LAN to something less common, such as 192.168.77.0/24, in your router’s LAN settings.
4. Test it
- Turn off Wi‑Fi on the phone, switch the tunnel on in the WireGuard app, and open a LAN address such as your router’s page.
- On the server,
sudo wg showshould list the phone with a recent latest handshake and some data transferred.
The port checker can’t see WireGuard
Online port checkers, including ours, test TCP. WireGuard is UDP and deliberately stays silent to anyone without a valid key, so a checker will show the port as closed or filtered even when everything works. The handshake in wg show is the real test.
If there is no handshake:
- Check the name resolves to your current address with the DNS lookup, and compare it with ip.uk.app.
- Check the forward is UDP, to the right LAN address, on port 51820.
- Check you are not behind CGNAT or a double NAT.
- Check the keys: each side needs the other side’s public key.
If there is a handshake but you can’t reach LAN devices, IP forwarding or the masquerade rule isn’t working – check the interface name in PostUp.
When your home IP address changes
WireGuard looks up the endpoint name when the tunnel starts, not continuously. Phone apps look it up again each time you switch the tunnel on, so a changed address is picked up the next time you connect. For always‑on Linux clients, run the reresolve-dns.sh script that ships with wireguard‑tools (under /usr/share/doc/wireguard-tools/examples/reresolve-dns/ on Debian) from a timer. The DNS record is updated with a 60‑second TTL, so the new address is visible within about a minute of your updater running.
Trusted HTTPS for names you only use over the VPN
Because .app names always need HTTPS, a service you only reach over the VPN still needs a real certificate. The trick is DNS‑01 validation, which doesn’t require the service to be reachable from the internet. Point pve.yourname.uk.app at the machine’s LAN address, get a wildcard certificate with the uk.app acme.sh hook, and install it on the service or on an internal reverse proxy. The HTTPS guide has the commands, and the Proxmox guide is a worked example.
Note
Some routers block DNS answers that point at private addresses (“DNS rebind protection”). If pve.yourname.uk.app doesn’t resolve at home or over the VPN, allow the name in your router or Pi‑hole, or use a local DNS entry.