VPNSmith
self-host-vpnINFO

WireGuard Site-to-Site VPN: Link Two Networks (2026 Guide)

Connect two whole LANs over WireGuard — office to home, two data centres, or branch to HQ. Subnet routing, AllowedIPs, NAT and firewall, step by step on a VPS.

By Eric Gerard · Founder · VPNSmith — Self-host VPN & GDPR VPS specialist9 min readPhoto via Pixabay

Affiliate disclosure — This article contains Contabo affiliate links. If you order a VPS through them, we earn a commission at no extra cost to you. Every command and config below is documented from official WireGuard sources and written to be reproducible on your own machines.

A site-to-site VPN joins two entire networks so they behave like one. Every host on the office LAN can reach every host on the home LAN — your NAS, a printer, a hypervisor, a database — without installing a VPN client on each device. WireGuard makes this lean and fast: a single UDP port, a handful of config lines, kernel-space crypto. This guide builds a working WireGuard site-to-site tunnel from scratch, then explains the three things people always get wrong: AllowedIPs, IP forwarding, and host routing.

We will use a concrete, common topology: Site A is a home or office LAN behind NAT (no usable public IP), and Site B is a VPS with a public IPv4 acting as the always-on hub. The exact same config also links two homes, two offices, or two data centres — only the subnets change.

Site-to-site vs road-warrior: what actually changes

If you have set up WireGuard for a laptop before, 90% of this is familiar. The mental shift is small but crucial:

  • Road-warrior (remote access): one device joins the network. Its peer announces a single tunnel address — AllowedIPs = 10.66.66.2/32.
  • Site-to-site: a whole network joins. The peer announces the LAN subnet behind itAllowedIPs = 10.66.66.2/32, 192.168.10.0/24 — and the WireGuard box forwards for every host on that LAN.

Everything else — keys, the handshake, the UDP port — is identical. If your handshake never completes, the causes are the same as any tunnel; work through the WireGuard handshake fix list before blaming the site-to-site parts.

A dense bundle of blue, green, yellow and red Ethernet patch cables plugged into a network switch in a rack
A dense bundle of blue, green, yellow and red Ethernet patch cables plugged into a network switch in a rack

Plan the address space first (5 minutes that save hours)

Before touching a config, write down three ranges. Getting this wrong is the number-one cause of a tunnel that connects but carries no host traffic.

RangeExampleRule
Tunnel subnet10.66.66.0/24Private to the VPN, must not collide with either LAN
Site A LAN192.168.10.0/24The home/office network
Site B LAN192.168.20.0/24The remote network — must differ from Site A

The hard rule: the two LANs must not overlap. If both sides currently use 192.168.1.0/24, renumber one of them now. A host cannot route to a remote subnet that looks identical to its own — it will treat the address as local and never hand the packet to WireGuard. If you are fuzzy on subnet maths, our what is a subnet explainer covers CIDR in plain terms.

Step 1 — Provision the hub (Site B, the VPS)

Site B needs a public IPv4 and an open UDP port. We use a Contabo Cloud VPS 10 (4 vCPU, 8 GB RAM, 75 GB NVMe) at €5.50/month on the 12-month term — overkill for a tunnel, comfortable if it also runs other services. If you don't have a VPS yet, grab the Contabo Cloud VPS 10; pick a region close to whichever site sends the most traffic. For a clean base install of WireGuard on it, follow the step-by-step Contabo + WireGuard setup, then come back here for the site-to-site routing.

Install WireGuard and generate keys on the VPS:

sudo apt update && sudo apt install -y wireguard
umask 077
wg genkey | tee siteB.key | wg pubkey > siteB.pub

Step 2 — Set up the WireGuard router at Site A

Site A's WireGuard box is any always-on Linux machine on the LAN — a Raspberry Pi, a small VM, an old laptop. It does not need a public IP; it dials out to the VPS. Generate its keys the same way:

wg genkey | tee siteA.key | wg pubkey > siteA.pub

