How to Set Up a VPN Server on a VPS with WireGuard: Fast, Private, Self-Hosted

How to Set Up a VPN Server on a VPS with WireGuard: Fast, Private, Self-Hosted

WireGuard is a modern VPN protocol that is significantly faster, simpler to configure, and more secure than its predecessors OpenVPN and IPsec. Running WireGuard on your own VPS gives you a private VPN that you fully control — no subscription fees, no usage logs from third-party providers, and the ability to route your traffic through any data center location where you have a VPS. This guide sets up a production-ready WireGuard VPN server in under 30 minutes.

Why Run Your Own WireGuard VPN?

  • Full control: You own the server, the keys, and the logs. No third party can access your traffic or sell your usage data.
  • Performance: WireGuard runs in the Linux kernel and uses state-of-the-art cryptography (ChaCha20, Curve25519, BLAKE2). Benchmarks consistently show WireGuard achieving 2–4x the throughput of OpenVPN.
  • Simplicity: WireGuard’s configuration is remarkably minimal compared to OpenVPN or IPsec — the entire protocol fits in approximately 4,000 lines of code.
  • Cost efficiency: A $5–$10/month VPS running WireGuard costs less than most commercial VPN subscriptions while giving you more flexibility.
  • Geographic flexibility: Host in any location where you have a VPS — useful for accessing regional content or connecting to services that require a specific country IP address.

Prerequisites

  • A KVM VPS running Ubuntu 22.04 LTS with a public IP address
  • Root or sudo access
  • UFW firewall configured (or willingness to adjust firewall rules)
  • WireGuard client installed on your device (available for Windows, macOS, iOS, Android, and Linux)

Step 1: Install WireGuard

sudo apt update
sudo apt install wireguard -y

Verify installation:

wg --version

Step 2: Generate Server Key Pair

WireGuard uses public-key cryptography. Generate the server’s private and public keys:

cd /etc/wireguard
umask 077  # Ensure generated files are private

# Generate server private key
wg genkey | tee server_private.key | wg pubkey > server_public.key

# View the keys (you'll need both shortly)
echo "Private key: $(cat server_private.key)"
echo "Public key: $(cat server_public.key)"

Step 3: Generate a Client Key Pair

Repeat the key generation process for each device (client) you want to connect:

wg genkey | tee client1_private.key | wg pubkey > client1_public.key

echo "Client private key: $(cat client1_private.key)"
echo "Client public key: $(cat client1_public.key)"

Step 4: Create the Server Configuration

First, identify your server’s network interface name:

ip route | grep default | awk '{print $5}'

This typically returns eth0 or ens3. Use this value in the PostUp/PostDown rules below.

sudo nano /etc/wireguard/wg0.conf
[Interface]
# Server private key (paste from server_private.key)
PrivateKey = SERVER_PRIVATE_KEY_HERE
# VPN subnet - this range is used for VPN IP addresses
Address = 10.0.0.1/24
# WireGuard listens on this UDP port
ListenPort = 51820
# Save config changes made with wg set command
SaveConfig = true

# Enable IP forwarding for internet routing
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# Client 1 peer configuration
[Peer]
# Client 1 public key (paste from client1_public.key)
PublicKey = CLIENT1_PUBLIC_KEY_HERE
# IP address assigned to this client within the VPN
AllowedIPs = 10.0.0.2/32

Replace SERVER_PRIVATE_KEY_HERE and CLIENT1_PUBLIC_KEY_HERE with the actual key values. Replace eth0 in the PostUp/PostDown lines with your actual interface name.

Step 5: Enable IP Forwarding

IP forwarding allows the VPS to route traffic from VPN clients to the internet:

sudo nano /etc/sysctl.conf

Find and uncomment (or add):

net.ipv4.ip_forward=1

Apply immediately:

sudo sysctl -p

Step 6: Configure UFW Firewall for WireGuard

# Allow WireGuard's UDP port
sudo ufw allow 51820/udp comment 'WireGuard VPN'

# If UFW's default forward policy is DROP, change it
sudo nano /etc/default/ufw

