// VPS Setup Guide v3.0

WireGuard VPS
Server Setup

Add peers & ports — generate a ready-to-paste wg0.conf and client configs

// 1 — VPS Base Configuration

Fill all fields. The generated config and guide commands update automatically.
Your VPS's public IP address
Run: ip route | grep default — look for 'dev X'
UDP port WireGuard listens on (default 51820)
VPS = .1, peers = .2, .3… Leave as 10.0.0 unless conflicting
Never share this — keep on VPS only
Share this with each peer client config

// 2 — Peers

Add one peer per client — Ubuntu VM, Gluetun container, phone, etc. Each gets the next tunnel IP automatically. Leave the public key blank and fill it in after you generate it on the peer machine.

// 3 — Port Forwarding

Each port is forwarded to exactly one peer's tunnel IP. Set TCP, UDP, or Both per port.

// Generated wg0.conf — paste onto VPS

Live-generated from your inputs. Copy and paste the full block into /etc/wireguard/wg0.conf on the VPS.
/etc/wireguard/wg0.conf
# Fill in the fields above to generate your config
// Setup Steps — VPS Terminal
// VPS Terminal
Step-by-Step Guide
Run on your fresh Ubuntu 24 VPS — in order
01Log in and update

SSH into your VPS and update all packages before doing anything else.

bash — VPS
ssh root@YOUR_VPS_IP
apt update && apt upgrade -y
02Enable IP forwarding

Allows the VPS to pass traffic through rather than just receiving it. Required for port forwarding to work.

bash
nano /etc/sysctl.conf
Find #net.ipv4.ip_forward=1 — remove the #. Save with Ctrl+X, Y, Enter.
apply without reboot
sysctl -p
You should see net.ipv4.ip_forward = 1 printed back.
03Fix UFW forward policy

UFW has a separate file that blocks all forwarding by default. Normal UFW commands cannot change it — you must edit the file directly.

bash
nano /etc/default/ufw
Find DEFAULT_FORWARD_POLICY="DROP" → change to DEFAULT_FORWARD_POLICY="ACCEPT". Save and close.
04Install WireGuard
bash
apt install wireguard -y
05Generate VPS WireGuard keys

Generates the server private and public key pair. Paste both into the configuration panel at the top.

bash
cd /etc/wireguard
wg genkey | tee server_private.key | wg pubkey > server_public.key
chmod 600 server_private.key
echo "=== PRIVATE KEY (keep secret) ===" && cat server_private.key
echo "=== PUBLIC KEY (share with peers) ===" && cat server_public.key
Paste the private key into VPS Private Key and the public key into VPS Public Key in the config panel above. The generated config will update automatically.
06Find your network interface name

Look for the word immediately after dev — it will be something like eth0, ens3, or enp1s0. Enter it in the Network Interface field above.

bash
ip route | grep default
07Write the WireGuard config

Open the config file then paste the entire block from the generated panel above. Make sure all your keys, peers, and ports are filled in first.

bash
nano /etc/wireguard/wg0.conf
Paste the full generated config. Save with Ctrl+X, Y, Enter.
If a peer's public key is not yet known, comment out that [Peer] block by adding # at the start of each line. Add it later with wg syncconf without restarting.
08Open ports in UFW

Generated from your port configuration above.

bash — generated
# Add ports above to generate
09Add UFW routing rules

Allow forwarded traffic to pass through UFW to each peer. Without these, UFW drops packets before they reach the tunnel.

bash — generated
# Add ports above to generate
10Start WireGuard

Enable WireGuard to start at boot and start it now.

bash
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
wg show
You should see the wg0 interface. No peer handshakes yet is expected — they connect when a client comes online.
To add a peer key later without restarting: edit wg0.conf then run wg syncconf wg0 <(wg-quick strip wg0)
// Verify
Verification Checks
Run after connecting a peer client
V1Check WireGuard handshake

Run on the VPS after a peer connects. Look for a recent handshake timestamp.

bash — VPS
wg show
# latest handshake should be seconds or minutes ago
V2Verify peer traffic exits via VPS IP

Run on the peer client. Must return the VPS IP, not your home IP.

bash — peer client
curl ifconfig.me
# Expected: YOUR_VPS_IP
V3Check iptables rules are clean
bash — VPS
iptables -t nat -L PREROUTING -n -v
# Each port should appear exactly once
# Duplicates? Fix: iptables -t nat -F && systemctl restart wg-quick@wg0
V4Test a forwarded port from outside

With peer connected and a service listening on the port, test reachability. Replace PORT with your forwarded port number.

any external machine
curl -v --max-time 10 http://YOUR_VPS_IP:PORT
A port shows closed if nothing is listening on it at the peer — even with perfect forwarding. The service must be running and bound to that port on the peer client.
// Debug
Troubleshooting
Diagnose common issues layer by layer
!wg-quick fails to start
diagnose
systemctl status wg-quick@wg0.service
journalctl -xeu wg-quick@wg0.service
  • Most common: placeholder text still in PublicKey field instead of a real key
  • Wrong interface name in PostUp lines — must match your actual interface
  • Typo in private key — must be exact base64
  • Peer key unknown: comment out [Peer] block lines with # and start wg0, add key later
!Peer traffic not routing through VPS
check on peer client
sudo wg show
# No handshake: VPS missing peer public key, or wrong endpoint/port
# Handshake exists but leaking: AllowedIPs must be 0.0.0.0/0 on peer
!Forwarded port times out from outside
bash — VPS, run in order
# 1. UFW allowing the port?
ufw status verbose

# 2. iptables DNAT rules loaded?
iptables -t nat -L PREROUTING -n -v

# 3. Packets arriving on VPS? (trigger from outside while running)
tcpdump -i eth0 tcp port PORT -n

# 4. Packets crossing the tunnel?
tcpdump -i wg0 tcp port PORT -n

# 5. Is peer connected?
wg show
Duplicate iptables rules cause misrouting. Fix: iptables -t nat -F && systemctl restart wg-quick@wg0
!Adding a peer after initial setup
bash — VPS
nano /etc/wireguard/wg0.conf
# Add new [Peer] block at bottom, then reload without dropping connections:
wg syncconf wg0 <(wg-quick strip wg0)
!Peer client setup reference

Every peer client needs a wg0.conf with this structure. See the generated client configs above for your specific values pre-filled.

peer client /etc/wireguard/wg0.conf
[Interface]
Address = PEER_TUNNEL_IP/24      # e.g. 10.0.0.2/24
PrivateKey = PEER_PRIVATE_KEY    # generated on the peer machine
DNS = 1.1.1.1

[Peer]
PublicKey = VPS_PUBLIC_KEY       # from your VPS setup above
Endpoint = VPS_IP:WG_PORT       # e.g. 172.245.213.155:51820
AllowedIPs = 0.0.0.0/0          # route all traffic through VPS
PersistentKeepalive = 25        # keeps tunnel alive through NAT
Generate peer keys on the peer machine: wg genkey | tee private.key | wg pubkey > public.key. The peer's public key goes into the VPS wg0.conf [Peer] block. The private key stays on the peer only.