Overview
We built a remote-access VPN so your phone, PC, and any systems can reach any 192.168.1.x device at home from anywhere. The Raspberry Pi terminates WireGuard on wg0, then forwards traffic to your home LAN via wlan0 with NAT masquerading. Each client receives unique cryptographic keys and a dedicated VPN IP.
Pros & Cons
✓ Advantages
- Minimal latency — WireGuard is significantly faster than OpenVPN
- Simple configuration — PiVPN automates most setup steps
- End-to-end encrypted — Modern cryptography (ChaCha20, Poly1305)
- Low maintenance — Runs as a systemd service with auto-restart
- Cross-platform — Works on iOS, Android, Windows, macOS, Linux
⚠ Considerations
- Port forwarding required — Some ISPs block or restrict this
- Uptime dependency — Must maintain stable power and internet
- Single point of failure — If Pi goes down, VPN is unavailable
- Dynamic IP challenges — May need DDNS for changing IPs
Network Topology Diagram
Client devices connect to your public IP on UDP 51820 → Router forwards to Pi → Pi decrypts on wg0 interface → Forwards to LAN via wlan0 using iptables NAT masquerading
Phase 1: Install Raspberry Pi OS
Start by flashing Raspberry Pi OS to your microSD card using the official imaging tool.
-
Download Raspberry Pi Imager
On your PC, install Raspberry Pi Imager from raspberrypi.com/software -
Choose your configuration
- Device: Raspberry Pi 5 (or your model)
- OS: "Raspberry Pi OS (Lite 64-bit)" — desktop is optional
- Storage: Your microSD card
-
Configure advanced settings (⚙️ gear icon)
- Set username =
pivpn - Set secure password (e.g.,
mypi123) - Enable SSH with password authentication
- Configure Wi-Fi credentials or use Ethernet
- Set username =
-
Write, eject, and boot
Write the image → Safely eject the card → Insert into Pi → Power it up -
Connect via SSH
From your PC on the same network:
Replacessh pivpn@192.168.1.x192.168.1.xwith your Pi's actual IP (check your router's DHCP list) -
Update the system
sudo apt update && sudo apt full-upgrade -y sudo reboot
Phase 2: Install WireGuard VPN (via PiVPN)
PiVPN is a convenient installer that automates WireGuard setup, profile generation, and firewall rules.
Run the installer
curl -L https://install.pivpn.io | bash
Installation prompts
| Step | What to Choose |
|---|---|
| VPN Type | WireGuard |
| Static IP | Auto-detect or set manually (e.g., 192.168.1.89) |
| Port | Default 51820 (UDP) |
| DNS Provider | Cloudflare (1.1.1.1) or Quad9 (9.9.9.9) |
| Unattended Upgrades | ✅ Enable (recommended for security patches) |
After installation completes:
sudo reboot
Phase 3: Create Your VPN Profiles
After the Pi reboots, create individual profiles for each device that will connect to your VPN.
Add a new client
pivpn add
Give it a simple name (e.g., phone or laptop). PiVPN generates the config file at:
/home/pivpn/configs/phone.conf
Display QR code for mobile setup
pivpn -qr
Scan this QR code with the WireGuard mobile app (iOS/Android) to import the profile instantly.
Phase 4: Router Port Forwarding
Why? You must allow VPN traffic from the internet to reach your Pi. Without port forwarding, external clients cannot establish a connection.
- Log into your home router (typically
192.168.1.1or192.168.0.1in a browser) - Find the Port Forwarding, Virtual Server, or NAT section
- Add a new forwarding rule with the following configuration:
| Field | Value | Notes |
|---|---|---|
| Name / Service | WireGuard | Easy label for identification |
| Protocol | UDP | WireGuard uses UDP exclusively |
| WAN Start Port | 51820 | External port for incoming connections |
| WAN End Port | 51820 | Same as start port |
| LAN Host IP | 192.168.1.*** | Your Pi's static IP (masked for security) |
| LAN Host Port | 51820 | Same as WAN port |
After saving the rule:
REBOOT THE ROUTER
Phase 5: Server Config (/etc/wireguard/wg0.conf)
This file is auto-generated by PiVPN when you add clients. Here's what a typical configuration looks like:
[Interface]
PrivateKey = <SERVER_PRIVATE_KEY>
Address = 10.155.159.1/24
ListenPort = 51820
MTU = 1420
# Phone (10.155.159.2)
[Peer]
PublicKey = <MOBILE_PUBLIC_KEY>
PresharedKey = <PSK>
AllowedIPs = 10.155.159.2/32
# PC (10.155.159.3)
[Peer]
PublicKey = <PC_PUBLIC_KEY>
PresharedKey = <PSK>
AllowedIPs = 10.155.159.3/32
192.168.1.0/24 in the server's AllowedIPs field. The server config defines which IPs belong to each peer, not which destinations they can reach. Adding your LAN range here will break routing.
Auto-generated by pivpn add command
Phase 6: Client Configuration
Each client needs a profile that tells WireGuard how to connect and what traffic to route through the tunnel.
Mobile Client (Phone)
PiVPN generates this automatically. Use pivpn -qr to scan the QR code or manually transfer the .conf file.
[Interface]
PrivateKey = <MOBILE_PRIVATE_KEY>
Address = 10.155.159.2/24
DNS = 9.9.9.9, 149.112.112.112
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <PSK>
Endpoint = <YOUR_PUBLIC_IP>:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
Windows PC Client
Download WireGuard for Windows and import this config: Use pivpn add to create the profile.
[Interface]
PrivateKey = <PC_PRIVATE_KEY>
Address = 10.155.159.3/24
DNS = 9.9.9.9, 149.112.112.112
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <PSK>
Endpoint = <YOUR_PUBLIC_IP>:51820
AllowedIPs = 0.0.0.0/0, ::/0, 192.168.1.0/24
PersistentKeepalive = 25
192.168.1.0/24 to the PC's AllowedIPs ensures proper LAN discovery for apps like Remote Desktop, SMB shares, and network printers. Mobile clients often work without this because their VPN stack automatically routes LAN subnets under 0.0.0.0/0.
Read detailed explanation of AllowedIPs & routing modes
Phase 7: IP Forwarding & NAT Rules
These settings allow your Pi to act as a router, forwarding VPN traffic to your LAN and back.
Enable IP Forwarding
sudo nano /etc/sysctl.conf
Ensure these lines are present and uncommented (remove the # if present):
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
Save the file (Ctrl+O, Enter, Ctrl+X) and apply the changes:
sudo sysctl -p
Configure NAT & Traffic Forwarding
These iptables rules allow bidirectional traffic between wg0 (VPN interface) and wlan0 (Wi-Fi interface). If your Pi uses Ethernet, replace wlan0 with eth0.
For Wi-Fi (wlan0)
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
For Ethernet (eth0)
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Verify your interface name:
ip a
Make Rules Persistent
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
Restart WireGuard
sudo systemctl restart wg-quick@wg0
Phase 8: Verify & Test
On the Raspberry Pi
sudo wg
Look for recent handshakes and non-zero transfer counters:
interface: wg0
peer: <PC_PUBLIC_KEY>
endpoint: ***.***.***.***:xxxxx
allowed ips: 10.155.159.3/32
latest handshake: 12 seconds ago
transfer: 2.51 KiB received, 1.83 KiB sent
Check both IP addresses are assigned:
hostname -I
Should show: 192.168.1.*** 10.155.159.1
From a VPN Client
ping 10.155.159.1
Tests connectivity to the Pi via VPN tunnel.
ping 192.168.1.***
Tests LAN IP accessibility through tunnel.
curl ifconfig.me
Should return your home's public IP (confirms full-tunnel routing).
Optional: Static Route for True LAN Visibility
If you want devices on your home LAN to directly see and initiate connections to VPN clients (e.g., ping 10.155.159.2 from a LAN PC), add a static route in your router:
- Destination:
10.155.159.0 - Subnet mask:
255.255.255.0 - Gateway:
192.168.1.***(your Pi's IP)
Look for this in your router's Advanced → Static Routing section.
AllowedIPs & Routing Modes Explained
WireGuard decides which traffic goes through the VPN using the AllowedIPs field in your client config. Understanding this setting is crucial for proper operation.
Full-Tunnel Mode (AllowedIPs = 0.0.0.0/0, ::/0)
All network traffic — internet and LAN — is sent through the VPN tunnel to your Raspberry Pi. This provides complete encryption and makes your device appear to browse from your home IP.
Full-tunnel: All traffic (internet + LAN) routes through VPN; Pi forwards via wlan0 using NAT.
✓ Advantages
- Maximum security and privacy
- Your IP appears as your home network
- Protects all traffic on untrusted networks
- Bypasses geographic restrictions
⚠ Trade-offs
- Higher latency for all internet traffic
- Full dependency on Pi uptime
- Uses more home bandwidth
- May be slower on mobile data
Split-Tunnel with LAN (AllowedIPs = 0.0.0.0/0, ::/0, 192.168.1.0/24)
This hybrid mode routes all traffic through the VPN (like full-tunnel) but explicitly includes the home LAN subnet. On Windows, adding 192.168.1.0/24 ensures proper routing table priority for LAN services.
Split-tunnel: Internet and home LAN both route through Pi, allowing privacy + remote device access.
192.168.1.0/24:Mobile OS implementations (Android/iOS WireGuard apps) automatically route all traffic matching
0.0.0.0/0, which includes LAN subnets as a subset. Windows maintains separate routing tables and requires explicit inclusion of the LAN range to avoid conflicts with its physical network adapter.
✓ Advantages
- Complete LAN device access (RDP, SMB, printers)
- Still encrypted and secure
- Works around Windows routing quirks
- Network discovery enabled
⚠ Trade-offs
- Can cause routing conflicts if misconfigured
- Slightly more complex troubleshooting
- Still routes all internet through VPN
LAN-Only Mode (AllowedIPs = 10.155.159.0/24, 192.168.1.0/24)
For users who only need access to home devices (not full internet through VPN), this mode keeps your regular internet connection local while tunneling only VPN and LAN traffic.
| Use Case | Recommended Mode |
|---|---|
| Remote desktop + secure browsing on public Wi-Fi | Full-tunnel (0.0.0.0/0, ::/0) |
| Access NAS/IoT with home IP visible | Split-tunnel (0.0.0.0/0, ::/0, 192.168.1.0/24) |
| Mobile device with automatic routing | Split-tunnel (works without explicit LAN) |
| Only need home LAN access, keep internet local | LAN-only (10.155.159.0/24, 192.168.1.0/24) |
Troubleshooting Decision Tree
Follow checks left → right. Most issues stem from routing (AllowedIPs), forwarding (sysctl), or duplicate client IPs.
Common Issues & Solutions
| Symptom | Likely Cause | Fix |
|---|---|---|
| VPN connects but can't reach internet | NAT not configured | Check iptables MASQUERADE rule on wlan0/eth0 |
| Can reach VPN IP but not LAN devices | Missing LAN subnet in AllowedIPs | Add 192.168.1.0/24 to client config |
| Handshake never completes | Port forwarding issue | Verify router forwards UDP 51820 to Pi's IP |
| Ping shows "General failure" on Windows | Routing table conflict | Ensure client AllowedIPs includes LAN subnet |
| Client can't connect at all | Public IP changed | Update Endpoint in client config with current public IP |
| Connection drops after few minutes | NAT timeout | Add PersistentKeepalive = 25 to client config |
Operations & Day-2 Tips
Common Management Commands
pivpn add # Add new client profile
pivpn -qr # Show QR code for mobile
pivpn list # List all peers
pivpn remove # Revoke a client
sudo wg # Show handshakes & traffic
sudo wg show wg0 transfer # Per-peer data transfer
sudo systemctl restart wg-quick@wg0
sudo netfilter-persistent save
Security Hardening
- Disable password SSH once key-based auth is configured
- Only expose UDP 51820; never forward SSH/RDP to internet
- Use
PersistentKeepalive = 25for mobile clients behind NAT - Regularly update:
sudo apt update && sudo apt upgrade - Monitor logs:
sudo journalctl -u wg-quick@wg0 -f - Use
fail2banfor additional SSH protection
Performance Monitoring
sudo wg show wg0 transfer # Check data transfer per peer
sudo journalctl -u wg-quick@wg0 -f # Live WireGuard logs
htop # Monitor CPU/RAM usage
vnstat -i wg0 # Network statistics for wg0 interface
Glossary
| Term | Definition |
|---|---|
| AllowedIPs | On client: which destinations route through the tunnel. On server: which IPs belong to each peer. |
| MASQUERADE | iptables NAT rule that rewrites source IP so LAN devices can reply to VPN clients. |
| Handshake | WireGuard key exchange event; must update periodically for a healthy tunnel (every 2 min by default). |
| wg0 | The WireGuard network interface on your Pi (virtual tunnel adapter). |
| wlan0 / eth0 | Physical network interface — wlan0 for Wi-Fi, eth0 for Ethernet. |
| PersistentKeepalive | Sends periodic packets to keep NAT mappings alive (essential for mobile clients). |
| Endpoint | The server's public IP:port that clients connect to. |
| PSK (PresharedKey) | Optional extra layer of symmetric encryption for quantum resistance. |
| ChaCha20-Poly1305 | Modern authenticated encryption cipher used by WireGuard. |
| Curve25519 | Elliptic curve used for key exchange in WireGuard. |