What's new
  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

IPv6 Routing Rules Not Working to Redirect Local Devices Via Wireguard VPN Clients

wildland_hondo

New Around Here
I have the following configuration / setup on my router:
  1. Setup 1x OpenVPN client via user Merlin user interface
  2. Setup 5x Wireguard VPN clients via the Merlin user interface
  3. Router setup as an exit node for Tailscale (via tailmon)
  4. Use VPN director to route Tailscale IPv4s into VPN tunnels with failover
  5. Manually add Tailscale IPv6 to ip -6 routing table to route IPv6 traffic over VPN (works for wg not for ovpn)
But when I try to do the same for local IP addresses, it works for IPv4 addresses but not for IPv6.

I have tried the following:
Serial​
Action​
IPv4 Result​
IPv6 Result​
1​
Manually add IPv4 and IPv6 (GUA) addresses to routing tables
Routed​
Failed​
2​
Add IPv4 via GUI and IPv6 (GUA) manually to routing tables
Routed​
Failed​
3​
Added IPv6 (LL) to routing tables
N/A
Failed​
4​
Created client MAC ipsets and marked traffic with fwmark 0x30/0xf0 and used this rule: ip(6)tables -t mangle -A PREROUTING -m set --match-set client_macs src -j MARK --set-mark 0x30/0xf0 along with ip rules to redirect marked traffic to VPN interfaces
Routed​
Failed​
5​
Tried to do the same as serial 4 but with two ipsets (one for ipv4 and one for ipv6) to route traffic to VPN interfaces
Routed​
Failed​

Could someone tell me what I am doing wrong and why tailscale IPv6 get routed but those of my local devices do not?

Please note that I am not proficient in Linux networking and used forums and AI help to do what I did.

Grateful for all your help. Thanks.



PS: Is there any plan to switch VPN director to use MAC addresses rather than IP addresses and for it to support dual stack VPNs?
 
Could someone tell me what I am doing wrong and why tailscale IPv6 get routed but those of my local devices do not?
How have you tried to add the routes, just in the main route table or even in the policy route table? Have you added ipv6 policy rules?
Ipv6 firewall is statefull and drops everything not explicitly allowed so have you added ipv6 firewall rules?
 
How have you tried to add the routes, just in the main route table or even in the policy route table? Have you added ipv6 policy rules?
Ipv6 firewall is statefull and drops everything not explicitly allowed so have you added ipv6 firewall rules?
To redirect Tailscale IPv6 traffic, I basically looked at the IPv4 routing table and changed the IPs and added using this rule:
ip -6 rule add from [aaaa:bbbb:cccc::dddd]/48 lookup wgc1 priority 11210
ip -6 rule add from [aaaa:bbbb:cccc::dddd]/48 prohibit pref 12219

This works perfectly fine for Tailscale traffic.

Inferring from this and some googlefu, I made an ipset using:
ipset create vpn_macs hash:mac hashsize 1024 maxelem 65536
and added the hash of the local client to this set.

Then marked for IPv4 using:
iptables -t mangle -A PREROUTING -m set --match-set client_macs src -j MARK --set-mark 0x30/0xf0

for IPv6:
ip6tables -t mangle -A PREROUTING -m set --match-set client_macs src -j MARK --set-mark 0x30/0xf0

Assumed routing tables made by VPN director would keep working fine, because they worked for Tailscale IPv6 routes.

Then added to rules in this format:
ip rule add from all fwmark 0x30/0xf0 lookup wgc1 pref 11211
ip -6 rule add from all fwmark 0x30/0xf0 lookup wgc1 pref 11211

This also led to IPv4 traffic being successfully routed but IPv6 traffic simply disappeared.

ip6tables -t mangle -L PREROUTING -vn did show packets being captured by this rule but it wasn't working how I wanted it to. Oh and all traffic simply died on the router after some time. I think it ran out of memory and swap is on a USB drive so probably became unresponsive and had to be restarted.
 
So, your issue is to use mac address based routing from lan to wgc1 only?
This works perfectly fine for Tailscale traffic.
Just for a quick test, if you would have added a rule for the lan client, i.e its global address, would it work then? I would assume it should but I have never tested it. It would prove that there are no other issues at play, like firewall stuff.

This also led to IPv4 traffic being successfully routed but IPv6 traffic simply disappeared.
If you only mean lan to wgc1 it should be possible to get it to work. There are some things to notice, for example, the policy route table (i.e table wgc1) is not as complete as the main route table and I don't know how ipv6 routing would work if all device communication is set to use a route table which only have routes to wgc1 and not even back to your own lan. Not sure if you would need to limit the adress scope to global addresses or something.
 
So, your issue is to use mac address based routing from lan to wgc1 only?
Basically that the traffic from one (or multiple) clients go through a VPN with multiple tunnels in failover ending in a killswitch. I want IPv6 because I want to avoid CG-NAT.

