pfSense WireGuard VPN: Road Warrior Setup for Remote Access
Configure WireGuard on pfSense for secure remote access to your homelab — covers server setup, peer configuration, firewall rules, DNS split-tunneling
WireGuard is the modern choice for pfSense VPN — it’s faster, simpler, and more battery-efficient than OpenVPN. On current pfSense it is available as an installable package (and on recent pfSense Plus it’s integrated); the exact availability depends on your version, so check System → Package Manager / VPN → WireGuard rather than assuming. If you’re still weighing the protocols, the OpenVPN vs WireGuard comparison ↗ covers throughput, the Plus-only DCO offload, and the auth features that still favor OpenVPN. This guide sets up a road warrior configuration for remote access to your home network.
Two prerequisites determine whether this will work at all. First, inbound reachability: WireGuard listens on a UDP port that must be reachable from the internet. If your pfSense WAN is behind another router/ISP CGNAT, a single port-forward on the upstream device — or a different remote-access approach entirely — is required; CGNAT (common on mobile/4G/5G and some fiber ISPs) blocks unsolicited inbound and WireGuard road-warrior will not work without a relay. Second, a stable endpoint: clients connect to an IP or hostname. Without a static IP you need Dynamic DNS (covered below). Sort both before configuring tunnels, or you’ll have a working tunnel that no client can reach.
Concepts
WireGuard uses a peer model: the pfSense router is the server (called the “tunnel interface”), and each remote device is a peer. Each peer has a public/private keypair. The server knows each peer’s public key; each peer knows the server’s public key and endpoint.
Step 1: Install WireGuard (pfSense CE)
System → Package Manager → Available Packages → search WireGuard → Install.
On pfSense Plus, WireGuard is built-in — skip this step.
After install: VPN → WireGuard.
Step 2: Create the tunnel interface
VPN → WireGuard → Tunnels → Add Tunnel:
- Description: WG_RoadWarrior
- Listen Port: 51820 (default; can change for obscurity)
- Interface Keys: Generate — click the Generate button to create a server keypair
- Interface Address: 10.10.0.1/24 (WireGuard subnet — separate from your LAN)
- DNS Server: 192.168.1.1 (your pfSense LAN IP, or a split-DNS resolver)
Save. Note the Public Key — you’ll need it for client configs.
Step 3: Add peers (clients)
VPN → WireGuard → Peers → Add Peer:
For each client device:
- Tunnel: WG_RoadWarrior
- Description: iPhone (or laptop, etc.)
- Public Key: paste the client’s WireGuard public key
- Allowed IPs: 10.10.0.2/32 (unique IP per peer within the WireGuard subnet)
- Persistent keepalive: 25 (recommended for mobile clients behind NAT)
Generating client keys
On Linux/macOS:
wg genkey | tee private.key | wg pubkey > public.key
cat public.key # paste this into pfSense as the peer's public key
On iOS/Android: the WireGuard app generates the keypair in-app.
Allowed IPs is the most misunderstood field. On the server’s peer entry it defines which source addresses that peer is permitted to use inside the tunnel — for a road-warrior client this is its single tunnel IP as a /32, not your LAN subnet. Putting your LAN here on the server side, or a broad range, causes routing/cryptokey-routing conflicts. The client config’s AllowedIPs (Step 6) is what controls what the client routes into the tunnel; don’t confuse the two.
Step 4: Assign the WireGuard interface
Interfaces → Assignments → select the WireGuard tunnel from the drop-down → Add → Enable interface → Save. Assigning the interface (rather than leaving it tunnel-only) is what lets you write explicit firewall rules and makes the tunnel a proper routing/NAT participant — do this even though basic connectivity sometimes appears to work without it; the firewall rule tab won’t exist otherwise.
Step 5: Firewall rules
WAN rule — allow WireGuard UDP
Firewall → Rules → WAN → Add:
Action: Pass
Protocol: UDP
Destination: WAN address
Destination Port: 51820
Description: Allow WireGuard inbound
WireGuard interface rule — allow traffic to LAN
Firewall → Rules → WireGuard → Add:
Action: Pass
Protocol: Any
Source: WireGuard subnets (10.10.0.0/24)
Destination: LAN subnets
Description: WireGuard peers access LAN
Step 6: Client configuration
Create a .conf file for each peer:
[Interface]
PrivateKey = <peer private key>
Address = 10.10.0.2/32
DNS = 192.168.1.1
[Peer]
PublicKey = <pfSense WireGuard public key>
Endpoint = your-home-ip-or-ddns:51820
AllowedIPs = 192.168.1.0/24, 10.10.0.0/24
PersistentKeepalive = 25
For full-tunnel (route all traffic through pfSense): set AllowedIPs = 0.0.0.0/0, ::/0.
Import the .conf file into the WireGuard app on your device, or scan the QR code (the WireGuard app can display a QR code from the config).
Step 7: DDNS (if you don’t have a static IP)
System → Dynamic DNS → Add:
- Choose your DDNS provider (CloudFlare, DuckDNS, etc.)
- Set the hostname your clients will use as the endpoint
Use this hostname in client configs instead of a raw IP.
Verify the connection
# On the pfSense console or via SSH:
wg show
# Should show the peer with a recent handshake timestamp and traffic counters
From the client, ping 192.168.1.1 — you should reach your pfSense LAN interface, then test reaching an actual LAN host by IP. This same tunnel is the recommended way to reach the web GUI remotely without ever exposing it to the internet, as the pfSense initial setup hardening checklist ↗ spells out.
Troubleshooting (in diagnostic order)
Work from the outside in — each step isolates a layer:
- No handshake at all (
wg showshows no recent handshake). Almost always the inbound path: the WAN firewall rule isn’t passing UDP to the listen port, the upstream router/CGNAT is dropping it, or the client’sEndpointis wrong/stale. Test from a network you control:nc -u -z your-endpoint 51820won’t prove much for UDP, so rely on the handshake timestamp. Temporarily check the pfSense firewall log for the inbound packets. - Handshake succeeds but no traffic passes. This is a routing/rules problem, not a crypto one. Check: the WireGuard-interface firewall rule allows the client subnet to the destinations you want; the client’s
AllowedIPsincludes the LAN subnet you’re trying to reach; and Outbound NAT covers the WireGuard subnet if LAN hosts have no route back (the simplest fix for “I can ping the firewall but not LAN devices” is hybrid Outbound NAT translating the WG subnet on the LAN interface, or static routes/host firewalls that accept the WG range). - Works on Wi-Fi but not cellular (or vice-versa). Usually
PersistentKeepalivemissing on a NAT’d client, or an MTU issue — try lowering the client interface MTU (e.g., 1380–1420) if large packets stall while the handshake works. - DNS doesn’t resolve over the tunnel. The client
DNS =must be a resolver reachable through the tunnel (the pfSense LAN IP), and the pfSense DNS Resolver must accept queries from the WG subnet (Services → DNS Resolver → ACLs/network ACLs).
wg show (console/SSH) is the single best diagnostic: a recent handshake + incrementing rx/tx confirms the tunnel itself; the absence of either points you to the layer above.
When WireGuard road-warrior is the wrong approach
If your ISP uses CGNAT and you can’t get an inbound port or a static/forwarded endpoint, a self-hosted listening VPN simply won’t work — a managed mesh/overlay (which uses an outbound-initiated relay) or a small public relay is the right tool instead, and forcing WireGuard here wastes hours. If you only need occasional access to a single web service, an authenticated reverse proxy may be simpler than a full VPN. And full-tunnel mode (AllowedIPs = 0.0.0.0/0) routes all client traffic through home — great for trust on hostile networks, but it adds latency and depends on your home uplink; use split-tunnel (LAN subnets only) unless you specifically want every packet to egress via home.
WireGuard throughput is bound mostly by AES-NI and single-core speed, so if a saturated gigabit tunnel matters, pick a box with the headroom described in the best hardware for pfSense ↗ guide.
Prefer OpenVPN? OPNsense ↗ has strong OpenVPN tooling too. See firewallcompare.com ↗ for a WireGuard vs OpenVPN comparison across platforms.
Related
OpenVPN vs WireGuard on pfSense: Which to Run in 2026
An honest comparison of OpenVPN and WireGuard on pfSense — throughput, the pfSense Plus DCO offload, CE vs Plus availability, cipher and auth differences
pfSense vs OPNsense for Homelab: Which Firewall Wins in 2026?
A technical breakdown of pfSense CE, pfSense Plus, and OPNsense for homelab use — covering update cadence, WireGuard, Suricata, multi-WAN, UI, and
Best Mini PC for pfSense 2026: Buying Guide and Picks
What actually matters when picking a mini PC for pfSense in 2026: Intel NICs over Realtek, core count for IDS and VPN, RAM headroom, and the specific