Yes — WireGuard works beautifully for site-to-site VPN. It works between two routers, between thirty routers, and between routers sitting behind ISP CGNAT with no static public IP at either end. What you do not get out of the box is a control plane: someone has to generate the keypairs, distribute the configurations, keep the AllowedIPs in sync, and update everyone when a peer's overlay address changes. MeshWG is that control plane. It runs on top of the WireGuard already in your TP-Link, MikroTik, OpenWrt, Ubuntu, OPNsense, or Ubiquiti gear — and connects a 20-branch network for around ₹7,000 a month against the ₹30 lakhs of hardware plus ₹30,000 a month of licensing a comparable SDWAN deployment costs. Setup takes under two minutes per site. Two machines are free, forever. Below is exactly how WireGuard site-to-site works under the hood in 2026, where the manual-configuration approach starts to bite, and how to decide between hand-rolling and a cloud control plane for your environment.
Can WireGuard be used for site-to-site VPN?
Yes — and it's arguably what WireGuard does best. Three properties make the protocol well-suited for connecting LANs rather than individual devices.
First, every peer is symmetric. There is no client mode and no server mode in the WireGuard core — both sides of any tunnel maintain the same state, run the same handshake, and care only about which public keys they have configured. The same wg-quick configuration shape that works between two laptops works between two routers, between a server and a router, or between thirty routers in a mesh.
Second, the configuration is connectionless from a TCP standpoint. WireGuard packets are UDP datagrams. There is no TCP three-way handshake to time out, no half-open connection state, and no "session" that breaks when one end's upstream IP rotates. The tunnel comes up on the next packet exchange and stays up as long as either side is sending traffic or PersistentKeepalive heartbeats.
Third, the routing is explicit and inspectable. The AllowedIPs field on each peer declares both an inbound-filter (packets arriving from this peer's tunnel must have a source IP in this list) and an outbound-route (packets destined to these IP ranges go down this peer's tunnel). One field, two jobs, exactly defined. There is no shadow routing table or auxiliary IKE policy file you might miss when troubleshooting.
The minimum viable site-to-site setup is two peers, each with one
[Interface] block and one [Peer] block
referencing the other. Each side's AllowedIPs declares the other
side's overlay IP and the other side's LAN subnet. That's
it — about sixteen lines of configuration across both ends, no
IKE policy to align, no certificate authority to operate. The
complexity arrives at three peers; we'll get there in section
five.
Hold this thought: even this simple two-peer model has a quiet assumption baked in — both peers know each other's endpoint address up front. Section four returns to that assumption when it starts to bite.
How WireGuard handles peer discovery, keys, and handshakes
Most guides on the public web cover WireGuard configuration. Few cover what the protocol is actually doing underneath. The mechanics are worth the ten minutes — they explain why certain failure modes look the way they do, and why some seemingly-similar alternatives behave very differently.
There is no dynamic peer discovery
WireGuard does not have a peer-discovery layer in the base protocol. Every peer's public key is statically configured on the peers it talks to. There is no rendezvous server, no STUN-like NAT hole-punch dance, no broadcast probe — none of that lives in WireGuard core. This is by design (minimal attack surface, no extra moving parts) and it's the wedge for every cloud control plane in the space, including MeshWG. The cloud control plane is the rendezvous layer; it generates and distributes the configurations so the peers themselves never need to discover each other.
The Noise_IK handshake
Each peer holds a long-term static Curve25519 keypair. When two peers first exchange traffic, they run a Noise_IK handshake — exchanging fresh ephemeral keys and deriving session keys via HKDF on the combined static-plus-ephemeral material. The handshake also produces a chaining key used for the next rekey so that even if a current session key is compromised, past traffic stays encrypted (forward secrecy).
The handshake re-runs every two minutes by default if traffic flows. If no traffic flows, the tunnel goes idle and the peer table no longer marks the session as recent. PersistentKeepalive — when configured — sends a 32-byte heartbeat every N seconds (25 is the common default). This keeps the tunnel session alive and, more importantly for branch-office work, keeps the NAT mapping at any intermediate firewall fresh so the tunnel stays reachable through CGNAT.
The peer state machine, observed
From wg show on either side, the entire visible
state surface is: which peers are configured, when each peer's
latest handshake completed, what its last known endpoint IP was,
and how many bytes have moved in each direction. That's all. No
phase-1 SA, no phase-2 SA, no IKE keepalive cycle, no transform
set, no proposal table. The minimalism is operational, not
aesthetic — failure modes become reason-able-about because
there's less state to be wrong in.
For comparison the Linux kernel WireGuard implementation is roughly four thousand lines of C. The original kernel IPsec stack runs to about a hundred thousand. That ratio shows up in everything from boot times to bug counts to how long it takes a new engineer to feel confident reading the source. Section four revisits the IPsec comparison from a deployment angle; the implementation-size point is just to ground why WireGuard's configuration is small in the first place.
How to create a site-to-site VPN?
Five steps, platform-agnostic. The walkthrough below works for Linux servers, MikroTik RouterOS, OpenWrt, OPNsense, and the official WireGuard apps. For the TP-Link-specific menu paths — Archer, Deco, ER, and Omada — see the companion post on TP-Link site-to-site VPN with WireGuard; this one stays at the protocol level so it generalises across gear.
-
Generate a keypair at each site
On Linux or macOS:
wg genkey | tee privatekey | wg pubkey > publickey. On router admin UIs, there's a one-click "Generate keypair" button on the WireGuard panel. The private key stays on that peer; only the public key gets shared with the others. Lose a private key and the move is to regenerate the pair on that peer and re-distribute the new public key — nothing else needs to change. -
Pick the overlay IP scheme
Pick an overlay subnet that does not collide with any LAN you intend to route. The conventional default is
10.100.0.0/24for small mesh networks. Assign one/32per peer — for example 10.100.0.1 for the HQ, 10.100.0.2 for branch-mumbai, 10.100.0.3 for branch-pune. On wg-quick configurations the line isAddress = 10.100.0.1/24(the /24 here is the network mask the kernel uses to know "the rest of this subnet is reachable via wg0"). -
Decide which peer holds the static endpoint
WireGuard is symmetric, but operationally one peer needs an endpoint the others can dial. Pick the peer with the most stable address — typically the HQ on a business fibre line with a static IP. The dialer peers will have
Endpoint = hq.example.com:51820in their configurations; the listener peer has no Endpoint line at all (it just accepts whatever comes in). If neither side has a static IP — both behind ISP CGNAT — you need a third peer with a stable address as the rendezvous. That's what section six and the cloud-control-plane discussion are about. -
Set AllowedIPs correctly on every peer
This is the single most common first-time gotcha. On every peer's
[Peer]block referencing some other peer, AllowedIPs must list both:- The other peer's overlay IP, as a
/32— e.g.10.100.0.2/32 - The other peer's LAN subnet, as the appropriate CIDR — e.g.
192.168.20.0/24
The /32 lets the two peers reach each other directly across the overlay. The LAN subnet entry is what tells the kernel "packets destined to 192.168.20.x go down the wg0 tunnel, not out the default route." Without it, the tunnel comes up,
wg showreports healthy handshakes, butping 192.168.20.5from across the tunnel gets a no-route-to-host error. Missing the LAN entry is why so many setup posts on Reddit ask "tunnel is up but I can't reach LAN" — section 3 of this guide is the answer. - The other peer's overlay IP, as a
-
Bring up the tunnel and verify
wg-quick up wg0on Linux. Apply / Save in the router admin UI. Within about ten seconds the handshake completes. From a LAN client on one side, ping a LAN host on the other side. If the ping answers, the tunnel and the routing are both correct. From either peer,wg showwill display the latest handshake time (seconds ago) and the accumulated transfer bytes in each direction.
The whole walkthrough takes about fifteen minutes the first time and about three minutes once you've done it before. Most of the time gets spent staring at AllowedIPs — write down both peers' overlay IPs and LAN subnets on paper before opening any configuration file. The post-mortem on virtually every "tunnel comes up but routing does not work" support case traces back to a wrong CIDR in AllowedIPs.
Is IPsec better than WireGuard for site-to-site?
Neither is universally better. Both are encrypted tunnels that carry LAN traffic between sites; both are mature enough to stake a production deployment on. The right pick depends on the constraints your environment actually has, not on which protocol your favourite vendor pushes.
Where IPsec is the right pick
- Vendor interop with non-WireGuard endpoints. If you're terminating a tunnel against a Cisco ASA, an AWS Site-to-Site VPN gateway in policy-based mode, a Fortinet firewall at a partner site, or any of the older Juniper SRX family — IPsec is the lingua franca. WireGuard requires WireGuard on both ends; IPsec does not.
- Compliance requirements that name IPsec by name. Some financial-services audit checklists still list IPsec explicitly. Picking the protocol your auditor recognises saves a quarter of arguing.
- You already operate IPsec successfully. Protocol churn for its own sake is not a win. If your team's muscle memory is in IPsec and the deployment is working, keep it.
- Both sides have static public IPs and your IKE policy is well-defined. IPsec's home turf. Phase 1 and phase 2 align quickly when both ends agree on transforms.
Where WireGuard is the right pick
- One or both sides behind ISP CGNAT or DHCP. The typical retail branch in India in 2026 has a CGNAT'd fibre line. WireGuard with PersistentKeepalive handles this cleanly because every peer can dial outbound and the keepalive maintains the NAT mapping. IPsec without extensive NAT-T tuning tends to struggle here.
- Mixed-vendor estates. WireGuard's configuration is identical on TP-Link, MikroTik, OpenWrt, Ubuntu, OPNsense, and Ubiquiti. IPsec is also cross-vendor in theory, but in practice the IKE policy details vary between firmware versions and bite worst during upgrades.
- You want a configuration you can read in five minutes. About eight lines of wg-quick per peer covers a complete site-to-site setup. An equivalent IPsec configuration with full IKEv2 phase 1 and phase 2 policy is closer to thirty lines, plus the transform sets and proposals both ends have to agree on.
- Fast failover matters. WireGuard re-handshakes in a second or two when an upstream IP changes. IPsec's IKE rekey timers are typically longer, and some implementations require a full tunnel teardown before the new IP is accepted.
- It's the 2026 default for new greenfield SMB and prosumer site-to-site deployments. Most teams I talk to who are starting fresh in 2026 pick WireGuard unless they have one of the constraints in the IPsec list above.
The honest summary: this is not a religious choice. Both protocols ship encrypted packets between two networks. Pick by the constraints. MeshWG uses WireGuard because it's the right pick for the BYO-router-plus-cloud-control-plane-plus-branches- behind-CGNAT pattern we serve every day. A different deployment with two static IPs and an existing IPsec stack would be silly to migrate just to chase a protocol fashion.
Multi-site WireGuard: 3, 5, 30 peers
Almost every public-web guide to "WireGuard site-to-site" stops at two routers. The textbook patterns when you add a third are where the manual-configuration approach starts paying its bill.
The full-mesh option
A full mesh of N peers means every peer has direct tunnels to
every other peer. The math is N×(N-1)/2 tunnel pairs to
maintain. Three peers = three pairs. Five peers = ten pairs.
Ten peers = forty-five pairs. Each peer's wg-quick configuration
has N-1 [Peer] blocks; adding peer N+1 means
touching every existing peer's configuration AND adding the new
one. This is why hand-rolled WireGuard mesh deployments past
five or six sites usually collapse into "we should have built
something" within six months.
Full mesh has one real advantage: peer-to-peer flows take the direct path between source and destination. No extra hop, no extra latency. For latency-sensitive workloads — VoIP between two branches, real-time database replication between sites — this matters. For most branch-office work it doesn't.
The hub-and-spoke option
Every peer has exactly one [Peer] block, pointing
at a central hub. The hub has N peer blocks, one per branch.
Branch-to-branch traffic traverses the hub: encrypted at the
source branch, decrypted and re-encrypted at the hub, delivered
encrypted to the destination branch. One extra hop of
WireGuard, a few milliseconds of latency on a well-placed hub.
In return you get a single place for everything: policy lives on the hub, logging is centralised at the hub, revocation is one config change at the hub. Adding peer N+1 is a four-minute job at the new branch and zero changes at the existing peers. For 95% of branch-networking deployments, the trade pays back on the first re-shuffle of which branches exist.
Hub-and-spoke is what virtually every cloud-control-plane WG
product does under the hood, including MeshWG. The mechanics
are transparent: from the branch router's perspective, it's
maintaining one outbound WireGuard tunnel to
vpn.meshwg.com:51820; the hub handles the
forwarding logic.
One operational pattern that matters
When sizing the hub, account for the aggregate bandwidth of cross-branch flows. A 10-branch mesh where four branches stream an overnight backup runs all four backups through the hub. MeshWG's shared hub comfortably supports the small-fleet patterns we see in practice; for sustained, high-throughput cross-branch streaming, the right answer is a dedicated deployment — talk to us and we'll size it for the workload.
WireGuard through CGNAT and double-NAT
This is the section that doesn't show up in any of the top-ranking WireGuard site-to-site guides on the public web, and yet it's the reality for most branch-office work in India in 2026. Worth the words.
CGNAT — Carrier-Grade NAT — is what most Indian ISPs run on their consumer and small-business fibre tiers in 2026. Reliance Jio Fiber, Airtel Xstream Fiber, and ACT Fibernet all default to it on the plans most branches actually buy. What CGNAT means practically: your branch's public IP is shared with thousands of other customers on the same carrier, you cannot accept inbound connections to it, and the IP itself rotates every few hours as the carrier's NAT pool reshuffles.
Traditional site-to-site VPN designs assume both sides have a stable inbound public IP — that's how the "other side" knows where to dial. CGNAT breaks that assumption. The branch doesn't have an inbound IP to publish; even if it did, the IP would change before you could write it down.
How WireGuard handles it
Every peer can be configured as a pure dialer. It sends
outbound UDP to a known endpoint and never accepts inbound
connections at all. The dialer's wg-quick configuration has
an Endpoint = hostname:port line; the listener's
configuration has no Endpoint line.
The single configuration line that makes CGNAT work is
PersistentKeepalive = 25 in the dialer's Peer
block. Every 25 seconds the dialer sends a tiny encrypted
heartbeat outbound. The ISP's NAT layer sees the outbound
packet, refreshes its NAT mapping, and that mapping stays
valid for the next minute or two — long enough for return
packets to find their way back. Without PersistentKeepalive,
the NAT mapping would expire after the carrier's idle
timeout (often 30-60 seconds), and your tunnel would mostly
work but occasionally drop until traffic re-triggered the
mapping.
When both sides are behind CGNAT
The case where neither branch has a stable inbound IP is the common one. Two retail branches, two ISP-CGNAT'd fibre lines, no way for either to dial the other directly. The fix is to introduce a third peer with a stable public address — a cloud hub. Both branches dial the hub outbound; the hub forwards encrypted packets between them. Neither branch opens an inbound port. Neither pays for a static IP. Neither subscribes to a Dynamic DNS service.
This is the no-static-IP scenario modern mesh-VPN platforms like MeshWG are built for. The pattern has been validated through extensive testing on Jio Fiber, Airtel Xstream, and ACT Fibernet in 2026; all three behave the same way — outbound UDP works, PersistentKeepalive holds the mapping, and tunnels recover within a second or two when the branch's public IP rotates. The same applies to the double-NAT case where the ISP-issued router sits in front of the branch router; the keepalive holds through both NAT layers reliably.
What are the disadvantages of WireGuard?
The honest list. None of these are dealbreakers for branch-office or prosumer use, but they're worth knowing before you commit. Per the rest of this site, this section is feature-positive — it describes what WireGuard chose not to do and what that costs in operations.
- No built-in peer discovery. Every peer's public key has to be statically configured on the peers it talks to. There's no equivalent to IPsec's IKE peer-discovery or Tailscale's coordination server in the core protocol. This keeps the attack surface tiny, but it means someone has to do the distribution. Cloud control planes — MeshWG, Tailscale's coordinator, Netbird's signal server, headscale — exist exactly to solve this layer.
- No identity layer beyond the keypair. WireGuard says "this public key is allowed to send packets for this overlay IP." It does not say "this user belongs to this department" or "this device passed the device-posture check." For RBAC, ZTNA, or device-posture scenarios, you layer those on top — typically via the same control plane that distributes the configurations.
- Roaming behaviour is opinionated. If a peer's source IP changes between handshakes, WireGuard accepts the new IP and updates its peer table automatically. That's exactly what you want for laptops moving between Wi-Fi and 4G — and occasionally surprising for static-config scenarios where you'd rather pin the endpoint.
- No traffic shaping, no QoS in the protocol. If you need to prioritise voice over backup traffic at the tunnel level, that work happens in Linux tc, the router's QoS layer, or an upstream firewall — not in WireGuard itself. For most branch deployments this isn't a blocker; for specialised cases it adds an integration step.
- UDP-only in the base protocol. A small number of pathological corporate firewalls block all UDP except port 53 and port 443. WireGuard can be tunneled over TCP/443 via auxiliary tools like wstunnel or udp2raw — but that's not part of WireGuard core; it's an operational workaround. The same workaround applies to IPsec in the same firewall, so this isn't unique to WireGuard.
None of these are dealbreakers for the deployments MeshWG serves. They're the deliberate trade-offs WireGuard made to keep the protocol small enough to be audited, fast enough to live in the kernel hot path, and simple enough that a new engineer can read the source and feel confident in a weekend. For branch networking, the trade was the right one.
Three ways to run WireGuard site-to-site in 2026.
DIY per-peer configs, hub-and-spoke on your own server, or a managed cloud control plane. The right pick depends on how many sites you have, whether your branches have static IPs, and how much of this you want to operate yourself.
| DIY per-peer configs | Self-hosted hub-and-spoke (headscale, wg-easy, etc.) | MeshWG | |
|---|---|---|---|
| Setup time, 2-site mesh | About 15 minutes once you've done it before | About 45 minutes (host setup + hub config + 2 peers) | Under 2 minutes per site |
| Adding the Nth peer when N>2 | Update N existing configs + add 1 new | Update hub config + add the new peer | 1 paste at the new site; 0 changes at the other peers |
| Branches behind ISP CGNAT / no static public IP | Requires one peer with a static IP | Self-host the hub on a VPS with a static IP | Native — every branch dials outbound only, works through CGNAT |
| Key + peer-state distribution | Manual: scp, paste, version control by hand | Self-managed via the hub's admin UI | Cloud control plane handles key rotation, peer state, and revocation |
| Per-site monthly cost (20 sites, US$ or INR) | ₹0 software, paid in engineer-hours | VPS ₹500–2,000/mo + maintenance hours | ₹349 per machine per month, no hub to maintain |
| Open standard underneath | ✓ Pure WireGuard | ✓ Pure WireGuard | ✓ Pure WireGuard — same wg-quick config format your peers already speak |
When to use a cloud control plane vs hand-roll it
The decision is not religious; it's about your environment. Two clear-cut patterns and one gray zone.
Hand-rolled DIY is the right pick when
- You have two or three sites, all with static public IPs, and growth past five sites is not on the 12-month roadmap.
- You have an in-house network engineer who already runs Linux infrastructure and considers wg-quick configuration trivial — and who has the time to maintain the keys, the AllowedIPs, and the per-peer state by hand.
- You explicitly want zero third-party dependency. This is a defensible choice for some scenarios — government, air-gapped industrial, certain compliance regimes. The operational cost is real but the surface area you control is also real.
A cloud control plane earns its keep when
- One or more of your branches don't have static public IPs. Section six's CGNAT case is the typical one; without a stable rendezvous point, neither manual nor self-hosted DIY actually works without significant additional engineering.
- You're already at five sites, or expect to be within twelve months. The hand-roll math gets painful between site five and site ten.
- You don't have a full-time network engineer, and you don't want to make this someone's part-time job. The control plane handles key rotation, peer state distribution, and revocation so your team doesn't have to.
- You want a single place to revoke a compromised branch within seconds — without a coordinated configuration update cycle at every other branch.
- You want every branch to come online while others are down. Cloud control planes handle the peer-state propagation so an offline HQ doesn't prevent a new branch from joining the mesh.
The pilot pattern
Even for organisations that will eventually hand-roll, starting with MeshWG's two-machines-free tier provides a low-commitment way to validate topology and routing decisions before any operational investment. Some deployments remain on the free tier indefinitely — home labs and one-engineer environments that never exceed two peers. Others scale from a two-peer pilot to thirty branches inside three months. Both are valid trajectories of the same disciplined evaluation; the central value of the pilot is that it answers the architectural questions before either path becomes locked in.
Common questions
Can WireGuard be used for site-to-site VPN?
Yes. WireGuard is well-suited for site-to-site VPN because every peer is symmetric — there is no client/server asymmetry — and the same wg-quick configuration that works between two laptops works between two routers and between thirty. The minimum viable case is two peers, each with one Interface and one Peer block, where AllowedIPs declares the remote subnet. Section 1 covers the two-peer case in detail.
Is IPsec better than WireGuard for site-to-site?
Neither protocol is universally better. IPsec is mature and the right pick when you need to interoperate with non-WireGuard endpoints (Cisco ASA, AWS Site-to-Site VPN gateway) or both sides have static public IPs and your team already runs IPsec confidently. WireGuard is the 2026 default for branches behind ISP CGNAT, mixed-vendor estates, and teams that want a configuration they can read in five minutes. Section 4 has the decision framework with each protocol's sweet spot.
What are the disadvantages of WireGuard?
WireGuard has no built-in peer discovery (every public key is statically configured), no identity layer beyond the keypair, no QoS or traffic shaping in the protocol, and is UDP-only by default. None of these block branch-office or prosumer use — they are the design trade-offs that keep the protocol small enough to audit (around 4,000 lines of kernel code). Section 7 has the full honest list and how each disadvantage is addressed in practice.
How to create a site-to-site VPN with WireGuard?
Five steps, platform-agnostic: (1) generate a keypair at each site with wg genkey | wg pubkey, (2) pick the overlay IP scheme — typically a /24 like 10.100.0.0/24, (3) decide which peer holds the static endpoint (or use a cloud peer if neither does), (4) set AllowedIPs to include both the remote overlay IP and the remote LAN subnet, (5) bring up the tunnel with wg-quick up wg0. Section 3 has the detailed walkthrough.
Does WireGuard support multiple sites in one VPN?
Yes. Two topology options: full mesh, where every peer has direct tunnels to every other peer; or hub-and-spoke, where every peer has one tunnel to a central hub that forwards between peers. Full mesh has lower latency for direct peer-to-peer flows but requires N×(N-1)/2 tunnel pairs to maintain. Hub-and-spoke scales cleanly past ten sites and is what cloud control planes including MeshWG use. Section 5 walks through both options.
How does WireGuard work behind CGNAT?
Every peer can be configured to dial outbound only, never accepting inbound connections. PersistentKeepalive = 25 sends a small encrypted heartbeat outbound every 25 seconds, which keeps the NAT mapping at the ISP edge alive so return packets find their way back. If both sides are behind CGNAT (the common case for retail branches on Indian fibre), you need a third peer with a stable public address — a cloud hub — for both branches to dial. Section 6 has the details with Indian-ISP verification.
What's the simplest WireGuard site-to-site configuration?
Two wg-quick configuration files, one at each site, each with one Peer block referencing the other. Total is roughly sixteen lines of configuration across both ends. The catch every first-time setup hits is AllowedIPs: each peer must list both the other peer's overlay IP (typically a /32) AND the other peer's LAN subnet (typically a /24). Missing the LAN subnet is why people get a working tunnel but cannot ping the remote LAN. Section 3 step 4 spells out the exact pattern.