I have a wireguard VPN, setup and enabled through NetworkManager, called wg0
. I want to allow a program to access the internet directly without going through the tunnel. For this I’m trying to match by cgroupv2
Here’s what the routing looks like:
> ip -4 addr show dev wlan0
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
inet 10.126.232.253/16 brd 10.126.255.255 scope global dynamic noprefixroute wlan0
valid_lft 43135sec preferred_lft 43135sec
> ip -4 addr show dev wg0
6: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
inet 10.118.53.99/32 scope global noprefixroute wg0
valid_lft forever preferred_lft forever
> ip -4 rule
0: from all lookup local
31760: from all lookup main suppress_prefixlength 0
31761: not from all fwmark 0xcc4d lookup 52301
32766: from all lookup main
32767: from all lookup default
> ip -4 route list table local
local 10.118.53.99 dev wg0 proto kernel scope host src 10.118.53.99
local 10.126.232.253 dev wlan0 proto kernel scope host src 10.126.232.253
broadcast 10.126.255.255 dev wlan0 proto kernel scope link src 10.126.232.253
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
> ip -4 route list table main
default via 10.126.255.254 dev wlan0 proto dhcp src 10.126.232.253 metric 600
10.126.0.0/16 dev wlan0 proto kernel scope link src 10.126.232.253 metric 600
> ip -4 route list table 52301
default dev wg0 proto static scope link metric 20050
Now from reading up on wg-quick routing and trying to understand the Netfilter packet flow, I have created a table called "bypass" that matches my terminal’s cgroup and adds the fwmark 0xcc4d
:
> sudo nft list tables
table inet bypass
> sudo nft list table inet bypass
table inet bypass {
chain out {
type filter hook output priority mangle; policy accept;
socket cgroupv2 level 5 "user.slice/user-1000.slice/[email protected]/app.slice/app-org.kde.konsole-698af79930294eb09aa9231b0a8bd258.scope" log prefix "cgroup_matched out "
socket cgroupv2 level 5 "user.slice/user-1000.slice/[email protected]/app.slice/app-org.kde.konsole-698af79930294eb09aa9231b0a8bd258.scope" meta mark 0x00000000 meta oiftype != loopback meta mark set 0x0000cc4d
}
chain check {
type filter hook postrouting priority mangle; policy accept;
ip daddr 34.160.111.145 log prefix "postroute check "
}
}
> cat /proc/$$/cgroup
0::/user.slice/user-1000.slice/[email protected]/app.slice/app-org.kde.konsole-698af79930294eb09aa9231b0a8bd258.scope
Testing it out, it seems packets are matched correctly, but from the netfilter graph
> host ifconfig.me
34.160.111.145
> sudo conntrack -L -d 34.160.111.145
conntrack v1.4.7 (conntrack-tools): 0 flow entries have been shown.
> d=`date +'%Y-%m-%d %H:%M:%S'`
> curl https://ifconfig.me; echo
<tunnel public IP> # Expect to see my own public IP
> sudo journalctl --dmesg --since "$d" -n 2
Apr 14 12:40:56 <hostname> kernel: cgroup_matched out IN= OUT=wg0 SRC=10.118.53.99 DST=34.160.111.145 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=26291 DF PROTO=TCP SPT=48504 DPT=443 WINDOW=64860 RES=0x00 SYN URGP=0
Apr 14 12:40:56 <hostname> kernel: postroute check IN= OUT=wg0 SRC=10.118.53.99 DST=34.160.111.145 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=26291 DF PROTO=TCP SPT=48504 DPT=443 WINDOW=64860 RES=0x00 SYN URGP=0 MARK=0xcc4d
As I understand this, the fwmark 0xcc4d
is correctly to outgoing packets at mangle, which we see at postroute.
However at postroute, i.e. after the reroute check on the netfilter flow diagram, we still have OUT=wg0 SRC=10.118.53.99
, though as I understand it:
- changing
fwmark
should in mangle should trigger the reroute, see this thread, linux ipt mangle source code
- Anything marked
fwmark 0xcc4d
should not lookup table 52301
and therefore use the route default via 10.126.255.254 dev wlan0 proto dhcp src 10.126.232.253
So what am I missing, and how can I fix this?
I’m running OpenSUSE Tumbleweed (20230411) with:
- Linux kernel 6.2.9
- libnftables1 1.0.7
- iproute2 6.2
- wireguard-tools 1.0.20210914
- conntrack-tools 1.4.7
- NetworkManager 1.42.4