Skip to content

Setting up VPN Access

This guide explains how to set up various VPN solutions on your Raspberry Pi, including both VPN server (hosting your own VPN) and VPN client (connecting to external VPN services) configurations.

VPN Options Overview

There are several VPN solutions you can implement on Raspberry Pi:

  1. OpenVPN - Traditional, secure, and widely supported
  2. WireGuard - Modern, fast, and lightweight
  3. PiVPN - Simplified OpenVPN/WireGuard installer
  4. Commercial VPN clients - Connecting to services like NordVPN, ExpressVPN

Option 1: Setting up WireGuard VPN Server

WireGuard is the recommended modern VPN solution due to its simplicity and performance.

Installation

1
2
3
4
5
# Update system
sudo apt update && sudo apt upgrade -y

# Install WireGuard
sudo apt install wireguard -y

Generate Keys

# Navigate to WireGuard directory
cd /etc/wireguard

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

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

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

# Generate client public key
sudo cat client_private.key | wg pubkey | sudo tee client_public.key

# Set proper permissions
sudo chmod 600 server_private.key client_private.key

Server Configuration

Create the server configuration file:

sudo nano /etc/wireguard/wg0.conf

Add the following configuration:

[Interface]
PrivateKey = <SERVER_PRIVATE_KEY>
Address = 10.0.0.1/24
ListenPort = 51820
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

