iptables, wireguard: 2-way routing between VPN and LAN

i am setting-up a VPN using WireGuard and are stuck configuring my firewall on the respective VPN server. I want the following features available:

  • VPN devices (10.6.0.0/24) available from LAN (10.20.0.0/24) (problem!)
  • LAN devices (10.20.0.0/24) available from VPN (10.6.0.0/24) (works!)

Current iptables configuration:

Forward all traffic from existing (already open) connections in any direction

iptables -t filter -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

This enables LAN devicesto be available from VPN (works fine)

# Direction: VPN -> LAN -------------------------------------------------------------
iptables -t nat -A PREROUTING -d 10.20.0.0/24 -j DNAT --to-destination 10.6.0.1     # Act as destination NAT from VPN to LAN (be the LAN-gateway for the VPN)
iptables -t filter -A FORWARD -s 10.6.0.0/24 -d 10.20.0.0/24 -j ACCEPT              # Accept traffic from VPN to LAN
iptables -t nat -A POSTROUTING -s 10.6.0.0/24 -d 10.20.0.0/24 -j MASQUERADE         # Mask traffic from VPN to LAN for responses

This shall enable VPN devices to be available from LAN (need help!)

# Direction: LAN -> VPN -------------------------------------------------------------
iptables -t filter -A FORWARD -s 10.20.0.0/24 -d 10.6.0.0/24 -j ACCEPT              # Accept traffic from LAN to VPN
iptables -t nat -A POSTROUTING -s 10.20.0.0/24 -d 10.6.0.0/24 -j MASQUERADE         # Mask traffic from LAN to VPN for responses

Current findings:

From looking at these rules, I am probably mising another DNAT/SNAT in the lower section, but I still can't figure it out...

The interface counters on the VPN interface show, that pings are sent out to the VPN client and do return! So the problem seems to be the arriving VPN packet to be translated and forwarded to the LAN.

If further information is required, please ask :) Thanks for your time!


Solution 1:

Probmel Resolved

As @MichaelHampton correctly commented above, a NAT is unnecessary in this scenario. The whole task is solely a matter of correct routing, not NAT-ing.

Origin of the problem

In order for clients to be able to connect to the LAN (10.20.0.0/24), you must add this subnet to the AllowedIPs directive inside your server config to be allowed.

This however automatically sets-up a new route for the respective subnet, overriding the original route. The result: Your server can no longer reach hosts in your LAN subnet, which leaves all connection attempts failing:

      Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
-ok-> 10.6.0.0        0.0.0.0         255.255.255.0   U     0      0        0 wg0
-!!-> 10.20.0.0       0.0.0.0         255.255.255.0   U     0      0        0 wg0
-ok-> 10.20.0.0       0.0.0.0         255.255.255.0   U     303    0        0 wlan0

Since the metric for this rotue is 0 (lower than the metric of the default route below) the route will always be preferred and makes connection attempts to the LAN impossible.

Permanent resolution

In my case, I just added the following line to my /etc/wireguard/wg0.conf:

PostUp = route del -net 10.20.0.0/24 dev wg0

This deleted the route which will be created everytime wireguard restarts. This needs to be done for all subnets that ARE NOT VPN subnets and shall not be overridden.

EDIT: You can just add Table=off to your /etc/wireguard/wg0.conf and WireGuard will stop messing up your routing table :)


All in all a quite nerve-wracking experience. I'm pretty sure to write a script which takes care of those things, making WireGuard a bit more "plug-and-play" :)