Privacy Tools Guide

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.

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.

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
# Example: 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

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

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

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

Built by theluckystrike — More at zovo.one