This machine becomes the gateway for the remote subnet, so it must forward packets between its LAN interface and the WireGuard interface.

Step 3 — The two configs

Here is the whole tunnel. Note how each side's AllowedIPs lists the other site's LAN — that line is what turns a point-to-point link into a network-to-network link.

Site B — the VPS hub (/etc/wireguard/wg0.conf):

[Interface]
Address = 10.66.66.1/24
ListenPort = 51820
PrivateKey = <siteB.key>
# forward + masquerade so Site A hosts can also reach the internet via the VPS
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Site A
PublicKey = <siteA.pub>
AllowedIPs = 10.66.66.2/32, 192.168.10.0/24

Site A — the LAN router (/etc/wireguard/wg0.conf):

[Interface]
Address = 10.66.66.2/24
PrivateKey = <siteA.key>
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT

[Peer]
# Site B (the VPS hub)
PublicKey = <siteB.pub>
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.66.66.0/24, 192.168.20.0/24
PersistentKeepalive = 25

Two details that matter:

  • PersistentKeepalive = 25 lives on the side behind NAT (Site A). It sends a tiny packet every 25 seconds so the home router keeps the UDP path open and the VPS can always reach back.
  • Endpoint only appears on Site A's peer block — Site A dials the VPS. The VPS learns Site A's address when the first packet arrives, so its peer block has no Endpoint.

Bring both tunnels up with sudo wg-quick up wg0 and check sudo wg show. A latest handshake within the last two minutes on both sides means the link is alive.

Step 4 — The step everyone forgets: host routing

This is where most site-to-site tunnels stall. The routers can ping each other across 10.66.66.x, but a laptop on Site A still cannot reach a NAS on Site B. Why? Because the other hosts on each LAN have no idea the WireGuard box is the door to the remote subnet. They send the packet to their default gateway, which has no route for 192.168.20.0/24, and it dies.

You have two clean ways to fix it:

  1. Static route on the LAN gateway (best). On Site A's main router, add a static route: destination 192.168.20.0/24, gateway = the Site A WireGuard box's LAN IP (e.g. 192.168.10.5). Do the mirror on Site B. Now every host inherits the route automatically. Most consumer and business routers support static routes in their admin panel.
  2. Per-host static routes. If you cannot touch the router, add a route on each machine that needs cross-site access:
# on a Site A host, reach the Site B LAN via the local WireGuard box
sudo ip route add 192.168.20.0/24 via 192.168.10.5

If the WireGuard box is your LAN's default gateway, you can skip this entirely — it already forwards. This is conceptually a routing problem, not a VPN problem; the same logic as port forwarding but applied to a whole subnet instead of one port.

Step 5 — Firewall the forwarding path

Forwarding without a firewall rule means either nothing passes or everything does. Be explicit. On the VPS hub, the PostUp above already accepts forwarded traffic from wg0; tighten it if you only want specific subnets to talk:

# only allow Site A LAN <-> Site B LAN, drop the rest
iptables -A FORWARD -s 192.168.10.0/24 -d 192.168.20.0/24 -i wg0 -j ACCEPT
iptables -A FORWARD -s 192.168.20.0/24 -d 192.168.10.0/24 -o wg0 -j ACCEPT

Make the rules persistent (iptables-save, or netfilter-persistent save on Debian/Ubuntu) so they survive a reboot. The single UDP port also needs to be open in front of the VPS — see which port WireGuard uses and how to open it if the handshake never starts.

Verifying the full path

Run these in order and stop at the first failure:

  1. Tunnel up? sudo wg show on both ends → recent latest handshake, non-zero transfer.
  2. Router-to-router? From Site A's WireGuard box: ping 10.66.66.1. Fails → it's a tunnel problem, not site-to-site.
  3. Router to remote LAN? From Site A's box: ping 192.168.20.1. Fails → AllowedIPs or ip_forward on Site B.
  4. Host to remote host? From any Site A laptop: ping 192.168.20.50. Fails here but step 3 worked → host routing (Step 4).