Find DEFAULT_FORWARD_POLICY and change it to:

DEFAULT_FORWARD_POLICY="ACCEPT"

Also add NAT rules to UFW:

sudo nano /etc/ufw/before.rules

Add these lines at the very top of the file, before the *filter section:

# NAT for WireGuard
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
COMMIT

Reload UFW:

sudo ufw reload

Step 7: Start WireGuard

# Start WireGuard
sudo wg-quick up wg0

# Enable automatic start on boot
sudo systemctl enable wg-quick@wg0

# Check status
sudo wg show

The output of wg show displays the server’s public key, listening port, and any connected peers.

Step 8: Configure the Client

Create the client configuration file. On the client device, open the WireGuard app and add a new tunnel with this configuration:

[Interface]
# Client private key (from client1_private.key)
PrivateKey = CLIENT1_PRIVATE_KEY_HERE
# Client VPN IP address
Address = 10.0.0.2/32
# Use the VPS as DNS server (or use 1.1.1.1, 8.8.8.8)
DNS = 1.1.1.1

[Peer]
# Server public key (from server_public.key)
PublicKey = SERVER_PUBLIC_KEY_HERE
# Server IP and port
Endpoint = YOUR_VPS_IP:51820
# Route all traffic through the VPN
AllowedIPs = 0.0.0.0/0, ::/0
# Keep connection alive (important for NAT traversal)
PersistentKeepalive = 25

AllowedIPs = 0.0.0.0/0 routes all internet traffic through the VPN (full tunnel). For split tunnel (only route VPN subnet traffic), use AllowedIPs = 10.0.0.0/24 instead.

Step 9: Test the VPN Connection

Activate the WireGuard tunnel on your client device and verify:

  1. Visit ifconfig.me — your IP should show the VPS IP address, not your local IP
  2. On the server, run sudo wg show to see your client listed as a connected peer with a recent handshake timestamp
  3. Test DNS resolution: nslookup google.com should resolve correctly

Adding Additional Clients

For each new device, generate a new key pair and add a peer entry to the server config:

# Generate keys for client 2
cd /etc/wireguard
wg genkey | tee client2_private.key | wg pubkey > client2_public.key

# Add peer to running WireGuard instance (no restart needed)
sudo wg set wg0 peer CLIENT2_PUBLIC_KEY_HERE allowed-ips 10.0.0.3/32

# Save the configuration
sudo wg-quick save wg0

Generating QR Codes for Mobile Clients

WireGuard mobile apps (iOS, Android) can scan QR codes to import configuration:

sudo apt install qrencode -y

# Create the client config file and generate QR code
cat client2.conf | qrencode -t ansiutf8

Scan the QR code displayed in your terminal with the WireGuard mobile app to instantly import the configuration.

Security Recommendations

  • Rotate keys periodically: Generate new key pairs for clients every 6–12 months
  • Use pre-shared keys for additional security: wg genpsk generates a pre-shared key that adds symmetric encryption on top of the asymmetric key exchange
  • Revoke access immediately: When a device is lost or an employee leaves, remove their peer entry with sudo wg set wg0 remove peer CLIENT_PUBLIC_KEY
  • Monitor active connections: Regular sudo wg show checks reveal unexpected peers or connections from unusual locations

Getting Started

A WireGuard VPN server runs efficiently on even the smallest VPS plans — a 1 vCPU / 1 GB RAM instance comfortably handles dozens of simultaneous VPN clients. For maximum throughput, a VPS with a fast CPU and low-latency network is more important than raw RAM. USA VPS plans and Hong Kong VPS plans at VPS.DO both work well as WireGuard VPN endpoints, depending on which geographic location best serves your routing needs.

Conclusion

WireGuard on a VPS provides a fast, private, and fully controlled VPN in under 30 minutes of setup time. The configuration is minimal, the performance is excellent, and the cryptographic foundation is state-of-the-art. For anyone who values privacy and already has a VPS, WireGuard is one of the highest-value additions you can make to your server’s functionality.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!