NEW Self-serve signup is live. Free for 2 machines, forever. ₹349/machine/month after. See pricing →
/ opnsense + wireguard

OPNsense WireGuard: 2026 setup + multi-branch guide

OPNsense ships WireGuard as a first-class kernel module since 24.1. This guide covers the setup in the web UI, the site-to-site pattern between two appliances, the firewall rules everyone forgets, and what changes when one branch grows into ten.

Does OPNsense have WireGuard built in?

Yes — since OPNsense 24.1, released January 2024, WireGuard ships as a first-class kernel module in the base system. No plugin install is needed. On any currently-supported OPNsense release (24.1, 24.7, 25.1, and later), navigate to VPN → WireGuard immediately after install.

Older versions had a different story. From around OPNsense 19.1 through 23.7 there were two plugins — os-wireguard-go (a userspace Go implementation) and os-wireguard (the kernel module). Both are deprecated; if you're still on a release that uses them, you'll see a migration warning in the web UI and the canonical advice is to upgrade to 24.1 or later before continuing.

The migration matters because throughput nearly doubles when moving from the userspace implementation to the kernel module, and the configuration UI is unified under the new menu instead of split between os-wireguard and os-wireguard-go.

Where it lives in the OPNsense UI

The relevant pages, in the order you visit them on first setup:

  • VPN → WireGuard → Instances — each local WireGuard interface lives here. Holds the private key, listen-port, and tunnel address.
  • VPN → WireGuard → Peers — the remote endpoints that connect to your instances. Public key, endpoint, Allowed IPs.
  • VPN → WireGuard → General — the one master Enable / Disable toggle, and the gateway monitoring options.
  • VPN → WireGuard → Status — live view of handshakes, last-seen time, transferred bytes. This is the dashboard you'll have open while troubleshooting.
  • Interfaces → Assignments — once an instance is up, you assign it as a regular interface (typically named WG_LAN or WG0) so firewall rules and gateway monitoring apply.
  • Firewall → Rules → WAN — the inbound UDP rule allowing the WireGuard listen-port.
  • Firewall → Rules → WG_LAN (or whatever you named it) — what tunnel traffic is allowed to do once it arrives.

Step-by-step setup (single site)

