WireGuard has established itself in recent years as the standard for site-to-site VPNs in the mid-market. Performance is very good (kernel module, often 800 Mbit+ over typical ISP links), configuration is manageable, and on OPNsense the integration is mature. This article is a concrete tutorial: connect two sites via WireGuard in 30 minutes, with explanations of the typical pitfalls.
If you are still considering WireGuard or OpenVPN at the fundamental level: we have a comparison article with performance data. For site-to-site setups WireGuard is now clearly the first choice.
The scenario
- Site A — head office: OPNsense firewall, static public IPv4, LAN
192.168.10.0/24 - Site B — branch: OPNsense firewall, dynamic public IPv4 (DSL), LAN
192.168.20.0/24 - Goal: both LANs see each other, routing in both directions, tunnel rebuilds automatically after the branch reconnects.
Prerequisites
- OPNsense ≥ 23.7 on both sites — the current WireGuard implementation is an integrated plugin (
os-wireguard) - At site A: static public IP or at least a very stable DynDNS record
- Both sites can establish outbound UDP connections (standard, almost always the case)
- Optional: DynDNS at site A for more robust configuration
Step 1 — install WireGuard plugin (if not yet present)
In OPNsense under System → Firmware → Plugins:
- install
os-wireguard(on both sites)
After installation WireGuard appears under VPN → WireGuard.
Step 2 — generate key pairs
WireGuard works with asymmetric keys: each peer has a private and a public key. A key pair is generated per site.
In OPNsense under VPN → WireGuard → Local:
- “Add” — new instance for site A:
- Name:
wg_site_to_site - Listen port:
51820(default) - Public key / private key: generate via “Gen” button
- Tunnel address:
10.10.0.1/24(private transit network, not your LAN)
- Name:
On site B the same — but tunnel address: 10.10.0.2/24. The public key of both instances will be needed shortly.
Pitfall: the tunnel network (10.10.0.0/24) is not the LAN — it is a separate transit network only for the tunnel endpoints. We recommend a /30 subnet or a /24 that does not appear anywhere else.
Step 3 — configure peers
Each site needs the other as an “endpoint”. Under VPN → WireGuard → Endpoints:
At site A: peer for site B
- Name:
peer_site_b - Public key: public key of the instance at site B
- Allowed IPs:
10.10.0.2/32, 192.168.20.0/24 - Endpoint address: public IP or DynDNS name of site B
- Endpoint port:
51820 - Keepalive:
25(seconds)
At site B: peer for site A
- Name:
peer_site_a - Public key: public key of the instance at site A
- Allowed IPs:
10.10.0.1/32, 192.168.10.0/24 - Endpoint address: public IP or DynDNS name of site A
- Endpoint port:
51820 - Keepalive:
25
Allowed IPs — the most common pitfall. Allowed IPs has a dual meaning in WireGuard:
- Routing: “which destination IPs go via this tunnel?”
- Filter: “which source IPs do we accept on this tunnel?”
If site A puts 192.168.20.0/24 under allowed IPs for site B, this means: “packets to 192.168.20.x are routed via this peer AND only packets from 192.168.20.x (plus tunnel IP 10.10.0.2) are accepted.”
Symmetry is mandatory. Anyone who forgets the LAN network on one side has packets that go out but do not come in. When debugging always compare both allowed-IPs lists.
Persistent keepalive 25 seconds is the recommendation for NAT traversal. WireGuard as a UDP protocol is “stateless” by default — if no packet flows for 5 minutes stateful NATs (typical with ISP DSL routers) forget the state and the tunnel “dies” silently. With 25-second keepalive the state stays warm.
Step 4 — activate tunnel
In the WireGuard instance under Local:
- tick “Enabled”
- under “Peers” assign the endpoint you just created
After save and “Apply” the peer should appear under VPN → WireGuard → Status with “Latest handshake” recent (< 30 seconds).
Step 5 — firewall rules
Standard OPNsense blocks all traffic on the WireGuard interface until rules exist. Under Firewall → Rules → WireGuard (or the WireGuard interface) you need at least:
- From source: any, to destination: LAN net of site A — if branch should access head office
- on the other side analogously
For a start an “any to any” rule on the WG interface is enough. Once the setup works it can be limited to specific subnets or ports — e.g. only head-office LAN to branch file server.
Additionally: WAN rule for inbound WG traffic. At site A under Firewall → Rules → WAN:
- Protocol: UDP
- Destination port:
51820 - Source: any (or limited to site B public IP if static)
- Action: Allow
This is the rule that lets the inbound UDP tunnel on port 51820 through.
Step 6 — routing
With allowed IPs cleanly set WireGuard routes automatically. Important: allowed IPs automatically write a route into the routing system. You do not need to enter an additional static route.
Anyone wanting to check manually can do on the OPNsense CLI:
netstat -rn | grep 10.10
netstat -rn | grep 192.168.20
Both should show routes via the WireGuard interface.
Step 7 — test
Ping from site A LAN (192.168.10.x) to site B LAN (192.168.20.1 = OPNsense branch):
ping 192.168.20.1
If that works: check SMB share on a branch server:
smbclient -L //192.168.20.10 -U user
If that also works — tunnel is up, routing applies, firewall lets through. Done.
Common error sources
1. Latest handshake stays empty
- endpoint address or port wrong
- WAN firewall blocks inbound UDP 51820
- ISP carrier-grade NAT blocks (rare on normal SMB connections; happens with ISP LTE)
2. Handshake present but pings do not go through
- allowed IPs wrong on one side (LAN subnet missing)
- firewall rule on WG interface blocks
3. Tunnel dies after a few minutes
- keepalive not set
- aggressive ISP NAT timeout (rare)
4. Routing over tunnel only one-sided
- allowed IPs not configured symmetrically
- asymmetric routing on OPNsense (another default gateway pulls the return path elsewhere)
5. Disappointing performance
- MTU problem: WireGuard reduces effective MTU. Default 1420 is mostly right. On strange performance patterns (large packets break) lower MTU testwise to 1380 or 1400.
Persistent keepalive — what it really does
We recommended keepalive 25 seconds. Background: WireGuard packets are UDP. NAT devices (including your own OPNsense if it sits behind NAT) build a NAT mapping for every UDP connection that expires on inactivity — typically 30 seconds to a few minutes.
With keepalive 25 the peer sends an empty handshake packet every 25 seconds. This keeps the NAT state warm and the tunnel reacts immediately when real packets flow.
Who does not need this? Anyone working with static public IP on both sides without NAT in between. But: setting it does not hurt, costs only a few packets per minute.
Latency and throughput — qualitative
WireGuard uses a kernel module with ChaCha20-Poly1305 encryption — significantly more performant on modern CPUs than OpenVPN’s userspace AES. In typical SMB setups (site-fibre-site) WireGuard regularly reaches 80–90% of the underlying link bandwidth. We skip quantitative claims here.
For site-to-site with fibre connections beyond 200 Mbit WireGuard is almost always the right choice. For pure RDP or VoIP connections classic IPsec or OpenVPN are also sufficient — for new setups we would still choose WireGuard.
OpenVPN comparison briefly
For anyone moving from OpenVPN site-to-site: WireGuard is conceptually different. There are no “server” and “client” roles, only peers. There is no separate TLS initiation but key-based authentication. There is no config file per connection but peer lists.
WireGuard advantages: faster, simpler, less state to maintain. Disadvantages: no username/password login (for road-warrior VPNs additional tools are needed), no push config mechanism.
For site-to-site the disadvantages are irrelevant — the keys are exchanged once and that is it.
Site-to-site scaling
For three or more sites there are two topologies:
- Hub and spoke: central OPNsense (e.g. head office) as hub, all branches as spokes. Easy to maintain but hub as single point of failure.
- Full mesh: every branch has a tunnel connection to every other. More robust but configuration effort grows quadratically.
For four or more sites with high resilience need a mesh VPN tool like NetBird or Tailscale is worth a look — they encapsulate mesh management in a control plane.
DATAZONE recommendation
WireGuard site-to-site is standard repertoire today. We configure this per site in under 30 minutes — provided the WAN connections and OPNsense installations are clean.
Anyone coordinating several sites gets far with the configuration model from this article. As soon as it goes beyond four sites or road-warrior accesses are added, a look at an overlay mesh is worthwhile.
Sources and further reading
- OPNsense documentation — WireGuard — official documentation
- OPNsense WireGuard VPN setup — road-warrior setup
- OPNsense multi-WAN failover — multi-WAN background
- NetBird vs. Tailscale mesh VPN — mesh alternatives
Anyone wanting the setup configured with guidance: please book a meeting — we do this remotely too.
More on these topics:
More articles
OPNsense 26.7 Release: What's Coming
OPNsense 26.7 is due: what to expect from the traditional July major release — HardenedBSD/FreeBSD update, plugin refresh, GUI improvements. An honest look at the public roadmap.
OPNsense Multi-WAN: Failover Done Right for SMB
Configure two WAN connections in OPNsense — fibre and LTE backup — as a failover for the mid-market. Gateway groups, Tier 1/2, health checks via monitor IP, sticky connections for VoIP, outbound NAT per WAN. Why true failover beats load balancing for most SMBs.
OPNsense VLAN Routing: 6 Best Practices for SMB Networks
Plan OPNsense VLAN routing right: management isolation, per-VLAN DHCP, default-deny, MAC tracking, Unbound views and IoT segmentation explained.