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:
- A computer running macOS, Linux, or Windows
- Terminal or command-line access
- Administrator or sudo privileges (for system-level changes)
- A stable internet connection for downloading tools
Step 1 - Choose a VPS
Any low-end VPS with a public IP works. Options under $5/month:
- Hetzner Cloud (CX11). €3.29/month, multiple EU/US datacenters
- Vultr (Cloud Compute). $3.50/month
- DigitalOcean (Basic). $4/month
- Oracle Cloud Free Tier. free, but limited bandwidth
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
- Download WireGuard from
https://www.wireguard.com/install/ - Click “Add Tunnel” > “Add empty tunnel” or import a
.conffile - Paste the client configuration
- 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:
- Install WireGuard from App Store / Google Play
- Tap “+” > “Scan from QR code”
- Scan the QR code
- 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
- How to Set Up WireGuard on VPS for Personal VPN
- How to Set Up WireGuard VPN on iPhone for Always-On Privacy
- Wireguard Container Setup Docker Network Namespace Isolation
- How To Set Up Mobile Device Management Profile For Personal
- Privacy Setup for Celebrity - Protecting Personal Address.
- AI Coding Assistant Session Data Lifecycle
Built by theluckystrike. More at zovo.one