Routing traffic through Wireguard peers

Wireguard is an amazing VPN solution that in 10 years time will be the go-to VPN solution for most. If you haven’t heard of it yet, go check it out.

Common scenario

I had a situation where clients want to access internal network which is behind NAT and no incoming ports can be opened to the outside world.

Solution approach

The solution was simple – set up Wireguard on a server elsewhere, make clients connect to that Wireguard server and tell it to route traffic through one of the clients inside the aforementioned LAN.

Intricate details

While it seems simple, I initially misconfigured a parameter which stopped the configuration from working as necessary. The misconfigured parameter was AllowedIPs parameter on the server.

After configuring the internal address of the peer in AllowedIPs line, you can append multiple subnets that can and will be routed through that peer. Adding 0.0.0.0/0 will allow routing any traffic through it. But it will also create a default route that might have to be removed.

Without adding these subnets to the config Wireguard won’t accept packets for those subnets even if routed manually.

Then I set up separate routing table and used it for routing the other peers. This simplifies things.

Here is the Server config:

[Interface]
Address = 192.168.90.1/32
SaveConfig = false
PostUp = iptables -A FORWARD -i %i -j ACCEPT; ip rule add from 192.168.90.3 lookup privatenet; ip route add default via 192.168.90.2 table privatenet; `ip route del default dev wg1 table 51820`
PostDown = iptables -D FORWARD -i %i -j ACCEPT; ip rule del from 192.168.90.3 lookup privatenet; ip route del default via 192.168.90.2 table privatenet
ListenPort = 41234
PrivateKey = ...

# Router behind NAT
[Peer]
PublicKey = ..
PresharedKey = ..
AllowedIPs = 192.168.90.2/32, 0.0.0.0/0
PersistentKeepalive = 25

# Client
[Peer]
PublicKey = ..
PresharedKey = ..
AllowedIPs = 192.168.90.3/32

And here is the config of peer inside the LAN:

[Interface]
PrivateKey = ..
SaveConfig = false
Address = 192.168.90.2/32

[Peer]
PublicKey = ..
PresharedKey = ..
AllowedIPs = 192.168.90.0/24
Endpoint = example.com:41234
PersistentKeepalive = 25

Note how I use PersistentKeepalive to make sure it stays up. Wireguard is a silent protocol and unless some traffic is being sent to the interface, it won’t do anything.

To keep the configuration cleaner, I keep PostUp and PostDown commands in separate shell scripts.

Of course it also needs packet forwarding enabled and some forward/NAT rules on the peer behind the firewall.

Dropping of the Wireguard default route and some other things could maybe be avoided by interfacing with Wireguard directly instead of using wg-quick and config files, but I really like having those config files.

Leave a comment

Your email address will not be published. Required fields are marked *