How to Set Up WireGuard VPN on Your VPS for Secure Remote Access

WireGuard is the modern standard for VPN protocols — faster than OpenVPN, simpler to configure, and built directly into the Linux kernel since version 5.6. In this tutorial, you’ll set up a WireGuard VPN server on your VPS and connect clients from Windows, macOS, Linux, or mobile devices. By the end, you’ll have a secure, encrypted tunnel for remote access, privacy, and traffic routing.

Prerequisites

  • A VPS running Ubuntu 22.04 or 24.04 LTS (Debian 11/12 works too)
  • Root or sudo access
  • A registered domain name (optional, for easier DNS)
  • Open UDP port 51820 in your firewall

If you don’t have a VPS yet, compare VPS providers on our comparison table to find one that meets your needs. A 1 vCPU / 1 GB RAM plan is sufficient for dozens of VPN clients.

Step 1: Install WireGuard

SSH into your VPS and run:

sudo apt update
sudo apt install wireguard -y

On newer kernels (5.6+), the WireGuard module is already loaded. Verify with:

sudo modprobe wireguard
lsmod | grep wireguard

Step 2: Generate Keys

WireGuard uses Curve25519 key pairs. Generate the server keys:

cd /etc/wireguard
umask 077
wg genkey | tee server_private_key | wg pubkey > server_public_key

This creates two files. Save the public key — you’ll need it when configuring clients.

Step 3: Create the Server Configuration

Create /etc/wireguard/wg0.conf:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <paste-server-private-key>

# Enable IP forwarding (required for NAT)
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

# Client 1: Laptop
[Peer]
PublicKey = <client1-public-key>
AllowedIPs = 10.0.0.2/32

# Client 2: Phone
[Peer]
PublicKey = <client2-public-key>
AllowedIPs = 10.0.0.3/32

Replace eth0 with your server’s public network interface (check with ip route | grep default). The PostUp/PostDown rules enable NAT so client traffic routes through your server.

Step 4: Enable IP Forwarding

Uncomment net.ipv4.ip_forward=1 in /etc/sysctl.conf, then apply:

sudo sysctl -p

Step 5: Configure the Firewall

Open the WireGuard port and enable forwarding in UFW:

sudo ufw allow 51820/udp
sudo ufw enable

If you’re using iptables directly, add:

sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT

Step 6: Create Client Configurations

On each client machine, generate its own key pair similarly. Then create a client config file (e.g., /etc/wireguard/wg0.conf on Linux, or imported into the WireGuard GUI app on Windows/macOS):

[Interface]
Address = 10.0.0.2/24
PrivateKey = <client-private-key>
DNS = 1.1.1.1, 8.8.8.8

[Peer]
PublicKey = <server-public-key>
Endpoint = your-vps-ip:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

AllowedIPs = 0.0.0.0/0 routes all traffic through the VPN (full tunnel). To only route traffic to your VPS’s subnet, use AllowedIPs = 10.0.0.0/24 instead (split tunnel).

Step 7: Start WireGuard

On the server, start and enable the service:

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

Check the status:

sudo wg show

You should see the interface, the listening port, and each connected peer with transfer statistics.

Step 8: Test the Connection

On the client, bring up the tunnel:

  • Linux: sudo wg-quick up wg0
  • Windows/macOS: Import the config into the official WireGuard app and click Activate
  • iOS/Android: Scan the config QR code (generate with qrencode -t ansiutf8 < client.conf)

Verify your IP is now the VPS’s IP:

curl ifconfig.me

Troubleshooting Common Issues

  • No handshake: Check that UDP port 51820 is open on the server (use nc -u -vz your-vps-ip 51820 from the client). Verify the server’s public key matches in both configs.
  • No internet when connected: Ensure IP forwarding is enabled (sysctl net.ipv4.ip_forward returns 1). Check that MASQUERADE iptables rules are active. Verify the PostUp interface name matches your server’s public interface.
  • DNS not resolving: Set DNS = 1.1.1.1 in the client [Interface] section. On Linux, install resolvconf if needed: sudo apt install resolvconf.
  • Server unreachable: Check if your provider blocks common VPN ports. Consider switching to a non-standard UDP port (e.g., 443 or 51821).
  • Handshake succeeds but no data transfer: Check that AllowedIPs on the server’s [Peer] section matches the client’s tunnel IP.

Performance Tuning and Next Steps

  • Increase MTU: Set MTU = 1420 in the [Interface] section for better throughput on most connections.
  • Set up a QR code: For mobile clients, generate a QR code with qrencode -t ansiutf8 < client.conf.
  • Monitor with wg-show: Run sudo wg show periodically to check latest handshake times and traffic volumes for each peer.
  • Automate client config generation: Use a script like wireguard-manager to add/remove peers without editing config files manually.

WireGuard is one of the best use cases for a budget VPS. If you’re shopping for a provider to host your VPN, check out our VPS comparison table to find plans with good network throughput and low latency.

Leave a Reply