Logo

Install a WireGuard VPN on a Debian VPS

Install a WireGuard VPN on a Debian VPS

Set up your own modern VPN server with WireGuard in under 15 minutes. Fast, secure protocol, kernel-integrated on Linux, and compatible with all clients (Linux, Windows, macOS, iOS, Android).

Introduction

WireGuard is the modern successor to OpenVPN. It does everything better: 100x smaller codebase (~4000 lines vs ~600000 for OpenVPN), superior performance, state-of-the-art cryptography (Curve25519, ChaCha20, Poly1305, BLAKE2s), and ultra-simple configuration.

Typical uses:

  • Personal VPN to encrypt your traffic on public wifi
  • Secure remote access to your infrastructure (alternative to an SSH bastion)
  • Site-to-site between multiple VPS
  • Anonymity (the VPS serves as exit IP)

Prerequisites

  • Debian 12 or Ubuntu 22.04+ VPS at VeryCloud
  • Root access via SSH
  • UDP port 51820 open (default WireGuard port)
  • IP forwarding which we'll enable

Step 1: Install WireGuard

WireGuard is integrated into Linux kernel 5.6+. On Debian 12 / Ubuntu 22.04+, you just install the tools:

sudo apt update && sudo apt upgrade -y
sudo apt install -y wireguard wireguard-tools qrencode

qrencode generates QR codes to configure mobile clients with a single scan.

Step 2: Enable IP forwarding

sudo nano /etc/sysctl.conf

Uncomment or add:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Apply:

sudo sysctl -p

Step 3: Generate the server keys

cd /etc/wireguard
sudo umask 077
sudo wg genkey | sudo tee server_private.key | sudo wg pubkey | sudo tee server_public.key

View:

sudo cat server_private.key
sudo cat server_public.key

Step 4: Configure the server

sudo nano /etc/wireguard/wg0.conf
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.66.66.1/24
ListenPort = 51820

# Enable NAT so clients reach internet through VPN
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# Peers (clients) will be added below

⚠️ Check your public network interface name with ip route show default | awk '{print $5}'. On VeryCloud, it's usually eth0 or ens3.

Replace SERVER_PRIVATE_KEY with the content of server_private.key.

Step 5: Start WireGuard

sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0

Check the interface:

sudo wg show

Expected output:

interface: wg0
  public key: XXXXXXXXX
  private key: (hidden)
  listening port: 51820

Step 6: Open firewall port

sudo ufw allow 51820/udp
sudo ufw status

On Netrix (VeryCloud customer area), make sure UDP port 51820 is allowed.

Step 7: Add a client (peer)

Generate client keys

On the server (convenient), generate keys for the future client:

cd /etc/wireguard
sudo umask 077
sudo wg genkey | sudo tee client1_private.key | sudo wg pubkey | sudo tee client1_public.key

Create the client config file

sudo nano /etc/wireguard/client1.conf
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.66.66.2/32
DNS = 1.1.1.1, 1.0.0.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = VPS_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
  • AllowedIPs = 0.0.0.0/0: all client traffic goes through VPN (full tunnel)
  • To only route the private network: AllowedIPs = 10.66.66.0/24

Add the peer server-side

Edit server's wg0.conf and add at the end:

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.66.66.2/32

Reload:

sudo systemctl restart wg-quick@wg0

Step 8: Connect a mobile client (with QR code)

For iOS / Android, easiest is to generate a QR code from the client file:

sudo qrencode -t ansiutf8 < /etc/wireguard/client1.conf

A QR code appears in the terminal. Open the WireGuard app on mobile → +Import from QR code → scan.

Step 9: Connect a desktop client

Windows / macOS

  1. Download the official app at https://www.wireguard.com/install/
  2. Add Tunnel → Import tunnel from file
  3. Import client1.conf (transferred via SFTP or copy-pasted)
  4. Activate

Linux

sudo apt install -y wireguard
sudo cp client1.conf /etc/wireguard/wg0.conf
sudo systemctl enable --now wg-quick@wg0

Step 10: Verify the connection

On the connected client:

curl -s https://api.ipify.org

Should return the VPS IP, not your real IP.

Server side:

sudo wg show

You see the peer with its last latest handshake and transferred traffic.

Step 11: Automated client-add script

To make adding clients easier, create a script:

sudo nano /usr/local/bin/wg-add-client.sh
#!/bin/bash
set -e
if [ -z "$1" ]; then echo "Usage: $0 <client_name>"; exit 1; fi

CLIENT=$1
SERVER_IP=$(curl -s https://api.ipify.org)
SERVER_PUBKEY=$(cat /etc/wireguard/server_public.key)
NEXT_IP=$(grep -oP 'AllowedIPs = 10.66.66.\K[0-9]+' /etc/wireguard/wg0.conf | sort -n | tail -1 | awk '{print $1+1}')
NEXT_IP=${NEXT_IP:-2}

cd /etc/wireguard
umask 077
wg genkey | tee ${CLIENT}_private.key | wg pubkey > ${CLIENT}_public.key

cat > ${CLIENT}.conf <<EOF
[Interface]
PrivateKey = $(cat ${CLIENT}_private.key)
Address = 10.66.66.${NEXT_IP}/32
DNS = 1.1.1.1, 1.0.0.1

[Peer]
PublicKey = ${SERVER_PUBKEY}
Endpoint = ${SERVER_IP}:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF

cat >> wg0.conf <<EOF

[Peer]
# ${CLIENT}
PublicKey = $(cat ${CLIENT}_public.key)
AllowedIPs = 10.66.66.${NEXT_IP}/32
EOF

systemctl restart wg-quick@wg0
echo "Client ${CLIENT} created."
echo "QR code:"
qrencode -t ansiutf8 < ${CLIENT}.conf
sudo chmod +x /usr/local/bin/wg-add-client.sh
sudo wg-add-client.sh alice

Troubleshooting

Tunnel comes up but no traffic passes

Check IP forwarding:

sysctl net.ipv4.ip_forward

Must return 1.

Check iptables rules:

sudo iptables -L FORWARD -v
sudo iptables -t nat -L POSTROUTING -v

"Resource temporarily unavailable"

Often due to a kernel/module version mismatch. Update:

sudo apt full-upgrade -y
sudo reboot

High latency

Rare with WireGuard. If it happens, check:

  • MTU: try MTU = 1420 in the [Interface] section
  • VPS CPU load (WireGuard uses AES/ChaCha20 encryption, can saturate a small VPS)

Peer doesn't connect

On the client side, check that Endpoint points to the right IP and port. Test UDP connectivity:

nc -u VPS_IP 51820

Useful commands

# Interface status
sudo wg show

# Service status
sudo systemctl status wg-quick@wg0

# Restart
sudo systemctl restart wg-quick@wg0

# Live peer monitoring
sudo watch -n 1 wg show

# Count peers
grep -c "\[Peer\]" /etc/wireguard/wg0.conf

# Disable tunnel
sudo wg-quick down wg0

# Re-enable
sudo wg-quick up wg0

Conclusion

Your WireGuard VPN is operational. Going further:

  • Install wg-easy (web UI to manage peers easily)
  • Combine with internal DNS (Pi-hole, AdGuard) to block ads on top of encryption
  • Set up a kill switch client-side (no traffic if VPN drops)
  • Configure a site-to-site VPN between multiple VPS for a global private network

Resources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members