That four-line ladder isolates the exact layer that is broken in under a minute.

When to add more sites — hub-and-spoke

To link three or more networks, keep the VPS as a central hub and add each new LAN as a spoke peer on it. Each spoke lists all the other LAN subnets in its AllowedIPs (routed via the hub), and the hub lists each spoke's LAN. This stays simple up to a handful of sites. Past that — or if you want automatic key rotation, ACLs, and NAT traversal without a public IP on any side — a mesh control plane like Tailscale or Headscale is less work than hand-editing peers; weigh it in our Tailscale vs WireGuard self-host comparison.

Why self-host the hub instead of a managed service

A site-to-site link is exactly where owning the box pays off: no per-seat pricing, no data limits, no third party in the path between your two networks. A Contabo Cloud VPS 10 at €5.50/month gives you a public IPv4, full root, unlimited traffic (fair-use) and the freedom to open the one UDP port you need — the ideal always-on hub for tying your sites together. Build it once and it runs for years.

Going further

Sources and references:


Published 2026-06-26. Topology validated on Debian 12 and Ubuntu 24.04 with a Contabo Cloud VPS 10 hub and a Raspberry Pi LAN router. Your subnets, router models and ISP NAT behaviour will differ — always confirm each layer with wg show, ping and ip route before considering a setup final.

Reminder: running WireGuard and self-hosting a VPN is legal in the EU, US, Canada and most democratic countries. VPNSmith publishes this content for educational purposes.

★ Nuremberg GDPR datacenter · ✓ Dedicated IPv4 included · 200+ Mbps guaranteed

Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region

Frequently asked questions

What is the difference between a site-to-site and a road-warrior WireGuard setup?
A road-warrior (or remote-access) setup connects a single device — your laptop, your phone — into a network. A site-to-site setup connects two whole networks so that every machine on LAN A can reach every machine on LAN B, transparently, without installing WireGuard on each device. The difference lives almost entirely in AllowedIPs and routing: a road-warrior peer announces a single /32 tunnel IP, a site-to-site peer announces the remote LAN subnet (e.g. 192.168.20.0/24) and the routers forward for the hosts behind them.
Do both sites need a public IP address?
No — only one side needs a reachable public IP and an open UDP port. WireGuard is peer-to-peer, so the side behind NAT (a home connection, a CGNAT mobile link) initiates the tunnel and keeps it open with PersistentKeepalive. The classic pattern is a cheap VPS with a public IPv4 acting as the always-on hub, and one or more LANs dialing into it. If neither site has a public IP, route both through a VPS hub instead of trying to connect them directly.
How do I let the remote LAN reach the local LAN through WireGuard?
Three things must line up. (1) AllowedIPs on each peer must list the remote LAN subnet, not just the tunnel /32. (2) IP forwarding must be on: net.ipv4.ip_forward=1. (3) The hosts on each LAN must know to send traffic for the remote subnet to their local WireGuard router — either via a static route on each host, or a static route on the LAN's default gateway pointing the remote subnet at the WireGuard box. Skipping step 3 is the single most common reason a site-to-site tunnel 'works' on the routers but no host can ping across.
Will overlapping subnets break a site-to-site VPN?
Yes, and badly. If both LANs use 192.168.1.0/24, a host cannot tell whether 192.168.1.50 is local or remote, so it never sends the packet over the tunnel. You must renumber one side (e.g. move one LAN to 192.168.20.0/24) or use 1:1 NAT to map the remote subnet to a non-overlapping range. Plan your address space before you build — renumbering a live network afterwards is painful.
Is WireGuard site-to-site faster than OpenVPN site-to-site?
WireGuard generally has lower CPU overhead and lower latency than OpenVPN because it runs in kernel space and uses modern fixed cryptography, which matters on small VPS instances and on links you saturate. The exact throughput depends on your CPU, MTU and the quality of the path between the two sites — always benchmark your own setup. For a feature-by-feature comparison see our OpenVPN vs WireGuard deep dive.