I have finally figured out how to add local routes to another VLAN subnet in Wireguard without leaking DNS, and figured that I would share. In this case, I am running an Unbound DNS server on the gateway.

In a Wireguard config file you can add “PreUp” and “PostDown” system commands to run stuff before and after the tunnel connects. Unfortunately with some Linux networking (NetworkManager in this case) it will keep using the DHCP assigned DNS server, and if a local route to the DNS server is available it will use it for some things and therefore leak.

To prevent this, you can use the Pre/Post commands to force the LAN DNS server to match the Wireguard tunnel’s DNS server, and simply return it to normal after the tunnel is closed.

This only works with wg-quick, not the NetworkManager Wireguard plugin since that does not overwrite the resolv.conf or run the PreUp/PostDown commands as far as I can tell.

Example:

PreUp = ip route add 192.168.3.0/24 via 192.168.1.1 dev enp4s0
PreUp = nmcli conn modify enp4s0 ipv4.ignore-auto-dns yes
PreUp = nmcli conn modify enp4s0 ipv4.dns "10.2.0.1"
PreUp = systemctl restart NetworkManager
PostDown = ip route del 192.168.3.0/24 via 192.168.1.1 dev enp4s0
PostDown = nmcli conn modify enp4s0 ipv4.ignore-auto-dns no
PostDown = nmcli conn modify enp4s0 ipv4.dns "192.168.1.1"
PostDown = systemctl restart NetworkManager