Skip to main content
RunBook Academy

VyOSXLI · WireGuardWireGuard

WireGuard routing — routing over WireGuard, MTU 1420, MSS clamping

Advanced⏱ ~22 minshow interfaces wireguardshow ip routeconfigurecomparecommitsaverollbackpingtcpdumptraceroute

What you'll learn

  • Explain how packets flow through a WireGuard tunnel at the routing level
  • Calculate the MTU of a WireGuard tunnel (1420 bytes)
  • Configure the MSS clamping for TCP-over-tunnel
  • Recognise the production routing failure modes (MTU, MSS, asymmetric routing)

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15

Not yet marked complete on this device.

WireGuard tunnels carry IP packets across an untrusted network. The tunnel is a virtual interface (wg0) with its own IP address and MTU; packets sent into the tunnel are encrypted and encapsulated in UDP, then sent over the underlying network. The routing decision on the inner packet is independent of the routing decision on the outer packet; the operator must configure routes on both layers.

This lesson covers the routing flow through a WireGuard tunnel, the MTU calculation (1420 bytes for the inner packet, not 1500), the MSS clamping that makes TCP work over the tunnel, and the production patterns for dynamic routing (BGP, OSPF point-to-point) over the tunnel.

How packets flow through the tunnel

When a host sends a packet to a destination behind the peer:

  1. The host sends the packet to its default gateway (the local router’s LAN IP).
  2. The local router receives the packet on the LAN interface.
  3. The local router looks up the destination in its routing table; the destination matches the route through wg0 (installed by the peer’s allowed-ips).
  4. The router sends the packet into wg0. The WireGuard kernel module encrypts it and encapsulates it in a UDP packet.
  5. The UDP packet is sent out the WAN interface (or whichever interface routes to the peer’s endpoint).
  6. The UDP packet travels across the untrusted network to the peer’s endpoint.
  7. The peer receives the UDP packet, decrypts the inner packet, and delivers it to the peer’s local network.
  8. The destination host receives the inner packet and responds.
  9. The reverse path (destination → peer → WAN → local router → LAN → host) follows the same steps in reverse.
sequenceDiagram
  participant H1 as Host (10.0.0.50)
  participant R1 as R1 (WireGuard)
  participant NET as Untrusted network
  participant R2 as R2 (WireGuard)
  participant H2 as Host (10.20.0.50)
  H1->>R1: TCP SYN to 10.20.0.50:80
  R1->>R1: routing decision: 10.20.0.0/16 via wg0
  R1->>R1: encrypt inner packet (10.0.0.50 -> 10.20.0.50)
  R1->>NET: UDP packet (src=R1.pub, dst=R2.pub:51820)
  NET->>R2: UDP packet
  R2->>R2: decrypt inner packet
  R2->>H2: TCP SYN (10.0.0.50 -> 10.20.0.50:80)
  H2->>R2: TCP SYN-ACK
  R2->>R2: encrypt reply (10.20.0.50 -> 10.0.0.50)
  R2->>NET: UDP packet to R1.pub:51820
  R1->>R1: decrypt reply
  R1->>H1: TCP SYN-ACK

The inner packet travels through the tunnel transparently. The outer packet carries the encrypted payload. The router does not re-encrypt or re-route the inner packet during transit — it routes the outer packet based on the peer’s endpoint.

The MTU calculation — 1420, not 1500

The default Ethernet MTU is 1500 bytes. A WireGuard tunnel adds overhead:

LayerOverhead
Inner IP header20 bytes
Inner TCP header20 bytes
UDP header8 bytes
Outer IP header20 bytes
WireGuard encryption/padding32 bytes

Total overhead: 80 bytes. The maximum inner packet size that fits in the outer 1500-byte Ethernet frame is:

1500 - 20 (outer IP) - 8 (UDP) - 32 (WireGuard) = 1440

Some sources use slightly different numbers (the exact overhead depends on whether IPv4 or IPv6, on whether the IP header has options, etc.). The most commonly cited value is 1420 bytes as the MTU for the WireGuard interface, leaving a safety margin.

# Set the MTU on the WireGuard interface
set interfaces wireguard wg0 mtu 1420

Some operators set the MTU lower (e.g., 1380) to be extra safe. The trade-off: lower MTU means more fragmentation for large packets. The right MTU depends on the underlying network’s path MTU.