Just for a quick test, if you would have added a rule for the lan client, i.e its global address, would it work then? I would assume it should but I have never tested it. It would prove that there are no other issues at play, like firewall stuff.
IPv4 works fine. IPv6 becomes non-responsive.

If you only mean lan to wgc1 it should be possible to get it to work. There are some things to notice, for example, the policy route table (i.e table wgc1) is not as complete as the main route table and I don't know how ipv6 routing would work if all device communication is set to use a route table which only have routes to wgc1 and not even back to your own lan. Not sure if you would need to limit the adress scope to global addresses or something.
Yes I noticed that the IPv4 routing table (and firewall) is a lot more populated so its probably something which is missing from the IPv6 table which is causing the issues.

Not to mention seems very confusing too as it has some entries which seem redundant? For example:

Code:
Chain WGCF (1 references)
target     prot opt source               destination
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset1 src return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset1 dst return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset2 src return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset2 dst return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset3 src return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset3 dst return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset4 src return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset4 dst return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset5 src return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere             match-set vpnc_ipset5 dst return-nomatch ! update-counters ! update-subcounters
ACCEPT     all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere

The mentioned IPsets are all empty and it seems to have a lot of redundant entries. But I don't know enough about linux firewalls so maybe I am missing something.

No I do want traffic to go to my own LAN too. That is how it works with tailscale addresses currently. First LAN and what is not LAN to the VPN tunnel.
 
IPv4 works fine. IPv6 becomes non-responsive.
This used to work on 388 firmware so if you are on the newer 3006 fw then maybe something have changed.


Not to mention seems very confusing too as it has some entries which seem redundant? For example:
Did you add the ipsets here? This is how mine looks on 388 fw:
Code:
admin@RT-AX86U_Pro:/tmp/home/root# ip6tables -nvL WGCF
Chain WGCF (1 references)
 pkts bytes target     prot opt in     out     source        destination
    0     0 TCPMSS     tcp      *      wgc2    ::/0        ::/0                 tcpflags: 0x06/0x02 TCPMSS clamp to PMTU
    0     0 ACCEPT     all      *      wgc2    ::/0        ::/0
    0     0 DROP       all      wgc2   *       ::/0        ::/0
    0     0 TCPMSS     tcp      *      wgc1    ::/0.       ::/0                 tcpflags: 0x06/0x02 TCPMSS clamp to PMTU
    0     0 ACCEPT     all      *      wgc1    ::/0        ::/0
    0     0 DROP       all      wgc1   *       ::/0        ::/0
You should use the -nv to get the interface with the rules along with the packet count so you can trace hits through the firewall..

I understand it is convenient with the mac ipset but I think you need to get it to work when adding lan ipv6 gua rule. If thats not working the ipset will never work.
 
Last edited:
Did you add the ipsets here? This is how mine looks on 388 fw:

I didn't. It is possible some other module did. But I did not.

You should use the -nv to get the interface with the rules along with the packet count so you can trace hits through the firewall..

I understand it is convenient with the mac ipset but I think you need to get it to work when adding lan ipv6 gua rule. If thats not working the ipset will never work.
Hmm. I did not know that. My reason for using MAC addresses was not convenience but rather because IPv6 address can change and multiple temporary IPv6 addresses can end up being assigned to a particular device. So I felt MAC (along with a MAC filter) would be the most stable way of ensuring that all client traffic is redirected into the VPN tunnel.

However thank you for pointing me in the direction of -nv. I guess I'll have to look deeper into how networking works to achieve my goal.
 
However thank you for pointing me in the direction of -nv. I guess I'll have to look deeper into how networking works to achieve my goal.
Just go through the firewall and look at the packet counter to identify if your packet reaches this stage. Firewall goes from PREROUTING to FORWARD to POSTROUTING. Routing happens between prerouting and forward. You can make dummy rule in each chain to identify where the packets dissapears...

This is how the firewall is organized:
Untitled-Diagram.png
 
Just go through the firewall and look at the packet counter to identify if your packet reaches this stage. Firewall goes from PREROUTING to FORWARD to POSTROUTING. Routing happens between prerouting and forward. You can make dummy rule in each chain to identify where the packets dissapears...

This is how the firewall is organized:
View attachment 67269
Thank you for the helpful diagram and apologies for the late reply. I got caught up in work.

I have verified that the packet counter does increase for the IPv6 rule. What I do not know is where the traffic goes afterwards. I think it gets stuck somewhere inside the router because with the aforementioned config, eventually my router stops responding and no traffic goes through which I suspect is due to the RAM filling up.
 
I have verified that the packet counter does increase for the IPv6 rule. What I do not know is where the traffic goes afterwards.
If it makes it through routing and firewall forward chain (WGCF) it is usually off at the interface determined during routing. You should be able to see them under
Code:
ifconfig wgc1
but mixed with ipv4 data. There is some ipv6 packet counter by
Code:
cat /proc/self/net/dev_snmp6/wgc1
but I have never used it.
To actually sniff the interface for packets and see how they look you could install Entware and tcpdump.
 

Similar threads

Latest threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Back
Top