Implementing Policy-Based Routing for Tailscale and WireGuard on OpenWRT

Hello OpenWRT community,

I am currently trying to set up policy-based routing on my OpenWRT device to allow Tailscale and WireGuard to coexist. I've been following this guide which is quite helpful, but it's written for a Linux system and I'm having trouble translating the iptables commands to OpenWRT's firewall rules.

Here's a brief summary of what I'm trying to achieve:

  1. I have both Tailscale and WireGuard (proto, utils, etc) installed on my OpenWRT device. Both are up and running.
  2. I want to set up policy-based routing so that traffic from certain IP addresses or subnets goes through the Tailscale interface, while all other traffic goes through the WireGuard interface.
  3. The guide I'm following uses iptables to mark packets and set up routing rules based on these marks. I understand that OpenWRT uses a different system for managing firewall rules, and I'm not sure how to translate these iptables commands to OpenWRT.

I would appreciate any advice or guidance on how to achieve this. Specifically, I have a few questions:

  1. How can I translate the iptables commands used in the guide to OpenWRT's firewall rules? Are there any tools or scripts available that can help with this?
  2. Are there any specific considerations or potential issues I should be aware of when setting up policy-based routing on OpenWRT, especially with Tailscale and WireGuard?
  3. Is there a way to test or debug the routing rules once they're set up, to ensure that traffic is being routed correctly?

Thank you in advance for your help!

Instead of iptables you can use ip rule

Let's say you have made a table 11 using tailscale and you have a client which you want to use this table then:
ip rule add from table 11

You can use CIDR notation to group the clients.

This is simple and fast.

There is also an OpenWRT PBR package which you might have a look at:

Testing can be done wit ping and traceroute (tracert from Windows)

1 Like

The PBR package does not work for tailscale traffic, it only works for wireguard traffic

I was under impression that pbr works for tailscale just as well as wireguard.

1 Like

Well, the problem is tailscale table priority (5270) is always lower value than the PBR tables(30000-30001), so it always get prioritized before it even hit the PBR decision:

root@LAM_BUT:~# ip rule show
0:      from all lookup local
5210:   from all fwmark 0x80000/0xff0000 lookup main
5230:   from all fwmark 0x80000/0xff0000 lookup default
5250:   from all fwmark 0x80000/0xff0000 unreachable
5270:   from all lookup 52
30000:  from all fwmark 0x10000/0xff0000 lookup pbr_wanb
30001:  from all fwmark 0x20000/0xff0000 lookup pbr_tailscale
32766:  from all lookup main
32767:  from all lookup default

The only way to make it work is to change the priority to be higher value than the BPR tables, however this change is not persistent and you will have to do it everytime you reboot the OpenWRT router.

It is best for someone who actively uses Tailscale to report an issue against the respective package asking to add a UCI option for disabling its built-in PBR, meanwhile here's a workaround:

1 Like

I wanted to post about wan_ip_rules_priority setting for pbr, but @vgaetera beat me to it. :wink:

I've also realized the setting description was missing from the pbr README, so I've recently added it there.

1 Like

I'm guessing this will only work if --exit-node=<exit-node-ip> is active?