Set Up Your Own WireGuard VPN Server in Under 10 Minutes

Set Up Your Own WireGuard VPN Server in Under 10 Minutes


WireGuard is a modern VPN protocol that’s faster, simpler, and more secure than OpenVPN or IPSec. Its codebase is roughly 4,000 lines of code (compared to OpenVPN’s 100,000+), making it easier to audit and less prone to vulnerabilities. It’s now built into the Linux kernel and works on every major platform.

This guide walks you through setting up your own WireGuard VPN server and connecting clients.

Why Run Your Own VPN?

  • Privacy — Your internet traffic is encrypted between your device and your server
  • Security on public Wi-Fi — All traffic is tunneled through your server
  • Access home network remotely — Reach devices on your LAN from anywhere
  • No subscription fees — A $5/month VPS gives you unlimited VPN usage
  • No logging — You control the server, so there are no third-party logs

Prerequisites

  • A Linux server (VPS) with a public IP — providers like Vultr, DigitalOcean, Linode, or Hetzner offer servers from $4-5/month
  • Ubuntu 22.04+ or Debian 12+ (this guide uses Ubuntu)
  • Root or sudo access

Step 1: Install WireGuard

SSH into your server and install WireGuard:

sudo apt update
sudo apt install -y wireguard

WireGuard is included in the Linux kernel since version 5.6. On older kernels, the package installs the kernel module automatically.

Step 2: Generate Server Keys

# Generate private and public keys
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key

# Set secure permissions
chmod 600 /etc/wireguard/server_private.key

View the keys (you’ll need them for configuration):

cat /etc/wireguard/server_private.key
cat /etc/wireguard/server_public.key

Step 3: Configure the Server

Create the WireGuard interface configuration:

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

# Enable IP forwarding and 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
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32

Replace <SERVER_PRIVATE_KEY> with the output from server_private.key. Replace eth0 with your server’s actual network interface (check with ip route | grep default).

Step 4: Enable IP Forwarding

echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Step 5: Start WireGuard

# Start the interface
sudo wg-quick up wg0

# Enable at boot
sudo systemctl enable wg-quick@wg0

Verify it’s running:

sudo wg show

You should see the interface details, listening port, and any connected peers.

Step 6: Open the Firewall

sudo ufw allow 51820/udp
sudo ufw allow OpenSSH
sudo ufw enable

Step 7: Generate Client Keys

On the server (or on the client machine):

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

Step 8: Add Client to Server

Add the client’s public key to the server config. Edit /etc/wireguard/wg0.conf and add the [Peer] section shown in Step 3, using the client’s public key.

Then reload WireGuard:

sudo wg-quick down wg0 && sudo wg-quick up wg0

Or add peers without restarting:

sudo wg set wg0 peer <CLIENT_PUBLIC_KEY> allowed-ips 10.0.0.2/32

Step 9: Configure Clients

Client Configuration File

Create a configuration file for the client:

[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = 10.0.0.2/24
DNS = 1.1.1.1, 8.8.8.8

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = YOUR_SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
  • AllowedIPs = 0.0.0.0/0 routes all traffic through the VPN (full tunnel)
  • AllowedIPs = 10.0.0.0/24 routes only VPN network traffic (split tunnel)
  • PersistentKeepalive = 25 keeps the connection alive behind NAT

Linux Client

sudo apt install -y wireguard
sudo nano /etc/wireguard/wg0.conf
# Paste the client configuration above
sudo wg-quick up wg0

macOS Client

  1. Install from the App Store: WireGuard for macOS
  2. Click Import Tunnel(s) from File or Add Empty Tunnel
  3. Paste the client configuration
  4. Click Activate

Windows Client

  1. Download from wireguard.com/install
  2. Click Add TunnelAdd empty tunnel
  3. Paste the client configuration
  4. Click Activate

iOS / Android

  1. Install the WireGuard app from App Store or Google Play
  2. You can either:
    • Scan a QR code (easiest — generate on server)
    • Import a .conf file
    • Create from scratch

Generate a QR Code for Mobile

On the server, install qrencode:

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

This prints a QR code directly in your terminal. Open the WireGuard mobile app, tap +, select Create from QR code, and scan.

Adding More Clients

For each new client:

  1. Generate a new key pair
  2. Assign a new IP (10.0.0.3, 10.0.0.4, etc.)
  3. Add a [Peer] section to the server’s wg0.conf
  4. Create a client .conf file
  5. Reload: sudo wg-quick down wg0 && sudo wg-quick up wg0

Quick Setup with wg-easy (Docker)

If you want a web UI for managing WireGuard, use wg-easy:

docker run -d \
  --name wg-easy \
  --restart unless-stopped \
  -e WG_HOST=YOUR_SERVER_IP \
  -e PASSWORD=your-admin-password \
  -v ~/.wg-easy:/etc/wireguard \
  -p 51820:51820/udp \
  -p 51821:51821/tcp \
  --cap-add NET_ADMIN \
  --cap-add SYS_MODULE \
  --sysctl net.ipv4.ip_forward=1 \
  --sysctl net.ipv4.conf.all.src_valid_mark=1 \
  ghcr.io/wg-easy/wg-easy

Access the web UI at http://YOUR_SERVER_IP:51821. You can create clients, download configs, and generate QR codes all from the browser.

Verifying the VPN Works

Once connected, verify your traffic is going through the VPN:

# Check your public IP (should show server IP)
curl ifconfig.me

# Check WireGuard status
sudo wg show

# Ping the server through the tunnel
ping 10.0.0.1

Visit ipleak.net or whatismyipaddress.com in a browser to confirm your IP has changed.

Performance Comparison

ProtocolThroughputLatencyCode Size
WireGuard~800-900 MbpsLow~4,000 lines
OpenVPN~400-500 MbpsMedium~100,000 lines
IPSec/IKEv2~600-700 MbpsMedium~400,000 lines

WireGuard’s performance advantage comes from running in the kernel and using modern cryptographic primitives (ChaCha20, Poly1305, Curve25519, BLAKE2s).

Troubleshooting

Can’t connect to VPN

  • Verify port 51820/udp is open: sudo ss -ulnp | grep 51820
  • Check firewall: sudo ufw status
  • Verify keys match (server has client’s public key, client has server’s public key)
  • Check the endpoint IP is correct in client config

Connected but no internet

  • Verify IP forwarding: cat /proc/sys/net/ipv4/ip_forward (should be 1)
  • Check iptables NAT rule: sudo iptables -t nat -L POSTROUTING
  • Make sure PostUp/PostDown rules use the correct interface name

View connection details

# Server side
sudo wg show wg0

# Shows each peer, last handshake, data transferred

Security Considerations

  1. Protect private keyschmod 600 on all key files
  2. Use a firewall — Only expose port 51820/udp
  3. Update regularlysudo apt update && sudo apt upgrade
  4. Rotate keys periodically — Generate new key pairs every few months
  5. Limit peer access — Use specific AllowedIPs rather than broad ranges
  6. DNS privacy — Use encrypted DNS (1.1.1.1 or 9.9.9.9) in client configs

Conclusion

WireGuard is the easiest VPN to set up and the fastest to use. With just a few commands, you have a fully encrypted tunnel between your devices and your server. Whether you’re securing public Wi-Fi, accessing your home network remotely, or just want privacy from your ISP, a self-hosted WireGuard VPN gives you complete control over your network traffic.