[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32

Replace <SERVER_PRIVATE_KEY> and <CLIENT_PUBLIC_KEY> with the generated keys.

Enable IP Forwarding

1
2
3
4
5
# Enable IP forwarding
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf

# Apply changes
sudo sysctl -p

Start WireGuard Service

1
2
3
4
5
6
# Enable and start WireGuard
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

# Check status
sudo systemctl status wg-quick@wg0

Client Configuration

Create a client configuration file:

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

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = <YOUR_PI_PUBLIC_IP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Firewall Configuration

1
2
3
4
5
# Allow WireGuard port through firewall
sudo ufw allow 51820/udp

# Enable UFW if not already enabled
sudo ufw enable

Option 2: Using PiVPN (Automated Setup)

PiVPN provides an easy installation script for both OpenVPN and WireGuard.

Installation

# Download and run PiVPN installer
curl -L https://install.pivpn.io | bash

Follow the interactive installer: 1. Choose your VPN protocol (WireGuard recommended) 2. Configure network settings 3. Set up port forwarding 4. Create certificates/keys

Adding Clients

# Add a new client
pivpn add

# List clients
pivpn list

# Generate QR code for mobile devices
pivpn -qr <client_name>

# Remove a client
pivpn revoke

Managing PiVPN

# Check status
pivpn status

# Restart service
sudo systemctl restart wg-quick@wg0  # For WireGuard
# or
sudo systemctl restart openvpn@server  # For OpenVPN

# View logs
journalctl -u wg-quick@wg0 -f

Option 3: OpenVPN Server Setup

If you prefer OpenVPN over WireGuard:

Installation

1
2
3
4
5
# Install OpenVPN and Easy-RSA
sudo apt install openvpn easy-rsa -y

# Copy Easy-RSA templates
sudo cp -r /usr/share/easy-rsa /etc/openvpn/

Certificate Authority Setup

cd /etc/openvpn/easy-rsa
sudo ./easyrsa init-pki
sudo ./easyrsa build-ca

# Generate server certificate
sudo ./easyrsa gen-req server nopass
sudo ./easyrsa sign-req server server

# Generate Diffie-Hellman parameters
sudo ./easyrsa gen-dh

# Generate TLS authentication key
sudo openvpn --genkey --secret ta.key

Server Configuration

Create /etc/openvpn/server.conf:

sudo nano /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-auth /etc/openvpn/easy-rsa/ta.key 0

server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

keepalive 10 120
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun

status openvpn-status.log
log-append /var/log/openvpn.log
verb 3

Option 4: VPN Client Setup

To connect your Raspberry Pi to commercial VPN services:

OpenVPN Client

1
2
3
4
5
6
7
8
# Install OpenVPN client
sudo apt install openvpn -y

# Download your VPN provider's configuration files
# Example for NordVPN:
cd /etc/openvpn
sudo wget https://downloads.nordcdn.com/configs/archives/servers/ovpn.zip
sudo unzip ovpn.zip

Create credentials file:

sudo nano /etc/openvpn/auth.txt
your_username
your_password
sudo chmod 600 /etc/openvpn/auth.txt

Connect to VPN:

1
2
3
4
5
6
# Connect to specific server
sudo openvpn --config /etc/openvpn/ovpn_udp/us1234.nordvpn.com.udp.ovpn --auth-user-pass /etc/openvpn/auth.txt

# Or set up as service
sudo systemctl enable openvpn@us1234.nordvpn.com.udp
sudo systemctl start openvpn@us1234.nordvpn.com.udp

WireGuard Client

For WireGuard-based VPN services:

# Create client configuration
sudo nano /etc/wireguard/client.conf

Add your provider's configuration, then:

1
2
3
4
5
6
7
8
# Connect
sudo wg-quick up client

# Disconnect
sudo wg-quick down client

# Auto-start on boot
sudo systemctl enable wg-quick@client

Network Configuration

Port Forwarding

Configure your router to forward VPN traffic:

  • WireGuard: Forward UDP port 51820
  • OpenVPN: Forward UDP port 1194 (or your chosen port)

Dynamic DNS Setup

If you don't have a static IP:

1
2
3
4
5
# Install ddclient for dynamic DNS
sudo apt install ddclient -y

# Configure ddclient
sudo nano /etc/ddclient.conf

Example configuration for No-IP:

1
2
3
4
5
6
7
protocol=noip
use=web
web=checkip.dyndns.org
server=dynupdate.no-ip.com
login=your_username
password='your_password'
your_hostname.ddns.net

Security Best Practices

Firewall Rules

1
2
3
4
5
6
# Allow only VPN traffic and SSH
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 51820/udp  # WireGuard
sudo ufw enable

Key Management

1
2
3
4
5
6
# Backup your keys securely
sudo tar -czf wireguard_backup.tar.gz /etc/wireguard/
# Store this backup in a secure location

# Regular key rotation (recommended every 6 months)
# Generate new keys and update configurations

Monitoring

1
2
3
4
5
6
7
8
# Monitor VPN connections
sudo wg show

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

# Monitor network traffic
sudo iftop -i wg0

Performance Optimization

CPU Governor Settings

# Set performance governor for better VPN throughput
echo 'performance' | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

Network Buffer Tuning

Add to /etc/sysctl.conf:

1
2
3
4
5
# Increase network buffers for VPN
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216

Troubleshooting

Common Issues

  1. Can't connect from outside network

    • Check port forwarding on router
    • Verify firewall rules
    • Confirm public IP address
  2. Slow VPN performance

    • Try different ciphers/protocols
    • Check CPU usage
    • Optimize network settings
  3. DNS not working through VPN

    • Check DNS settings in VPN config
    • Test with nslookup through VPN

Diagnostic Commands

# Check VPN interface
ip addr show wg0

# Test connectivity
ping 8.8.8.8

# Check routing table
ip route

# Monitor VPN traffic
sudo tcpdump -i wg0

# Check if VPN is working
curl ipinfo.io/ip

Log Analysis

1
2
3
4
5
6
7
8
# WireGuard logs
sudo journalctl -u wg-quick@wg0

# OpenVPN logs
sudo tail -f /var/log/openvpn.log

# System logs
sudo dmesg | grep -i vpn

Advanced Configuration

Split Tunneling

Configure selective routing through VPN:

1
2
3
4
5
6
# Create custom routing table
echo "200 vpn" | sudo tee -a /etc/iproute2/rt_tables

# Add routes for specific subnets only
sudo ip route add 192.168.100.0/24 dev wg0 table vpn
sudo ip rule add from 192.168.1.0/24 table vpn

Kill Switch

Prevent traffic when VPN is down:

# Block all traffic except VPN
sudo iptables -I OUTPUT ! -o wg0 -m mark ! --mark $(wg show wg0 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

Multi-Client Setup

For multiple simultaneous connections:

1
2
3
4
5
6
7
8
# In server config, add multiple peer sections
[Peer]
PublicKey = <CLIENT1_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32

[Peer]
PublicKey = <CLIENT2_PUBLIC_KEY>
AllowedIPs = 10.0.0.3/32

Monitoring and Maintenance

Automated Monitoring Script

Create /home/pi/vpn_monitor.sh:

#!/bin/bash
# Check if VPN is running and restart if needed

if ! systemctl is-active --quiet wg-quick@wg0; then
    echo "$(date): VPN down, restarting..." >> /var/log/vpn_monitor.log
    systemctl start wg-quick@wg0
fi

# Log connected clients
echo "$(date): $(wg show wg0 peers | wc -l) clients connected" >> /var/log/vpn_stats.log
1
2
3
4
5
# Make executable
chmod +x /home/pi/vpn_monitor.sh

# Add to crontab for regular monitoring
echo "*/5 * * * * /home/pi/vpn_monitor.sh" | crontab -

Usage Statistics

1
2
3
4
5
# Get transfer statistics
sudo wg show wg0 transfer

# Monitor bandwidth usage
sudo vnstat -i wg0

Taking It Further

  • Set up a VPN dashboard with web interface
  • Implement automatic client provisioning
  • Create mobile apps for easy connection
  • Set up site-to-site VPN connections
  • Integrate with home automation systems

This comprehensive VPN setup enables secure remote access to your home network and protects your internet traffic when using public networks.