The numbered sequence below produces a working WireGuard server that a single road-warrior client can connect to. The site-to-site case in the next section is the same setup performed symmetrically on both firewalls.

  1. VPN → WireGuard → Instances → +. Name the instance (e.g. wg0). Generate a keypair using the dice icon. Set Listen Port to 51820. Set Tunnel Address to 10.100.0.1/24 for a single-server setup, or to a /32 like 10.100.0.2/32 for a peer-to-peer site-to-site.
  2. VPN → WireGuard → Peers → +. Name the peer. Paste its public key. Set Allowed IPs to the peer's tunnel IP (10.100.0.10/32 for a road warrior, or the whole remote tunnel + LAN subnet for a site-to-site). Leave Endpoint blank if the peer dials in; fill it in if the peer has a stable public address.
  3. Bind peer to instance. Edit the instance, add the peer in the Peers field, save.
  4. VPN → WireGuard → General. Tick Enable WireGuard, click Apply. The kernel interface (wg0) comes up immediately.
  5. Firewall → Rules → WAN. Add an inbound UDP rule on port 51820 to the WAN interface address (or the floating "any" if you're behind a single WAN). This is the most-forgotten step; a tunnel with no firewall hole gets no handshake.
  6. Interfaces → Assignments. The new wg0 interface should appear. Add it, give it a friendly name like WG_LAN, enable it (no IP needed — WireGuard's tunnel address covers it).
  7. Firewall → Rules → WG_LAN. Add at minimum an allow rule for traffic from the WG subnet to wherever your policy says it should reach (LAN net, or a specific host).
  8. Verify under VPN → WireGuard → Status. Once the remote peer is also configured, a handshake should complete within 10 seconds and the byte counter increments.

Site-to-site between two OPNsense firewalls

For a two-branch deployment you perform the setup symmetrically on both appliances. Convention is to use a /32 tunnel address on each side (so the routing is explicit) and a shared /24 overlay range, e.g. 10.100.0.0/24:

FieldBranch A (Mumbai)Branch B (Pune)
Instance tunnel address10.100.0.2/3210.100.0.3/32
Listen port5182051820
Peer public keyBranch B's public keyBranch A's public key
Peer Allowed IPs10.100.0.3/32, 192.168.20.0/2410.100.0.2/32, 192.168.10.0/24
Peer endpointBranch B's public address:51820Branch A's public address:51820
WAN firewall ruleAllow UDP 51820Allow UDP 51820

Once both sides are saved and enabled, the handshake should complete within ~10 seconds. On the appliance with the more permissive Allowed IPs (or the one initiating outbound first) the handshake shows in Status as a recent timestamp on the peer row.

Persistent Keepalive matters if either side is behind NAT: set it to 21 (seconds) on the side that's behind NAT so the connection-tracking table on the intermediate router doesn't drop the UDP flow.

Firewall rules that everyone forgets

Three rules trip up most OPNsense WireGuard setups:

  1. WAN inbound for the listen-port. If the local firewall is the WireGuard listener, you need an inbound UDP rule on WAN for the chosen port. Without it, packets are dropped before they reach WireGuard and no handshake ever appears.
  2. WG_LAN interface rules. By default a freshly-assigned WireGuard interface has zero rules, which means deny-all. You must explicitly allow at least the source subnets and destinations your policy permits. The default Allow-LAN-to-Any pattern does not cover traffic arriving on the WG interface.
  3. Outbound NAT. If your branches need to reach the internet through the tunnel (rare for site-to-site, common for road warriors), you need an outbound NAT rule on the listener side rewriting the source IP. For pure site-to-site mesh traffic, do not add outbound NAT — it breaks return-path routing because the response goes to the NAT'd IP rather than the originating peer.

Handshake, no traffic? Troubleshooting

The most useful single page in OPNsense for diagnosing this is Firewall → Log Files → Live View, with a filter on the WireGuard interface. Ping from one side; the log shows the verdict that applied. The five most common causes:

  • Allowed IPs mismatch. The destination IP is not in the peer's Allowed IPs list on either side, so WireGuard drops it before encrypting.
  • WG interface firewall rule missing. The traffic reaches WireGuard but is blocked by interface-level deny.
  • Asymmetric routing. Reply traffic exits the LAN interface instead of WG because the LAN gateway route doesn't know to send /32 destinations via the tunnel. Fix in System → Routes → Static Routes.
  • MTU clipping. Default WireGuard MTU is 1420 (1500 minus header overhead). If the upstream ISP is doing PPPoE (1492 MTU) or CGNAT (often less), tunnel traffic gets fragmented and dropped silently. Set MTU explicitly on the WireGuard interface to 1380 to be safe under most Indian ISP conditions.
  • NAT-related: source IP unreachable. If the side behind NAT has no Persistent Keepalive set, the handshake works once and then the upstream NAT table forgets the UDP flow. Set Persistent Keepalive to 21 on the NAT'd side.

From two sites to ten branches

OPNsense WireGuard is excellent at two sites in a clean point-to-point. The shape changes when the operator needs more than that:

  • Five sites in a full mesh = ten peer relationships. Each is configured twice (once on each side), so twenty configuration changes for one new firewall. Ten sites in full mesh = forty-five relationships, ninety changes. The number grows quadratically with site count.
  • One peer rotates a key. Every other peer needs its peer-config updated and the OPNsense WireGuard service reloaded. There is no automated way to do this from the OPNsense UI; it's a manual visit to every firewall.
  • Policy across the mesh. Per-peer access rules live on each firewall's WG interface. If you want to centrally enforce "no branch-to-branch traffic except via HQ," that policy has to be reproduced on every firewall and audited individually.
  • Double-NAT branches. If two branches are both behind CGNAT (common on cellular failover and rural fibre), they can't initiate to each other; they need a relay. OPNsense doesn't ship a relay layer.
  • Diagnostics across the mesh. VPN → WireGuard → Status shows one firewall's view. Across ten branches that's ten browser tabs to answer "is everything green?"

When a managed mesh layer pays for itself

MeshWG sits on top of the same OPNsense kernel-level WireGuard module. Your firewall keeps using the built-in implementation, the same as if you'd configured it yourself; MeshWG provides the orchestration:

  • Generated configuration that updates automatically. Each new site joining the mesh triggers a regenerated peer list for every existing site. You don't re-edit ten firewalls; you accept the new site in the dashboard.
  • Central policy. Allow / deny rules are configured once. The dashboard shows which device pairs are allowed to talk, by source / destination / protocol / port, without you opening ten Firewall → Rules → WG_LAN tabs.
  • Relay layer for double-NAT. When both peers are behind CGNAT, the relay handles the path automatically. You don't choose or configure it.
  • Single status pane. One dashboard view of last-handshake and bytes-transferred across every site. Replaces ten browser tabs.
  • Free up to 2 sites. Two devices free forever, then ₹349/device/month annual or ₹499/device/month monthly in INR via Razorpay. The OPNsense + MeshWG buyer typically crosses the free tier at the 3rd branch.

Frequently asked questions

Does OPNsense have WireGuard built in?

Yes. Since OPNsense 24.1 (released January 2024), WireGuard is a first-class kernel module included in the base system; no plugin install is needed. Older OPNsense versions used the os-wireguard-go (userspace) and os-wireguard (kernel) plugins, both of which are now superseded. On any currently-supported OPNsense release (24.1, 24.7, 25.1 and later), WireGuard appears under VPN → WireGuard in the web UI directly after a fresh install.

Where is WireGuard in the OPNsense web UI?

Under VPN → WireGuard. The page has three tabs: Instances (each local WireGuard interface), Peers (the remote endpoints that connect to those instances), and Status (a live view of handshakes and bytes transferred). Older versions of the plugin used 'Local' and 'Endpoints'; from 24.1 onwards the menu is unified.

How do I set up a site-to-site WireGuard tunnel between two OPNsense firewalls?

On each OPNsense, create a WireGuard Instance with a unique private key, a listen-port, and a tunnel address (typically a /32 in a shared overlay range, like 10.100.0.2/32 on one side and 10.100.0.3/32 on the other). Then on each side, add a Peer pointing at the other firewall's public key, the other firewall's public IP and listen-port, and the other firewall's tunnel address plus any LAN subnet behind it in Allowed IPs. Enable the instance, allow UDP 51820 inbound on the WAN firewall rule, and a handshake should appear in the Status tab within seconds.

What firewall rules does OPNsense WireGuard require?

Two sets. First, a WAN-side rule allowing UDP to the WireGuard listen-port (default 51820, customisable per instance). Second, rules on the WireGuard interface itself controlling what traffic from the tunnel can reach which destinations — typically you allow tunnel-to-LAN with whatever scope your policy dictates. OPNsense automatically creates a WireGuard interface in Interfaces → Assignments once an instance is configured; you assign it (call it WG0) and apply rules to it like any other interface.

Why does my OPNsense WireGuard tunnel show a handshake but no traffic?

A successful handshake means the cryptographic peer-pairing worked but does not guarantee the routing. The two most common causes when traffic isn't flowing are (1) Allowed IPs on one side does not include the destination subnet on the other side, so the packet is dropped before WireGuard sends it, and (2) firewall rules on the WireGuard interface are blocking the traffic. Check Firewall → Log Files → Live View while pinging from one side; the log will show whether the packet hit the WireGuard interface and what verdict applied.

Can I run a multi-site mesh with OPNsense WireGuard?

Mechanically yes — each OPNsense firewall is a peer, and you can configure every firewall to peer with every other firewall in a full mesh. Practically the configuration overhead grows quadratically (10 sites = 45 peer configurations). The pragmatic shape for more than three sites is hub-and-spoke (one central firewall is the listener, every branch peers with the hub) or a managed mesh service that generates and synchronises the peer configurations centrally.