Skip to main content

🔐 Setting Up a VPN Server with WireGuard

Introduction

This guide walks you through setting up your own VPN server using WireGuard on a Raspberry Pi (or any Linux box). This will allow you to:

  1. Securely access your home network when traveling
  2. Encrypt your internet traffic on public Wi-Fi
  3. Access local services (NAS, security cameras, etc.) remotely
  4. Bypass geo-restrictions using your home IP address

We'll cover installation, configuration, client setup, and security best practices.

Prerequisites

  • Raspberry Pi 4 or any Linux server (Ubuntu 20.04+ recommended)
  • Static IP address or Dynamic DNS setup (recommended for home networks)
  • Router with port forwarding capabilities
  • Basic command line knowledge

📝 Note: If you're using a home internet connection with a dynamic IP address (most common), complete the Dynamic DNS setup first. This will give you a stable domain name that always points to your current IP address.

1. Install WireGuard on Your Server

Update your system and install WireGuard:

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

For Raspberry Pi OS, you might need to install additional packages:

sudo apt install -y raspberrypi-kernel-headers

Verify installation:

sudo modprobe wireguard
lsmod | grep wireguard

2. Generate Server Keys

Create a directory for WireGuard configuration:

sudo mkdir -p /etc/wireguard
cd /etc/wireguard

Generate server private and public keys:

# Generate private key
sudo wg genkey | sudo tee server_private.key

# Generate public key from private key
sudo cat server_private.key | wg pubkey | sudo tee server_public.key

# Secure the private key
sudo chmod 600 server_private.key

3. Configure the WireGuard Server

Create the server configuration file:

sudo nano /etc/wireguard/wg0.conf

Add the following configuration:

[Interface]
# Server private key
PrivateKey = YOUR_SERVER_PRIVATE_KEY_HERE

# Server IP address in VPN network
Address = 10.0.0.1/24

# UDP port for VPN connection
ListenPort = 51820

# Save current client configuration
SaveConfig = true

# Enable IP forwarding and NAT rules
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# Example client configuration (add more as needed)
# [Peer]
# PublicKey = CLIENT_PUBLIC_KEY_HERE
# AllowedIPs = 10.0.0.2/32

Replace YOUR_SERVER_PRIVATE_KEY_HERE with your actual server private key:

sudo cat server_private.key

4. Enable IP Forwarding

Enable IP forwarding permanently:

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

5. Configure Firewall

Allow WireGuard through the firewall:

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

6. Start WireGuard Service

Enable and start the WireGuard service:

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

Verify the service is running:

sudo systemctl status wg-quick@wg0
sudo wg show

7. Configure Router Port Forwarding

Access your router's admin panel and forward port 51820 UDP to your server's local IP address.

Common router addresses:

  • 192.168.1.1 or 192.168.0.1
  • 10.0.0.1

🔗 Related: If you haven't set up Dynamic DNS yet, this is a good time to configure it alongside port forwarding. See our Dynamic DNS tutorial for detailed router configuration steps.

8. Set Up Client Configuration

Generate Client Keys

On your server, generate keys for each client:

# Generate client private key
wg genkey | sudo tee client1_private.key

# Generate client public key
sudo cat client1_private.key | wg pubkey | sudo tee client1_public.key

Create Client Configuration

Create a configuration file for your client:

sudo nano client1.conf

Add the following:

[Interface]
# Client private key
PrivateKey = CLIENT_PRIVATE_KEY_HERE

# Client IP address in VPN network
Address = 10.0.0.2/32

# DNS servers (optional)
DNS = 1.1.1.1, 8.8.8.8

[Peer]
# Server public key
PublicKey = SERVER_PUBLIC_KEY_HERE

# Server endpoint (your public IP:port)
Endpoint = YOUR_PUBLIC_IP:51820

# Route all traffic through VPN
AllowedIPs = 0.0.0.0/0

# Keep connection alive
PersistentKeepalive = 25

Replace the placeholders:

  • CLIENT_PRIVATE_KEY_HERE with client private key
  • SERVER_PUBLIC_KEY_HERE with server public key
  • YOUR_PUBLIC_IP with your public IP address or Dynamic DNS domain (e.g., myhomelab.duckdns.org)

💡 Tip: If you set up Dynamic DNS, use your DDNS domain instead of the IP address. This way, your VPN will continue working even if your home IP changes.

Add Client to Server

Add the client to your server configuration:

sudo wg set wg0 peer CLIENT_PUBLIC_KEY_HERE allowed-ips 10.0.0.2/32

Or manually edit /etc/wireguard/wg0.conf and add:

[Peer]
PublicKey = CLIENT_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.2/32

9. Install WireGuard Client

Android/iOS

  1. Install WireGuard from the app store
  2. Import the client configuration file or scan QR code
  3. Enable the VPN connection

Windows/macOS/Linux

  1. Download WireGuard from wireguard.com
  2. Import the configuration file
  3. Activate the tunnel

Generate QR Code (Optional)

For mobile devices, generate a QR code:

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

10. Test Your VPN Connection

  1. Connect from client device
  2. Check your IP address: Visit whatismyipaddress.com
  3. Test local network access: Try accessing local devices (e.g., router admin page)
  4. Verify DNS resolution: Use nslookup or dig to test DNS

11. Security Best Practices

Regular Key Rotation

Rotate keys periodically:

# Generate new server keys
sudo wg genkey | sudo tee server_private_new.key
sudo cat server_private_new.key | wg pubkey | sudo tee server_public_new.key

Firewall Rules

Limit VPN access to specific IPs if needed:

sudo ufw delete allow 51820/udp
sudo ufw allow from TRUSTED_IP to any port 51820

Monitor Connections

Check active connections:

sudo wg show
sudo wg show wg0 dump

Log Monitoring

Monitor VPN logs:

sudo journalctl -u wg-quick@wg0 -f

12. Troubleshooting

Common Issues

VPN connects but no internet:

  • Check IP forwarding: cat /proc/sys/net/ipv4/ip_forward
  • Verify iptables rules: sudo iptables -L -t nat

Cannot reach local network:

  • Update AllowedIPs to include local subnet: 10.0.0.0/24, 192.168.1.0/24

Connection fails:

  • Check firewall rules: sudo ufw status
  • Verify port forwarding on router
  • Check public IP address

Debug Commands

# Check WireGuard status
sudo wg show

# Check service logs
sudo journalctl -u wg-quick@wg0

# Test connectivity
ping 10.0.0.1 # from client
ping 10.0.0.2 # from server

Conclusion

You now have a fully functional VPN server that provides secure remote access to your home network. Remember to:

  • Keep your system updated
  • Regularly rotate keys
  • Monitor connection logs
  • Back up your configuration files

Your VPN server will now allow you to securely access your home network from anywhere in the world, encrypt your traffic on public Wi-Fi, and maintain privacy while browsing.

Happy secure browsing! 🔒