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" :)