Last updated: March 21, 2026

WireGuard is a VPN protocol that is faster, simpler, and more auditable than OpenVPN or IPSec. A personal WireGuard VPN on a $5/month VPS costs less than any commercial VPN subscription, and you own the server. no logging policy to trust.

This guide builds a complete WireGuard server from scratch with clients for every platform.

Prerequisites

Before you begin, make sure you have the following ready:

Step 1 - Choose a VPS

Any low-end VPS with a public IP works. Options under $5/month:

Pick a datacenter location that gives you the exit geography you want. An Amsterdam server makes your traffic appear to come from the Netherlands.

Choose Ubuntu 22.04 or Debian 12 as the OS.

Step 2 - Server Setup

SSH into your new VPS and update it:

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

Generate Server Keys

Generate the server's private and public key pair
wg genkey | sudo tee /etc/wireguard/server-private.key | wg pubkey | sudo tee /etc/wireguard/server-public.key

Set restrictive permissions
sudo chmod 600 /etc/wireguard/server-private.key

View the keys (you'll need these)
cat /etc/wireguard/server-private.key
cat /etc/wireguard/server-public.key

Generate Client Keys

Generate a key pair for each client (do this now for all clients you plan to add):

Client 1 - laptop
wg genkey | tee /tmp/laptop-private.key | wg pubkey > /tmp/laptop-public.key

Client 2 - phone
wg genkey | tee /tmp/phone-private.key | wg pubkey > /tmp/phone-public.key

Client 3 - tablet
wg genkey | tee /tmp/tablet-private.key | wg pubkey > /tmp/tablet-public.key

Find Your Server’s Network Interface

ip route | grep default
default via 95.216.1.1 dev eth0 proto dhcp src 95.216.1.234 metric 100
Interface name is eth0 in this example

Your interface may be eth0, ens3, enp1s0. check and use the correct one below.

Create the Server Configuration

sudo nano /etc/wireguard/wg0.conf
[Interface]
The WireGuard server's IP on the VPN network
Address = 10.0.0.1/24

Port WireGuard listens on (can be any UDP port; 51820 is conventional)
ListenPort = 51820

Your server's private key
PrivateKey = <contents of /etc/wireguard/server-private.key>

Enable NAT so VPN traffic gets forwarded to the internet
Replace eth0 with your actual network interface
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

If using IPv6, also add:
PostUp = ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

--- Client 1: Laptop ---
[Peer]
PublicKey = <contents of /tmp/laptop-public.key>
Assign this client the .2 address on the VPN network
AllowedIPs = 10.0.0.2/32

--- Client 2: Phone ---
[Peer]
PublicKey = <contents of /tmp/phone-public.key>
AllowedIPs = 10.0.0.3/32

--- Client 3: Tablet ---
[Peer]
PublicKey = <contents of /tmp/tablet-public.key>
AllowedIPs = 10.0.0.4/32

Enable IP Forwarding

Enable now
sudo sysctl -w net.ipv4.ip_forward=1

Persist across reboots
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf

Start the WireGuard Interface

Start WireGuard
sudo wg-quick up wg0

Enable on boot
sudo systemctl enable wg-quick@wg0

Check status
sudo wg show

Expected output:

interface: wg0
 public key: <server-public-key>
 private key: (hidden)
 listening port: 51820

Open the Firewall Port

UFW
sudo ufw allow 51820/udp
sudo ufw reload

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

Step 3 - Client Configuration

Create a config for each client. Replace variables with your actual keys and server IP.

Linux Client

[Interface]
Client's private key
PrivateKey = <contents of /tmp/laptop-private.key>
Client's VPN IP
Address = 10.0.0.2/24
Use the VPN server as DNS (optional: use Cloudflare or your own)
DNS = 1.1.1.1

[Peer]
Server's public key
PublicKey = <contents of /etc/wireguard/server-public.key>
Route all traffic through VPN (0.0.0.0/0 = full tunnel)
AllowedIPs = 0.0.0.0/0, ::/0
Server's public IP and port
Endpoint = YOUR_SERVER_PUBLIC_IP:51820
Keep connection alive through NAT
PersistentKeepalive = 25

Save as ~/wireguard-laptop.conf and connect:

Install WireGuard
sudo apt install wireguard

Copy config
sudo cp ~/wireguard-laptop.conf /etc/wireguard/wg0.conf

Connect
sudo wg-quick up wg0

Verify traffic is going through VPN
curl ifconfig.me # Should show your VPS IP, not your home IP

macOS Client

Install the WireGuard app from the Mac App Store, or via Homebrew:

brew install wireguard-tools

Create the config file at ~/wireguard-laptop.conf with the same content as the Linux config above, then:

sudo wg-quick up ~/wireguard-laptop.conf

Or use the WireGuard GUI app - File > Import tunnel from file.

Windows Client

  1. Download WireGuard from https://www.wireguard.com/install/
  2. Click “Add Tunnel” > “Add empty tunnel” or import a .conf file
  3. Paste the client configuration
  4. Click “Activate”

iOS and Android

Generate a QR code from the client config file to scan with the WireGuard mobile app:

Install qrencode
sudo apt install qrencode

Generate QR from config
qrencode -t ansiutf8 < /tmp/phone-wireguard.conf

On mobile:

  1. Install WireGuard from App Store / Google Play
  2. Tap “+” > “Scan from QR code”
  3. Scan the QR code
  4. Toggle the tunnel on

Step 4 - Verify the VPN Is Working

From a connected client:

Check your public IP. should show the VPS IP
curl https://ifconfig.me

Check for DNS leaks
Visit https://dnsleaktest.com. should show your VPN server's DNS

Verify WireGuard connection
sudo wg show
Should show handshake timestamp and data transfer for active peers

Check handshake timestamps on the server:

sudo wg show wg0
latest handshake: 2 minutes, 15 seconds ago
transfer: 1.23 MiB received, 4.56 MiB sent

Step 5 - Add a New Client Without Downtime

You can add peers without restarting WireGuard:

Generate new client keys
wg genkey | tee /tmp/newclient-private.key | wg pubkey > /tmp/newclient-public.key

Add the peer to the running interface
sudo wg set wg0 peer <newclient-public-key> allowed-ips 10.0.0.5/32

Persist to config file
echo -e "\n[Peer]\nPublicKey = $(cat /tmp/newclient-public.key)\nAllowedIPs = 10.0.0.5/32" | sudo tee -a /etc/wireguard/wg0.conf

Troubleshooting

Configuration changes not taking effect

Restart the relevant service or application after making changes. Some settings require a full system reboot. Verify the configuration file path is correct and the syntax is valid.

Permission denied errors

Run the command with sudo for system-level operations, or check that your user account has the necessary permissions. On macOS, you may need to grant terminal access in System Settings > Privacy & Security.

Connection or network-related failures

Check your internet connection and firewall settings. If using a VPN, try disconnecting temporarily to isolate the issue. Verify that the target server or service is accessible from your network.

Frequently Asked Questions

Who is this article written for?

This article is written for developers, technical professionals, and power users who want practical guidance. Whether you are evaluating options or implementing a solution, the information here focuses on real-world applicability rather than theoretical overviews.

How current is the information in this article?

We update articles regularly to reflect the latest changes. However, tools and platforms evolve quickly. Always verify specific feature availability and pricing directly on the official website before making purchasing decisions.

Does WireGuard offer a free tier?

Most major tools offer some form of free tier or trial period. Check WireGuard’s current pricing page for the latest free tier details, as these change frequently. Free tiers typically have usage limits that work for evaluation but may not be sufficient for daily professional use.

Can I trust these tools with sensitive data?

Review each tool’s privacy policy, data handling practices, and security certifications before using it with sensitive data. Look for SOC 2 compliance, encryption in transit and at rest, and clear data retention policies. Enterprise tiers often include stronger privacy guarantees.

What is the learning curve like?

Most tools discussed here can be used productively within a few hours. Mastering advanced features takes 1-2 weeks of regular use. Focus on the 20% of features that cover 80% of your needs first, then explore advanced capabilities as specific needs arise.

Related Articles

Built by theluckystrike. More at zovo.one