MSS clamping for TCP

TCP connections negotiate their Maximum Segment Size (MSS) during the SYN/SYN-ACK exchange. The MSS is the largest TCP payload that fits in a single IP packet, accounting for the IP and TCP headers. For Ethernet, the standard MSS is 1460 bytes (1500 - 40 bytes for IP + TCP headers).

When a TCP connection goes through a WireGuard tunnel with MTU 1420, the MSS needs to be smaller (e.g., 1380 bytes for safety). Without MSS clamping, the TCP endpoints may agree on MSS 1460 and then send 1460-byte segments that exceed the tunnel MTU; the tunnel must fragment them (or drop them, depending on the DF bit).

The fix: MSS clamping at the firewall. The firewall (or the router) rewrites the MSS in the TCP SYN/SYN-ACK to a value appropriate for the tunnel.

# Configure MSS clamping on the WireGuard interface
set interfaces wireguard wg0 mss 1380
# or
set firewall options mss-clamp interface wg0 1380

The MSS clamp value should be slightly smaller than the MTU to allow for any additional overhead (e.g., 1380 for MTU 1420, leaving 40 bytes for IP + TCP headers).

Static routing over WireGuard

A typical site-to-site configuration has static routes pointing to the peer’s network via the tunnel interface:

# On R1
set protocols static route 10.20.0.0/16 next-hop 10.10.10.2
# Or directly through the interface
set protocols static route 10.20.0.0/16 interface wg0

# Verify
show ip route 10.20.0.0/16
# S* 10.20.0.0/16 [1/0] via 10.10.10.2, wg0

The route via the tunnel interface sends traffic into wg0; the kernel routes the encrypted packet via the WAN interface based on the peer’s endpoint.

Dynamic routing over WireGuard

BGP works well over WireGuard (BGP is unicast-only, which matches WireGuard’s unicast-only nature). OSPF requires configuration changes (network-type point-to-point, since WireGuard does not forward multicast).

# BGP over WireGuard

# On R1
set interfaces wireguard wg0 address 10.10.10.1/24
set protocols bgp system-as 65001
set protocols bgp neighbor 10.10.10.2 remote-as 65002
set protocols bgp neighbor 10.10.10.2 update-source 10.10.10.1

# Verify
show ip bgp summary
# The peer should be Established

# On R2
set protocols bgp system-as 65002
set protocols bgp neighbor 10.10.10.1 remote-as 65001
set protocols bgp neighbor 10.10.10.1 update-source 10.10.10.2

The BGP session runs over the tunnel (peer’s tunnel IP). BGP advertises routes; the routes are installed in the routing table; traffic flows via the tunnel.

OSPF requires additional configuration:

# OSPF over WireGuard (point-to-point)

set protocols ospf area 0 network 10.10.10.0/24
set interfaces wireguard wg0 ip ospf network point-to-point

# Verify
show ip ospf neighbor
# Should show the peer via wg0

WireGuard does not forward multicast (which OSPF uses for neighbour discovery). Setting the OSPF network type to point-to-point forces unicast OSPF hello packets; adjacency forms via direct unicast.

Configuration and validation

configure
# Set the MTU on the WireGuard interface
set interfaces wireguard wg0 mtu 1420

# Configure static routes for the peer's network
set protocols static route 192.168.50.0/24 next-hop 10.10.10.2

# Optional: BGP over the tunnel
set protocols bgp system-as 65001
set protocols bgp neighbor 10.10.10.2 remote-as 65002

# Configure MSS clamping at the firewall
set firewall options mss-clamp interface wg0 1380

commit
save

Validation:

# Verify the route
show ip route 192.168.50.0/24
# Should show "via wg0"

# Test with a large packet
ping -s 1400 192.168.50.1
# Should succeed; this is near the MTU

ping -s 1500 192.168.50.1
# Should fail (or fragment); this exceeds the tunnel MTU

# Verify the BGP session
show ip bgp summary
# The peer should be Established

# Trace the route
traceroute 192.168.50.1
# Should show the path via wg0

A clean validation: routes via the tunnel are correct; the MTU test with -s 1400 succeeds and -s 1500 fails (or fragments); the BGP session is established; the MSS is clamped (TCP works).

