Force Router's Own Traffic Through VPN on MT6000 (Firmware 4.8.x) with Multi-VPN Policies

Hello,

I have a GL-MT6000 router running the latest 4.8.1 firmware. I have multiple WireGuard VPN clients configured, and I am using the VPN Policy section to route specific client devices through specific VPN tunnels. This works perfectly for my LAN clients.

However, I cannot get the router's own traffic to go through a VPN tunnel. When I SSH into the router and run a command like ⁠traceroute 8.8.8.8, it always goes out the default WAN (ISP) connection, bypassing all VPNs.

I need to force the router's local traffic (e.g., from ping, traceroute, wget, etc., run from the router's command line) to use one of my VPN tunnels.

Here is what I have tried so far without success:

  1. LuCI Traffic Rule: Created a traffic rule for ⁠Source zone: Device (output) to ⁠Destination zone: gl_vpn_X. This had no effect.
  2. Custom ⁠iptables **MARK rule in ⁠firewall.user: Added ⁠iptables -t mangle -I OUTPUT 1 -j MARK --set-xmark 0x2000 (and tried other marks). This did not work.
  3. Custom ⁠iptables rule targetingLOCAL_POLICY: Based on my ⁠iptables-save file, I saw that ⁠OUTPUT jumps to a ⁠LOCAL_POLICY chain. I tried adding ⁠iptables -t mangle -I LOCAL_POLICY 1 -m mark --mark 0x0 -j MARK --set-xmark 0x2000. This also had no effect.
  4. ip rule command: I tried to bypass ⁠iptables entirely by adding a direct routing policy: ⁠ip rule add from 192.168.1.1/32 lookup 1002 priority 5000. This also failed and the router's traffic still used the default WAN.

It seems the policy routing scripts are aggressively managing the firewall and routing rules, preventing or overriding any manual changes.

Could you please provide the correct, supported method for forcing the router's own processes to use a specific VPN tunnel in a multi-VPN policy setup?

Here are my routing rules for reference:

# ip rule show
0: from all lookup local
1: from all iif lo lookup 16800
800: from all lookup 9910 suppress_prefixlength 0
6000: from all fwmark 0x8000/0xf000 lookup main
6000: from all fwmark 0x1000/0xf000 lookup 1001
6000: from all fwmark 0x2000/0xf000 lookup 1002
6000: from all fwmark 0x3000/0xf000 lookup 1003
9910: not from all fwmark 0/0xf000 blackhole
9920: from all iif br-lan blackhole
9920: from all iif br-guest blackhole
10000: from 10.2.0.2 lookup 1002
10000: from 10.2.0.2 lookup 1003
10000: from 10.2.0.2 lookup 1001
20000: from all to 10.2.0.2 lookup 1002
20000: from all to 10.2.0.2 lookup 1003
20000: from all to 10.2.0.2 lookup 1001
32766: from all lookup main
32767: from all lookup default
90013: from all iif lo lookup 1002
90066: from all iif lo lookup 1003
90067: from all iif lo lookup 1001

Thank you for your help.

Correct. You're going to want pure/vanilla OWRT + Stangri's luci-app-pbr for finely tuned PBR.

Add ip.me & ifconfig.me to a respective black/white policy. That's a quick & easy way to validate:

printf "%s\n" \
  "tunnel one's ip is $(curl -s ip.me)" \
  "tunnel two's ip is $(curl -s ifconfig.me/ip)" \
  "$(env TZ='UTC' date +'%Y%m%dT%H%M%S%Z')"

There was no PBR in the Slate AX's v4.6.11 but with Kill Switch, Block Non-VPN Traffic toggled on curl from the device was tunneling. I have yet to test the Slate AX/v4.8.0-beta 9 (versioning isn't sync'd across devices).

There is a user group "explicat_vpn", and the policy always goes to VPN, you can use this user group to execute the service process:

sudo -g explict_vpn curl ip.sb

Update:
Firmware v4.8.1 or above is required

1 Like

Huh; I don't have that group on Slate AX/v4.8.0-beta9:

root@slate-ax:~# grep 'vpn' /etc/group 
dnsmasq:x:453:dnsmasq,dnsmasq_vpn
nonevpn:x:65533:root
usevpn:x:10000:root

Firmware v4.8.1 or above is required

1 Like

Hi @Bruce & @9b9e69c2-4b75-4420,

Thanks for the information about the "explict_vpn" user group. Excellent solution for running the service process.

Regards,

I'm confused as to what you're trying to do and your goal is. Interesting stuff to read though!

Hi, When I log into the router using SSH, I am giving direct commands to the router's own operating system. By default, the router does its own tasks—like running a diagnostic test or downloading an update—using the direct, main internet connection, ignoring the VPN.

My goal is to force the router to use the secure VPN tunnel for its own job. I need to make sure that the router itself is hidden behind the VPN when it performs any task I command it to do from the inside.

For thoroughness I think you should drop another device upstream to your Flint v2 to capture the flow including during boot/reboot. tcpdump should be in the default GL repos if you have another OWRT-based device if not a multi-homed Linux box. There's lots of tutorials for WireShark around for to get you started in analyzing the resulting pcap.

It doesn't do this within the VPN? Is this a privacy and security concern?

He's 'leak hunting.' There are times it's acceptable to have a daemon hit the WAN before the VPN is up to then shunt everything thru a tunnel. For example NTP to set the device time from a network server in order to properly negotiate TLS certificates, WG handshakes. If you use DOH via dnscrypt-proxy2 it needs to reach out & grab some resolvers to bootstrap itself. Then it can start using TLS to look up the DNS for the VPN endpoints.

... but cases like that should be the exception, not the rule, when privacy is the priority, IMO/YMMV.

1 Like