After experimenting with different options, I decided to stop using NetworkManager and instead use wg-quick directly. On Fedora Server, this was pretty easy and I only had to remove the NetworkManager connection using nmcli con del wg0
and enable the wg-quick service using systemctl enable --now wg-quick@wg0
(which reads the config from /etc/wireguard/wg0.conf
). Switching to wg-quick has the following advantages:
- I can specify custom
PostUp
commands to configure a more complex routing setup
- The number of the Wireguard routing table seems to be constant at
51820
, even though I could not find any documentation about this. This makes it easier to set up custom ip rules.
I then used the PostUp
command in wg0.conf
to set up additional ip rules that would make sure that any Wireguard traffic would also respond through Wireguard. There are two options to achieve this:
Option 1: source IP matching
The ip rules match the Wireguard packages based on their source IP addresses (which is automatically set to the IP address on which the request originally came in):
[Interface]
Address = 10.139.192.4/24
Address = fd52:30a4:f9e7:647a::4/64
PostUp = ip -4 rule add from 10.139.192.4 lookup 51820
PreDown = ip -4 rule del from 10.139.192.4 lookup 51820
PostUp = ip -6 rule add from fd52:30a4:f9e7:647a::4 lookup 51820
PreDown = ip -6 rule del from fd52:30a4:f9e7:647a::4 lookup 51820
Option 2: fwmark
Some iptables rules are configured to set a mark
on packages coming in through wg0
:
iptables -t mangle -A INPUT -j CONNMARK -i wg0 --set-mark 1
ip6tables -t mangle -A INPUT -j CONNMARK -i wg0 --set-mark 1
iptables -t mangle -A OUTPUT -j CONNMARK -m connmark --mark 1 --restore-mark
ip6tables -t mangle -A OUTPUT -j CONNMARK -m connmark --mark 1 --restore-mark
Then this mark
is matched by the IP rule:
PostUp = ip -4 rule add fwmark 1 lookup 51820
PreDown = ip -4 rule del fwmark 1 lookup 51820
PostUp = ip -6 rule add fwmark 1 lookup 51820
PreDown = ip -6 rule del fwmark 1 lookup 51820
More details about this solution can be found here.