Skip to content

RackNerd Hosting Deals

WireGuard VPN on OPNsense

Running WireGuard directly on OPNsense means your VPN lives at the kernel level inside the router — not in a container or on a separate host. This gives you better performance, native firewall integration, and a cleaner architecture. Remote clients connect to your router, and routing decisions happen at the same place as all other firewall rules.

Prerequisites

  • OPNsense installed and running (see OPNsense on Zimaboard 2)
  • WAN port with a reachable IP (static or DDNS)
  • UDP port 51820 accessible from the internet (you'll add the firewall rule below)
  • WireGuard client app on your devices (iOS, Android, macOS)

Why WireGuard on the Router?

Approach Pros Cons
WireGuard on OPNsense Kernel performance, native firewall rules, single config point Slightly more complex initial setup
WireGuard in a container Easy to set up initially Requires port forwarding, extra NAT hop, no native firewall integration
WireGuard on a separate VM Isolated More hardware, extra management

Step 1: Create the WireGuard Server Instance

Navigate to VPN → WireGuard → Instances → Add:

Field Value
Name wg0 (or any name)
Listen Port 51820
Tunnel Address 10.10.10.1/24
Generate keypair Click the generate button

Tunnel subnet must not overlap with your LAN

If your LAN is 192.168.1.0/24, your WireGuard tunnel must use a different subnet entirely (e.g., 10.10.10.0/24). Overlap here causes routing failures that are annoying to diagnose.

Save the instance. Note the public key — you'll need it when configuring client configs.


Step 2: Add Peers via the Peer Generator

The Peer Generator (VPN → WireGuard → Peer Generator) lets you create a peer config and QR code in one step.

For each device (phone, laptop, etc.):

Field Value
Name Descriptive (e.g., iphone, macbook)
Tunnel Address Unique IP in the tunnel subnet (e.g., 10.10.10.2/32)
DNS Your Pi-hole IP (e.g., 192.168.1.x)
Pre-shared key Generate one
Endpoint <your-wan-ip>:51820 or your DDNS hostname
Allowed IPs See split vs full tunnel below
Keepalive 25

Scroll down and Save before scanning the QR

The Peer Generator shows a QR code, but the peer is not saved to the instance until you scroll to the bottom and click Save. After saving, go to VPN → WireGuard → Peers and confirm your peer appears, then edit your WireGuard Instance and make sure the peer is selected in the Peers dropdown.


Split Tunnel vs Full Tunnel

The Allowed IPs field on each peer controls what traffic goes through the VPN.

Full Tunnel (phone — all traffic via VPN)

Allowed IPs: 0.0.0.0/0, ::/0

All traffic — including regular browsing — routes through your home connection. Useful on cellular where you want Pi-hole's ad blocking everywhere.

Split Tunnel (laptop — homelab only)

Allowed IPs: 192.168.1.0/24, 10.10.10.0/24

Only traffic destined for your LAN or other VPN peers routes through the tunnel. General browsing uses the device's local internet. Faster for daily use, lower load on your home connection.

Tip

Use full tunnel for phones (you get Pi-hole ad blocking on cellular) and split tunnel for laptops (general browsing isn't bottlenecked by your home upload speed).


Step 3: Firewall Rules

Two rules are required.

Rule 1 — Allow WireGuard traffic in on WAN

Firewall → Rules → WAN → Add

Field Value
Action Pass
Direction In
Protocol UDP
Source any
Destination WAN address
Destination port 51820

Rule 2 — Allow traffic through the tunnel

Firewall → Rules → WireGuard (tab) → Add

Field Value
Action Pass
Direction In
Protocol any
Source any
Destination any

Step 4: Outbound NAT (the part most guides miss)

This is where most WireGuard-on-OPNsense setups break. Without the correct NAT rules, VPN clients can reach LAN hosts but DNS replies from Pi-hole get silently dropped, and internet traffic doesn't route correctly.

First, set NAT mode to Hybrid: Firewall → NAT → Outbound → select Hybrid Outbound NAT.

Add two rules:

NAT Rule 1 — Tunnel to Internet

Field Value
Interface WAN
Source WireGuard (Group) net
Translation Interface address

This masquerades VPN client traffic behind your WAN IP so it can reach the internet.

NAT Rule 2 — Tunnel to LAN

Field Value
Interface LAN
Source WireGuard (Group) net
Translation Interface address

This rule is critical and commonly missed

Without this rule, VPN clients can ping LAN hosts and even open connections, but DNS responses from Pi-hole get dropped. The symptom is that DNS lookups time out or return nothing even though ping to the Pi-hole IP works. Adding this LAN NAT rule fixes it.


Step 5: Client Setup

iPhone / Android

  1. Open the WireGuard app
  2. Tap +Create from QR code
  3. Scan the QR from the Peer Generator
  4. Enable the tunnel

macOS

  1. Open the WireGuard app (Mac App Store)
  2. Click +Add Empty Tunnel
  3. Paste your peer config directly (copy from OPNsense peer view)

Alternatively, export the config file and drag it into the WireGuard app.


Verification

# From a device on cellular with VPN enabled
curl -I https://google.com
# Should return HTTP headers — internet routing works

ping -c 3 192.168.1.x   # your Pi-hole IP
# Should reply — LAN is reachable through tunnel

nslookup doubleclick.net
# Should return 0.0.0.0 — Pi-hole filtering works through VPN

In OPNsense: VPN → WireGuard → Status should show your peer with a recent handshake time and bytes transferred.


Common Gotchas

Problem Cause Fix
Peer not saving Didn't click Save at bottom of Peer Generator Scroll to bottom and Save; verify in Peers tab
Peer not appearing in instance Peer saved but not linked to instance Edit Instance → select peer in Peers dropdown → Apply
DNS not working through VPN Missing LAN NAT rule Add NAT Rule 2 (Tunnel to LAN)
Internet not working through full tunnel Missing WAN NAT rule Add NAT Rule 1 (Tunnel to WAN)
Can't connect from outside WAN firewall rule missing Add UDP 51820 pass rule on WAN


If there is an issue with this guide or you wish to suggest changes, please raise an issue on GitHub.