Production failure modes

MTU too low, performance suffers

The operator sets MTU to 800 on the WireGuard interface. Large packets are fragmented unnecessarily; throughput drops.

Diagnostic: ping -s 1400 <peer-tunnel> fails; ping -s 700 <peer-tunnel> succeeds.

Fix: set MTU to 1420 (IPv4) or 1380 (larger safety margin).

MTU too high, packets drop

The operator leaves the default MTU (1500). Large packets exceed the tunnel capacity; they are fragmented or dropped.

Diagnostic: ping -s 1400 <peer-tunnel> succeeds; ping -s 1500 <peer-tunnel> fails (or fragments with high drop rate).

Fix: set MTU to 1420.

MSS not clamped, TCP performance degrades

TCP connections negotiate MSS 1460; segments exceed the tunnel MTU; fragmentation/drops reduce throughput.

Diagnostic: tcpdump -ni wg0 shows fragmented packets. Web downloads are slow.

Fix: configure MSS clamping on the WireGuard interface (e.g., 1380).

Asymmetric routing

The forward path uses R1 → R2 → R3. The reverse path uses R3 → R2 → R1 (same path), but a stateful firewall in the middle drops the return packets because it has no state.

Diagnostic: traceroute shows different forward/reverse paths; TCP connections stall.

Fix: align the routing on both sides; ensure the same path is used for both directions.

OSPF adjacency does not form over WireGuard

OSPF does not establish adjacency; the peers remain in Down state.

Diagnostic: show ip ospf neighbor shows no peer; tcpdump -ni wg0 'proto 89' shows no OSPF packets.

Fix: configure OSPF network type as point-to-point on the WireGuard interface.

Rollback

# Enter configuration mode and write the running configuration to a
# file you can load back. `save` is a configuration-mode command that
# takes a path; operational mode has no `| save` pipe.
configure
save /config/pre-change-wg-routing-TICKET.conf

# Remove the WireGuard routing
delete protocols static route 192.168.50.0/24 next-hop 10.10.10.2
delete firewall options mss-clamp interface wg0

# Read the diff before committing anything
compare
commit

# Or restore the previous configuration
load /config/pre-change-wg-routing-TICKET.conf
commit
save

The rollback removes the routing and MSS clamp; traffic reverts to the original path (or fails if no backup path).

Production discipline

Cross-course references

  • Part XLI-01 (XLI-VyOS-WireGuard / concept) covers the protocol basics.
  • Part XLI-03 (XLI-VyOS-WireGuard / peers) covers the peer configuration that sets up the routing.
  • Part LI-02 (LI-VyOS-MTU / tunnel overhead) covers the MTU calculations for tunnels in general.
  • Part LI-04 (LI-VyOS-MTU / MSS clamping) covers the MSS clamping mechanism.
  • Part XLIII-02 (XLIII-VyOS-VPNRouting / BGP over VPN) covers BGP over a tunnel in detail.

Quiz

Knowledge check · 4 questions

  1. Q1. What is the recommended MTU for a WireGuard interface on an IPv4 network?

  2. Q2. MSS clamping is optional for TCP-over-WireGuard connections; without it, TCP works fine because the TCP endpoints negotiate an MSS appropriate for the tunnel.

  3. Q3. An operator deploys a WireGuard tunnel between two sites. Ping and traceroute work through the tunnel. However, web downloads from hosts behind the tunnel are slow — much slower than expected for the link capacity. What is the most likely cause?

    R1 and R2 have a WireGuard tunnel. The MTU on wg0 is left at default (1500). No MSS clamping is configured. Hosts behind R1 can ping hosts behind R2 (small packets); traceroute works. But HTTP downloads from a host behind R2 are slow. The link capacity should support 100 Mbps; actual throughput is 10 Mbps.

  4. Q4. An operator configures OSPF on the WireGuard interface. The OSPF adjacency does not form. The peers remain in Down state. What is the most likely cause?

    R1 and R2 have a WireGuard tunnel (wg0). The operator configures OSPF area 0 on both routers with the wg0 interface as an OSPF interface. Default network type (broadcast). OSPF adjacency does not form. `show ip ospf neighbor` shows no peer.

Passing score: 75%. Answers are checked in this browser.