Illustrative two-site WireGuard diagram and gateways at a WIUNIX Academy workstation

WIUNIX ACADEMY

Set up a routed WireGuard site-to-site VPN on Ubuntu and Debian

Connect two non-overlapping LANs with dedicated WireGuard gateways. Verify peer identity, return routes, narrow firewall rules and real receiver data in both directions.

Advanced60 min readUpdated
Make this guide yours

YOUR SYSTEM. YOUR STEPS.

Where are you working?

Choose your OS and version. The prerequisites, commands and troubleshooting follow your environment.

Ubuntu 26.10Reviewed against official documentation ·

USE YOUR OWN VALUES

Configure this tutorial

Set the example values for your environment; related explanations and copy panels update together. Never enter passwords, private keys or tokens. Values stay in this tab and are not sent to the server or share links. Check actual DNS, certificates and network policy before running commands.

Different IP addresses, domains or ports? Open the settings below, change the values and select “Apply to tutorial”, then copy the updated commands.

Set values for my environment24 editable values

THE OUTCOME

What will you have at the end?

Two routed LANs with authenticated peers, explicit service policy, proven bidirectional receiver data and retained recovery inputs.

01LAN A · 10.10.10.0/24router .1 → VPN .2
02WireGuard · UDP5182010.255.255.1 ↔ 10.255.255.2
03LAN B · 10.20.20.0/24VPN .2 → host .100
Supported operating systems and versions

OS paths are documentation-reviewed; isolated runtime evidence is distinct from complete distro installation and public-internet testing.

Before you begin

  • Fresh gateways with preconfigured LAN/WAN, IPv4 management, independent consoles and no existing VPN/firewall manager.
  • Non-overlapping LANs and control of persistent router routes and test-host policies.
  • Reachable UDP endpoints and authenticated public peer identities.

Two sites and their actual routers

A uses LAN 10.10.10.0/24: ordinary router 10.10.10.1, VPN gateway 10.10.10.2, test host 10.10.10.100, WAN ens18 and LAN interface ens19. B uses 10.20.20.0/24: ordinary router 10.20.20.1, VPN gateway 10.20.20.2, test host 10.20.20.100, WAN ens18 and LAN interface ens19. Interfaces and addresses are already configured by their OS network manager. Tunnel wg0 uses A 10.255.255.1/30 and B 10.255.255.2/30. Public endpoints are A 198.51.100.10 and B 203.0.113.20, UDP 51820. Initial public/management values are documentation examples: configure actual reachable addresses and the real management source. LAN, tunnel and management ranges must not overlap.

Route selection, peer identity and firewall policy

The Linux route selects wg 0. WireGuard then selects a peer using the destination and AllowedIPs; on receive it checks the authenticated peer’s inner source address against that peer’s AllowedIPs. A lists B’s tunnel /32 and LAN, and B lists A’s. wg-quick automatically adds those routes. The firewall independently permits ICMP between the LANs and TCP 8080 only between the two test hosts, in either direction, plus established replies. There is no default route, DNS override, bridge, IPv6 VPN or masquerade. Real LAN source addresses remain visible. Encryption ends at the gateways; retain application authentication and TLS beyond them.

Fresh dedicated gateways and independent management

Use fresh systemd gateways with a tested out-of-band console and IPv4 SSH path. Do not apply this to production routers, Docker hosts, existing VPNs, UFW/firewalld hosts or a nonempty nftables ruleset. Other base chains can drop traffic despite an accept here. Keep the current SSH session open, then prove a SECOND session after enabling the filter. Management CIDR 192.0.2.0/24 and SSH 22 below are examples: replace with the actual source seen by each gateway and your real port. Upstream/cloud ACLs must separately permit the peer UDP exchange. This is a single IPv4 tunnel, not HA or uninterrupted-service proof.

What was actually exercised

Reviewed 2026-10-20. An isolated one-host lab used kernel 6.8 and distribution wireguard-tools 1.0.20210914: two gateways, two ordinary routers and two LAN hosts in six private network namespaces. Twenty-four checks covered real handshakes, exact bidirectional receiver data with original sources, blocked ports/sources, missing return-route and AllowedIPs failures, MTU, recovery from restored inputs and scoped reversal. The source backup/restore panels also ran with protected scratch-path substitutions. All lab children stopped. This is not a real internet/NAT, physical-site, full systemd boot, provider firewall, production SSH or all-OS installation test. Every selectable OS path remains documentation-reviewed.

01

LET’S BUILD

Inspect A and B without changing them

On both gateways as the existing sudo administrator, in Bash. Confirm selected OS, actual interfaces, addresses, routes, SSH source and listeners. Any existing key/config or forwarding workload is a stop condition. Missing directories and inactive/missing services are normal for a fresh host. If nft is absent, inspect its rules after installation.

Bash
. /etc/os-release
printf '%s %s\n' "$ID" "$VERSION_ID"
uname -r
ip -br address
ip -4 route show table all
ip rule show
printf 'SSH source/session: %s\n' "${SSH_CONNECTION:-console}"
sudo ss -lunpt
sudo sysctl net.ipv4.ip_forward
sudo find /etc/wireguard -maxdepth 1 -type f -print 2>/dev/null
systemctl is-active ufw firewalld nftables
How do I know it worked?

Addresses and OS match; no existing VPN/firewall/routing workload is being replaced.

02

LET’S BUILD

Install from this OS release’s repositories

On both fresh gateways. APT verifies signed distro metadata and hashes. Reviewed stock kernels provide WireGuard: no foreign-release repository, DKMS workaround or downloaded installer. A restricted container can lack NET_ADMIN; use a supported VM instead of changing production kernel settings. Test hosts need curl and python3 from their own distribution.

Bash
sudo apt-get update
sudo apt-get install wireguard-tools nftables iproute2 iputils-ping curl python3 nano
wg --version
dpkg-query -W wireguard-tools nftables
sudo nft list ruleset
How do I know it worked?

Tools are present and the ruleset is EMPTY. If rules or another firewall manager exist, STOP and integrate through their owner.

Explore all tutorials ↗