WireGuard Site-to-Site VPN: Complete Configuration Guide
WireGuard Site-to-Site VPN: Complete Configuration Guide
Section titled “WireGuard Site-to-Site VPN: Complete Configuration Guide”RouterOS Version: 7.x+ Difficulty: Intermediate Estimated Time: 30 minutes
TL;DR (quick start)
Section titled “TL;DR (quick start)”For the impatient: here’s the 30-second version.
# On both routers: create interface and get public key/interface wireguard add name=wg-tunnel listen-port=13231/interface wireguard print
# On initiator (Office A): configure peer with remote endpoint/interface wireguard peers add interface=wg-tunnel public-key="OFFICE_B_KEY" allowed-address=10.2.0.0/24,10.255.255.2/32 endpoint-address=198.51.100.20 endpoint-port=13231/ip address add address=10.255.255.1/30 interface=wg-tunnel
# On responder (Office B): configure peer without endpoint/interface wireguard peers add interface=wg-tunnel public-key="OFFICE_A_KEY" allowed-address=10.1.0.0/24,10.255.255.1/32/ip address add address=10.255.255.2/30 interface=wg-tunnelOverview
Section titled “Overview”WireGuard is a modern VPN protocol that provides secure, high-performance tunnels between sites with minimal configuration overhead. Unlike traditional IPsec, WireGuard uses state-of-the-art cryptography and a simple peer-to-peer model that makes site-to-site connections both easier to configure and more reliable to maintain.
This guide explains how to establish secure tunnels between remote offices, covering the essential concepts, common pitfalls, and troubleshooting techniques that separate working configurations from broken ones.
Understanding WireGuard fundamentals
Section titled “Understanding WireGuard fundamentals”The peer-to-peer model
Section titled “The peer-to-peer model”WireGuard operates on a peer-to-peer basis - there’s no inherent “server” or “client” distinction. Each endpoint is a peer that can initiate connections to other peers. This simplicity is both WireGuard’s strength and the source of most configuration errors.
Key concepts
Section titled “Key concepts”Public/Private Key Pairs: Each WireGuard interface has a unique key pair. The private key never leaves the device; public keys are exchanged between peers for authentication.
Allowed Addresses: This is the most critical and misunderstood setting. It serves two purposes:
- Ingress filtering: Traffic FROM these addresses is accepted from this peer
- Routing table: Traffic TO these addresses is sent to this peer
Endpoint: The public IP address and port where a peer can be reached. Only one peer needs to know the other’s endpoint - WireGuard learns return paths automatically.
The critical mistake: overlapping allowed addresses
Section titled “The critical mistake: overlapping allowed addresses”The most common error is configuring overlapping allowed-addresses on the same interface:
# WRONG - This will cause routing conflicts/interface wireguard peersadd allowed-address=10.1.0.0/24 interface=wg1 public-key="peer1-key"add allowed-address=10.1.0.0/24 interface=wg1 public-key="peer2-key" # Overlap!Each subnet can only be allowed from one peer per interface. If multiple peers need access to the same subnet, they must share a single peer configuration or use different WireGuard interfaces.
Network architecture example
Section titled “Network architecture example”For this guide, we’ll configure a tunnel between two offices:
Tunnel addressing: We use 10.255.255.0/30 for the tunnel itself - a point-to-point link between the routers.
Routing logic:
- Traffic to 10.2.0.0/24 from Office A → goes via wg-tunnel to Office B
- Traffic to 10.1.0.0/24 from Office B → goes via wg-tunnel to Office A
Prerequisites
Section titled “Prerequisites”- Both routers have public IP addresses or port forwarding configured
- RouterOS 7.x+ installed on both devices
- UDP port 13231 (or chosen port) accessible from the internet
- Basic understanding of IP routing and subnetting
Configuration steps
Section titled “Configuration steps”This minimal example establishes a working tunnel between two sites. We’ll configure Office A as the initiator (knows Office B’s endpoint) and Office B as the responder.
Step 1: Create WireGuard interfaces
Section titled “Step 1: Create WireGuard interfaces”On both routers, create the WireGuard interface. This automatically generates the cryptographic key pairs:
/interface wireguard add name=wg-tunnel listen-port=13231Step 2: Exchange public keys
Section titled “Step 2: Exchange public keys”Display the generated public key on each router:
/interface wireguard printNote the public-key value from each router - you’ll need to configure these on the opposite peer.
Step 3: Configure peers
Section titled “Step 3: Configure peers”Office A (Initiator):
/interface wireguard peers add interface=wg-tunnel public-key="OFFICE_B_PUBLIC_KEY" allowed-address=10.2.0.0/24,10.255.255.2/32 endpoint-address=198.51.100.20 endpoint-port=13231Office B (Responder):
/interface wireguard peers add interface=wg-tunnel public-key="OFFICE_A_PUBLIC_KEY" allowed-address=10.1.0.0/24,10.255.255.1/32 responder=yesKey differences:
- Office A specifies the
endpoint-address(Office B’s public IP) - Office B uses
responder=yes(only responds, doesn’t initiate) - Each peer’s
allowed-addressincludes the remote LAN and tunnel IP
Step 4: Assign tunnel IP addresses
Section titled “Step 4: Assign tunnel IP addresses”Office A:
/ip address add address=10.255.255.1/30 interface=wg-tunnelOffice B:
/ip address add address=10.255.255.2/30 interface=wg-tunnelVerification
Section titled “Verification”Check 1: Interface status
Section titled “Check 1: Interface status”Verify the WireGuard interface is running:
/interface wireguard printExpected Output:
Flags: R - RUNNING 0 R name="wg-tunnel" mtu=1420 listen-port=13231 private-key="..." public-key="..."Check 2: Peer handshake
Section titled “Check 2: Peer handshake”Confirm the tunnel has established successfully:
/interface wireguard peers printExpected Output:
0 interface=wg-tunnel public-key="..." allowed-address=10.2.0.0/24,10.255.255.2/32 current-endpoint-address=198.51.100.20 current-endpoint-port=13231 last-handshake=5sThe last-handshake should show a recent time (under 3 minutes).
Check 3: Tunnel connectivity
Section titled “Check 3: Tunnel connectivity”Test basic tunnel connectivity:
/ping 10.255.255.2 count=3Expected Output:
SEQ HOST SIZE TTL TIME STATUS 0 10.255.255.2 56 64 25ms 1 10.255.255.2 56 64 24ms 2 10.255.255.2 56 64 26ms sent=3 received=3 packet-loss=0% min-rtt=24ms avg-rtt=25ms max-rtt=26msAdvanced configuration
Section titled “Advanced configuration”Adding static routes
Section titled “Adding static routes”For automatic routing between LANs, add static routes on both routers:
Office A:
/ip route add dst-address=10.2.0.0/24 gateway=wg-tunnelOffice B:
/ip route add dst-address=10.1.0.0/24 gateway=wg-tunnelFirewall configuration
Section titled “Firewall configuration”If you have restrictive firewall rules, allow WireGuard traffic:
Allow WireGuard UDP traffic:
/ip firewall filter add action=accept chain=input protocol=udp dst-port=13231 place-before=0Allow tunnel traffic forwarding:
/ip firewall filter add action=accept chain=forward in-interface=wg-tunnel place-before=0/ip firewall filter add action=accept chain=forward out-interface=wg-tunnel place-before=0NAT considerations
Section titled “NAT considerations”If devices behind the tunnel need internet access via the remote site, configure source NAT:
/ip firewall nat add action=masquerade chain=srcnat out-interface=ether1 src-address=10.1.0.0/24Troubleshooting guide
Section titled “Troubleshooting guide”Problem: Handshake never completes
Section titled “Problem: Handshake never completes”Symptoms: last-handshake shows “never” or very old timestamp
Common Causes and Solutions:
-
Firewall blocking UDP: Ensure UDP port 13231 is allowed on both routers
/ip firewall filter add chain=input protocol=udp dst-port=13231 action=accept place-before=0 -
Wrong or unreachable endpoint: Confirm the endpoint-address is correct and reachable
/tool traceroute 198.51.100.20/ping 198.51.100.20 -
Public key mismatch: Each peer must have the OTHER router’s public key
# On Router A, peer entry should have Router B's public key (not Router A's)/interface wireguard peers print -
NAT without port forwarding: If the endpoint router is behind NAT, configure port forwarding for UDP 13231
-
Time synchronization: WireGuard requires accurate clocks on both endpoints
/system ntp client print/system clock print
WebFig Bug: Empty endpoint-address
Critical: WebFig has a known bug where saving a peer without an endpoint-address sets it to "" (empty string) instead of leaving it unset. This causes handshakes to fail.
Symptoms: Tunnel worked, then stopped after editing peer in WebFig. Config appears correct.
Check for the bug:
/interface wireguard peers print detail# Look for: endpoint-address=""Solution: Use CLI to properly remove the endpoint-address:
# This is WRONG (WebFig does this):/interface wireguard peers set 0 endpoint-address=""
# This is CORRECT - use CLI to unset:/interface wireguard peers unset 0 endpoint-addressAlways use CLI (not WebFig) when configuring WireGuard peers without endpoints.
Debug commands:
/log print where topics~"wireguard"/interface wireguard peers print detailProblem: Tunnel connects but no LAN traffic
Section titled “Problem: Tunnel connects but no LAN traffic”Symptoms: Tunnel IPs ping, but LAN-to-LAN traffic fails
Solutions:
- Check allowed-address: Must include both tunnel IPs AND remote LANs
- Verify routing: Add explicit routes to remote networks
- Firewall rules: Ensure forward chain allows tunnel traffic
- Asymmetric routing: Check that return traffic uses the same path
Debug commands:
/ip route print where gateway=wg-tunnel/tool traceroute 10.2.0.1 src-address=10.1.0.1Problem: Connection drops frequently
Section titled “Problem: Connection drops frequently”Symptoms: Tunnel works intermittently, handshake times vary wildly, last-handshake shows >2 minutes
Solutions:
-
Add keepalive for NAT traversal: The peer BEHIND NAT must send keepalives to maintain the NAT mapping
# On the peer that is behind NAT (the initiator/client side)/interface wireguard peers set 0 persistent-keepalive=25s -
MTU issues: Reduce MTU to avoid fragmentation
/interface wireguard set wg-tunnel mtu=1380 -
ISP blocking: Some ISPs block or throttle VPN traffic - try different ports
/interface wireguard set wg-tunnel listen-port=51820 -
Dynamic IP without DDNS: If the endpoint’s public IP changes, implement DDNS and use hostname for endpoint-address
Problem: Overlapping allowed addresses
Section titled “Problem: Overlapping allowed addresses”Symptoms: Routing table conflicts, traffic goes to wrong peer
Solution: Each subnet can only appear in one peer’s allowed-address per interface:
# WRONG - 10.1.0.0/24 appears twiceadd allowed-address=10.1.0.0/24,10.2.0.0/24 interface=wg-tunnel public-key="peer1"add allowed-address=10.1.0.0/24,10.3.0.0/24 interface=wg-tunnel public-key="peer2"
# CORRECT - Non-overlapping subnetsadd allowed-address=10.2.0.0/24 interface=wg-tunnel public-key="peer1"add allowed-address=10.3.0.0/24 interface=wg-tunnel public-key="peer2"Useful debug commands
Section titled “Useful debug commands”# Check WireGuard interface statistics/interface wireguard print stats
# Monitor peer connection status/interface wireguard peers print detail
# View WireGuard-specific logs/log print where topics~"wireguard"
# Test tunnel with specific source/ping 10.2.0.1 src-address=10.1.0.1
# Check routing table for tunnel routes/ip route print where gateway~"wg"Security considerations
Section titled “Security considerations”Key management
Section titled “Key management”- Never share private keys - each device generates its own
- Rotate keys periodically - especially if devices are compromised
- Use strong entropy - RouterOS generates cryptographically secure keys automatically
Network segmentation
Section titled “Network segmentation”# Restrict tunnel traffic to specific services/ip firewall filter add action=accept chain=forward in-interface=wg-tunnel dst-port=22,80,443 protocol=tcp/ip firewall filter add action=drop chain=forward in-interface=wg-tunnelMonitoring and logging
Section titled “Monitoring and logging”# Log all tunnel connections/system logging add topics=wireguard action=memory
# Monitor data usage per peer/interface wireguard peers print statsMulti-site scenarios
Section titled “Multi-site scenarios”Hub-and-spoke topology
Section titled “Hub-and-spoke topology”For connecting multiple branch offices through a central hub:
Hub configuration: Each branch gets its own peer with non-overlapping allowed-addresses.
Branch configuration: Each branch only needs one peer pointing to the hub.
Full mesh topology
Section titled “Full mesh topology”For direct branch-to-branch communication without going through a hub:
Configuration: Each router needs peers for every other router. With N sites, each router needs N-1 peer configurations.
Performance optimization
Section titled “Performance optimization”Hardware offloading
Section titled “Hardware offloading”WireGuard benefits from AES-NI acceleration on x86 devices:
/system resource print# Look for "cpu-features" containing "aes"MTU tuning
Section titled “MTU tuning”Optimize MTU to avoid fragmentation:
# Test optimal MTU size/ping 8.8.8.8 size=1472 do-not-fragment
# Adjust WireGuard MTU accordingly/interface wireguard set wg-tunnel mtu=1420Connection limits
Section titled “Connection limits”Monitor connection tracking on high-traffic tunnels:
/ip firewall connection print count-only/ip settings printRelated topics
Section titled “Related topics”Prerequisites
Section titled “Prerequisites”- IP Address Configuration - interface addressing for WireGuard
- Static Routes - routing remote networks over VPN
- Firewall Basics - allow UDP 13231 for WireGuard
Alternative VPN Technologies
Section titled “Alternative VPN Technologies”- IPsec IKEv2 - industry-standard site-to-site VPN
- L2TP Server - remote access VPN for clients
Related articles
Section titled “Related articles”- NAT masquerade - NAT for VPN traffic
- Firewall mangle - mark VPN traffic for QoS
- OSPF - dynamic routing over WireGuard