Step 1
Install WireGuard and tools
Update the server and install WireGuard plus qrencode, which can render mobile client configs as QR codes in the terminal.
ssh root@<your-server-ip>
apt update && apt upgrade -y
apt install -y wireguard qrencode ufwStep 2
Generate server and client keys
WireGuard uses public-key authentication. Keep private keys private. The commands below create one server key pair and one client key pair. Add more clients later by generating another pair and another peer block.
umask 077
mkdir -p /etc/wireguard/keys
wg genkey | tee /etc/wireguard/keys/server_private.key | wg pubkey > /etc/wireguard/keys/server_public.key
wg genkey | tee /etc/wireguard/keys/client_private.key | wg pubkey > /etc/wireguard/keys/client_public.keyStep 3
Enable IP forwarding
The server must forward packets between the WireGuard interface and the public network interface. On many VPS images the public interface is eth0, but confirm with ip route.
ip route get 1.1.1.1
cat >/etc/sysctl.d/99-wireguard.conf <<'EOF'
net.ipv4.ip_forward=1
EOF
sysctl --systemStep 4
Create the server config
This example uses 10.8.0.0/24 for VPN clients and UDP 51820. Replace eth0 if your public interface has a different name. The PostUp and PostDown rules handle NAT for client traffic.
SERVER_PRIVATE=$(cat /etc/wireguard/keys/server_private.key)
CLIENT_PUBLIC=$(cat /etc/wireguard/keys/client_public.key)
cat >/etc/wireguard/wg0.conf <<EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = $SERVER_PRIVATE
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = $CLIENT_PUBLIC
AllowedIPs = 10.8.0.2/32
EOF
chmod 600 /etc/wireguard/wg0.confStep 5
Open the firewall and start WireGuard
Allow SSH and WireGuard before enabling UFW. Then start wg0 and enable it at boot.
ufw allow OpenSSH
ufw allow 51820/udp
ufw --force enable
systemctl enable --now wg-quick@wg0
wg showStep 6
Create a client config and QR code
AllowedIPs 0.0.0.0/0 routes all IPv4 traffic through the VPN. Use a public DNS resolver or your own resolver. For split tunneling, replace AllowedIPs with only the networks that should go through WireGuard.
CLIENT_PRIVATE=$(cat /etc/wireguard/keys/client_private.key)
SERVER_PUBLIC=$(cat /etc/wireguard/keys/server_public.key)
SERVER_IP=<your-server-ip>
cat >/root/client.conf <<EOF
[Interface]
PrivateKey = $CLIENT_PRIVATE
Address = 10.8.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = $SERVER_PUBLIC
Endpoint = $SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
qrencode -t ansiutf8 < /root/client.confStep 7
Understand kill switches and privacy
A kill switch is a client-side rule that prevents traffic from leaking outside the VPN if the tunnel drops. Mobile WireGuard apps and desktop firewall tools handle this differently, so test it before relying on it. Also remember that the VPN provider is now you: DNS choices, server logs, browser accounts, and application behavior still affect privacy.
