Wheelhouse docs

WireGuard between two sites#

You will end up with two routers joined by a WireGuard tunnel, each reaching the other's LAN. It is the same page as a tunnel for a laptop; the differences are that each router is a peer of the other, with the other's public key and address, and that each side needs a route to the far LAN.

Before you start#

  • The operator role and a licence on both routers, and the WireGuard page on both.
  • LAN networks that do not overlap. Two sites both on 192.168.1.0/24 cannot route to each other, and nothing in this guide fixes that.
  • At least one side reachable at a stable address or host name. If both addresses change, dynamic DNS on one side is the minimum.

The example throughout:

Site ASite B
LAN192.0.2.0/24198.51.100.0/24
Public address203.0.113.10203.0.113.20
Tunnel address10.10.0.1/3010.10.0.2/30

Step 1 — A tunnel on each router#

On each router, Protect → WireGuard → Add tunnel:

  • Addresses: 10.10.0.1/30 on site A, 10.10.0.2/30 on site B. A /30 holds exactly the two routers.
  • Listen port: 51820 on both.
  • Description: to site B and to site A.
  • Key pair: Generate.
  • Allow the listen port through the firewall: on.

Apply the change on each router. Each tunnel card now shows its Public key — copy it; the other router needs it.

Step 2 — Each router as the other's peer#

On site A, Add peer on the tunnel card:

FieldValue
NamesiteB
Public keySite B's tunnel public key, from its tunnel card.
Allowed IPs10.10.0.2/32 and 198.51.100.0/24 — site B's tunnel address and its LAN.
Endpoint and Port203.0.113.20 and 51820. A host name works too.
Keepalive25, to keep a NAT mapping on either side open.
Pre-shared keyOptional. When used, both sides hold the same one.

On site B, the mirror image: siteA, site A's public key, 10.10.0.1/32 and 192.0.2.0/24, and site A's address.

Allowed IPs is both a filter and a label: traffic from the peer is accepted only from those networks, and traffic in the tunnel for them goes to that peer. Getting it wrong gives a tunnel that handshakes and then drops traffic without a word.

Step 3 — A route to the far LAN, on both#

Allowed IPs does not put a route in the routing table: the router still has to be told that the far LAN is through the tunnel. On site A, Network → Static routes, a route to 198.51.100.0/24 through wg0 or through 10.10.0.2. On site B, a route to 192.0.2.0/24 through wg0 or 10.10.0.1. Add a static route.

Step 4 — The forward firewall, on both#

The listen port was opened in step 1. What remains is the traffic between the LANs, which passes the forward chain: on the Firewall page of each router, accept traffic arriving on wg0 for the LAN, and traffic from the LAN leaving on wg0.

Step 5 — Do not masquerade into the tunnel#

A source NAT rule that matches everything leaving the router can translate traffic bound for the tunnel, and the far side then sees your public address instead of your LAN. Check that the masquerade rule names the uplink as its outbound interface — which is what the Uplinks page writes — rather than matching on source alone. Masquerade behind each uplink.

Check it worked#

On either router's WireGuard page, the other site's row turns Connected, with its last handshake, its current endpoint and its traffic. Then, from a host on site A's LAN:

bash
ping -c 3 198.51.100.1
traceroute 198.51.100.1
What you seeAlmost always
Never connectedKeys, endpoint or port: each side has to hold the other's public key and reach the other's address.
Connected, the far tunnel address answers, the far LAN does notThe route in step 3, the allowed IPs, or the forward firewall.
Works one wayThe other router's route or forward rule.

Removing it#

On each router: Edit on the tunnel card, Delete tunnel, and the static route to the far LAN. Deleting one side leaves the other retrying against a peer that is not there, which is harmless and noisy.

See also#

Updated 2026-09-18 wireguard vpn site-to-site