All we need is an easy explanation of the problem, so here it is.
I want to set up Wireguard in a way where I only route specific processes (like qBittorrent) through the tunnel, while other processes default to the physical interface. Since my VPN provider only seems to work when
allowed-ips is set to
0.0.0.0/0, I decided to set up the Wireguard interface inside a namespace using this example.
My initial setup script looks like this:
ip netns add tunnel0 ip link add wg0 type wireguard ip link set wg0 netns tunnel0 ip netns exec tunnel0 wg set wg0 \ private-key /etc/wireguard/wg0_privkey \ peer <public_key> \ endpoint x.x.x.x:51820 \ allowed-ips 10.64.0.0/16,0.0.0.0/0 ip netns exec tunnel0 ip addr add 10.64.189.228/32 dev wg0 ip netns exec tunnel0 ip link set mtu 1420 up dev wg0 ip netns exec tunnel0 ip route add default dev wg0
This results in my setup looking something like this.
As the title suggests, I want to create an interface (
vpn0) on my host that is bridged from the Wireguard interface (
wg0) inside the
tunnel0 namespace, which would let me choose that interface in an application like qBittorrent, without any other processes being routed through the tunnel. My setup would then look something like this.
I have read somewhere that I would need to use something like VXLAN, however, since I am not very experienced in Linux networking, I have not managed to find any examples of what I am trying to specifically achieve.
Am I doing this right, or is there a much simpler solution?
How to solve :
I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.
Since my VPN provider only seems to work when allowed-ips is set to 0.0.0.0/0,
Yes, that’s normal for VPNs, because you’re using the tunnel to access the entire Internet, and you’re expecting to receive reply packets from the entire Internet as well. Therefore, the tunnel needs to allow the peer to represent the entire Internet.
This doesn’t make it necessary to use namespaces. The AllowedIPs setting on the
wg0 interface works as a filter, but does not actually grab and route all your IP traffic through that interface. It’s more like a firewall rule.¹
In short, you can just do literally the same
wg0 configuration without namespaces, and then you wouldn’t need to bridge anything because you already have the interface right here.
But instead of creating a global default route through wg0, put it in a different routing table using
ip -4 route add default dev wg0 table 3, and use "policy routing" rules via
ip -4 rule add to select that table only if a program tries to bind to the VPN address as the "source" address.
¹ (It’s only the identically named wg-quick setting that also creates IP routes for all allowed prefixes, giving you a default route through the VPN which you don’t want. But as you’re not using wg-quick to create the tunnel, this shouldn’t affect you – and even if you were using it, wg-quick also has an option to put the routes in a different routing table, or to not create them at all.)
Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