onii@raspberrypi ~ master runbook
root@onii:~$ ./setup-wireguard-vpn --mode=production --interface=wg0
✓ Checking prerequisites... OK
✓ Initializing WireGuard interface... OK
→ Configuring NAT & iptables forwarding rules...
✓ NAT configured on wlan0
✓ Firewall rules applied
Server: 10.155.159.1 | Port: 51820/UDP | Encryption: ChaCha20-Poly1305

Documentation

Raspberry Pi 5 WireGuard LAN Access NAT & Forwarding RDP/SSH Ready ChaCha20-Poly1305

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.

Server LAN: 192.168.1.XX Server VPN: 10.155.159.1 Phone: 10.155.159.X PC: 10.155.159.X UDP Port: 51820

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

Internet Public IP: ***.***.***.*** Home Router (NAT) Port Forward: 51820/UDP → 192.168.1.*** Raspberry Pi 5 — WireGuard Server LAN Interface: 192.168.1.*** (wlan0) VPN Interface: 10.155.159.1 (wg0) NAT: iptables MASQUERADE on wlan0 Encryption: ChaCha20-Poly1305 Home LAN Devices Desktop PC • NAS • Smart Home IoT Network: 192.168.1.0/24 Remote VPN Clients Mobile Phone → 10.155.159.2 Windows PC → 10.155.159.3 MacBook → 10.155.159.4 Endpoint: ***.***.***.***:51820 HTTPS UDP:51820 Forwarding Encrypted Tunnel

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.

  1. Download Raspberry Pi Imager
    On your PC, install Raspberry Pi Imager from raspberrypi.com/software
  2. Choose your configuration
    • Device: Raspberry Pi 5 (or your model)
    • OS: "Raspberry Pi OS (Lite 64-bit)" — desktop is optional
    • Storage: Your microSD card
  3. 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
  4. Write, eject, and boot
    Write the image → Safely eject the card → Insert into Pi → Power it up
  5. Connect via SSH
    From your PC on the same network:
    ssh pivpn@192.168.1.x
    Replace 192.168.1.x with your Pi's actual IP (check your router's DHCP list)
  6. 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

StepWhat to Choose
VPN TypeWireGuard
Static IPAuto-detect or set manually (e.g., 192.168.1.89)
PortDefault 51820 (UDP)
DNS ProviderCloudflare (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.

Pro Tip: Create separate profiles for each device to maintain individual key pairs and enable granular revocation if a device is lost or compromised.

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.

  1. Log into your home router (typically 192.168.1.1 or 192.168.0.1 in a browser)
  2. Find the Port Forwarding, Virtual Server, or NAT section
  3. Add a new forwarding rule with the following configuration:
FieldValueNotes
Name / ServiceWireGuardEasy label for identification
ProtocolUDPWireGuard uses UDP exclusively
WAN Start Port51820External port for incoming connections
WAN End Port51820Same as start port
LAN Host IP192.168.1.***Your Pi's static IP (masked for security)
LAN Host Port51820Same as WAN port

After saving the rule:

REBOOT THE ROUTER
⚠ Security Warning: Only expose UDP 51820. Never forward SSH (22), RDP (3389), or other services directly to the internet — access them securely through the VPN tunnel instead.

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
⚠ Critical: Make sure you do NOT include 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
Why the difference? Adding 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.

Your Device 10.155.159.2 All Traffic WireGuard Tunnel Encrypted (wg0) Internet + LAN Traffic Pi VPN Server NAT → wlan0

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.

Your Device 10.155.159.3 VPN + LAN WireGuard Tunnel Hybrid Routing Internet + LAN Combined Pi + LAN Access Privacy + Devices

Split-tunnel: Internet and home LAN both route through Pi, allowing privacy + remote device access.

📱 Why mobile works without 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 CaseRecommended Mode
Remote desktop + secure browsing on public Wi-FiFull-tunnel (0.0.0.0/0, ::/0)
Access NAS/IoT with home IP visibleSplit-tunnel (0.0.0.0/0, ::/0, 192.168.1.0/24)
Mobile device with automatic routingSplit-tunnel (works without explicit LAN)
Only need home LAN access, keep internet localLAN-only (10.155.159.0/24, 192.168.1.0/24)

Troubleshooting Decision Tree

Connects but no LAN? Handshake OK, services unreachable Check server forwarding ip_forward=1 + NAT on wlan0 Client routes include LAN? AllowedIPs = 0.0.0.0/0, ::/0, 192.168.1.0/24 Unique client IPs/keys? (10.155.159.2 vs .3 vs .4) Windows "General failure"? Add LAN to AllowedIPs Still blocked? Check Windows Firewall ICMP Verify iptables rules on Pi

Follow checks left → right. Most issues stem from routing (AllowedIPs), forwarding (sysctl), or duplicate client IPs.

Common Issues & Solutions

SymptomLikely CauseFix
VPN connects but can't reach internetNAT not configuredCheck iptables MASQUERADE rule on wlan0/eth0
Can reach VPN IP but not LAN devicesMissing LAN subnet in AllowedIPsAdd 192.168.1.0/24 to client config
Handshake never completesPort forwarding issueVerify router forwards UDP 51820 to Pi's IP
Ping shows "General failure" on WindowsRouting table conflictEnsure client AllowedIPs includes LAN subnet
Client can't connect at allPublic IP changedUpdate Endpoint in client config with current public IP
Connection drops after few minutesNAT timeoutAdd 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 = 25 for mobile clients behind NAT
  • Regularly update: sudo apt update && sudo apt upgrade
  • Monitor logs: sudo journalctl -u wg-quick@wg0 -f
  • Use fail2ban for 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

TermDefinition
AllowedIPsOn client: which destinations route through the tunnel. On server: which IPs belong to each peer.
MASQUERADEiptables NAT rule that rewrites source IP so LAN devices can reply to VPN clients.
HandshakeWireGuard key exchange event; must update periodically for a healthy tunnel (every 2 min by default).
wg0The WireGuard network interface on your Pi (virtual tunnel adapter).
wlan0 / eth0Physical network interface — wlan0 for Wi-Fi, eth0 for Ethernet.
PersistentKeepaliveSends periodic packets to keep NAT mappings alive (essential for mobile clients).
EndpointThe server's public IP:port that clients connect to.
PSK (PresharedKey)Optional extra layer of symmetric encryption for quantum resistance.
ChaCha20-Poly1305Modern authenticated encryption cipher used by WireGuard.
Curve25519Elliptic curve used for key exchange in WireGuard.