Policy-Based-Routing (pbr) package discussion

Hello,

I'm trying to set up policy-based routing (PBR) on my router running OpenWrt version 23.05.3, using PBR version 1.1.1-7 with nft support.

My goal is to route traffic to specific websites through the Tailscale interface, which I've configured on my router. I have a VDS in the cloud with Tailscale configured as an exit node.

Specifically, I want to route traffic to certain websites through the Tailscale exit node on my VDS, while directing all other traffic through the regular ISP channel.

I've followed the documentation and guides, but haven't been able to achieve the desired result. Is it possible to implement such a configuration using PBR on my OpenWrt router in conjunction with Tailscale? If so, could you please share configuration examples or provide advice on how to set it up?

Thank you in advance for your assistance!

README --> Getting Help and also post the list of certain web-sites you want routed thru tailscale. The local gurus would be equipped with the information to help you.

2 Likes

Hi!

Network: WAN<--->Router(192.168.0.1)<--->OpenWRT router(192.168.1.1)<-->User (192.168.1.219)
Goal: redirect all traffic from user 192.168.1.219 through Openconnect VPN

I've successfully setup openconnect vpn and followed instructions on page https://openwrt.org/docs/guide-user/network/routing/pbr_app

Routing traffic through VPN seems to work fine for all ping commands from user host. Some websites open fast (google.com), but a lot of websites open super slow or don't open at all. Some fail to load in Chrome, but load in Firefox after some delay.
Curl command return content of the page which failed to load in chrome. It seems like something is blocking some part of the traffic (maybe https) or making it very slow.
When I connect to the same VPN using iPhone with AnyConnect client over wifi distributed by 192.168.0.1, then all websites open fast with no problem, so it's definitely some mis-configuration in my OpenWRT router.

Any ideas how to troubleshoot and fix this issue ?

Thanks!

I would first check if the OpenConnect setup is the problem, so disable PBR and use OpenConnect only to test

I turned off PBR. OpenConnect interface works fine when used from within OpenWRT router e.g.

root@OpenWrt:~# ping -I vpn-oc0 google.com
PING google.com (142.250.179.142): 56 data bytes
64 bytes from 142.250.179.142: seq=0 ttl=55 time=207.012 ms
64 bytes from 142.250.179.142: seq=1 ttl=55 time=206.295 ms 

Use default gateway is unchecked for OpenConnect interface.
Routing table:

root@OpenWrt:~# ip route
default via 192.168.0.1 dev eth0.2 proto static src 192.168.0.115 
10.10.10.0/24 dev vpn-oc0 proto static scope link 
192.168.0.0/24 dev eth0.2 proto kernel scope link src 192.168.0.115 
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.1 

If I enable default routing for OpenConnect, then OC interface connects to remote VPN and establishes connection, however RX counter is not increasing, only TX increases. Also I can't ping from the router using command

root@OpenWrt:~# ping -I vpn-oc0 google.com
PING google.com (173.194.221.100): 56 data bytes 

So it looks like the problem is with the OpenVPN Connect setup.

I couldn't get OpenConnect default routing to work correctly. Despite all my attempts traffic from the client was passing directly through WAN interface completely ignoring OC VPN interface. That's when I started to look into PBR and with PBR I managed to get traffic from the client to flow through VPN interface, but with some side effects which I described in my original post

Maybe before PBR can work correctly you probably have first to solve that problem.
I do not use OpenConnect so cannot help you with that besides that is outside the scope of this thread

Hello, I want to route traffic via a pbr custom file on specific source ips (for example, 192.168.30.15 and 192.168.30.16). What , I have to do? At this time, I am using this file that routes all traffic on a specific interface.

#!/bin/sh

TARGET_SET='pbr_UAEAWZT_4_dst_ip_user'
TARGET_IPSET='pbr_UAEAWZT_4_dst_net_user'
TARGET_TABLE='inet fw4'
TARGET_URL="/usr/share/pbr/pbr_default_range"
TARGET_DL_FILE="/usr/share/pbr/pbr_default_range"
TARGET_NFT_FILE="/var/pbr_tmp_def_ip_ranges.nft"
[ -z "$nft" ] && nft="$(command -v nft)"
_ret=1

if [ ! -s "$TARGET_DL_FILE" ]; then
	uclient-fetch --no-check-certificate -qO- "$TARGET_URL" 2>/dev/null > "$TARGET_DL_FILE"
fi

if [ -s "$TARGET_DL_FILE" ]; then
	if ipset -q list "$TARGET_IPSET" >/dev/null 2>&1; then
		if awk -v ipset="$TARGET_IPSET" '{print "add " ipset " " $1}' "$TARGET_DL_FILE" | ipset restore -!; then
			_ret=0
		fi
	elif [ -n "$nft" ] && [ -x "$nft" ] && "$nft" list set "$TARGET_TABLE" "$TARGET_SET" >/dev/null 2>&1; then
		printf "add element %s %s { " "$TARGET_TABLE" "$TARGET_SET" > "$TARGET_NFT_FILE"
		awk '{printf $1 ", "}' "$TARGET_DL_FILE" >> "$TARGET_NFT_FILE"
		printf " } " >> "$TARGET_NFT_FILE"
		if "$nft" -f "$TARGET_NFT_FILE"; then
			rm -f "$TARGET_NFT_FILE"
			_ret=0
		fi
	fi
fi

return $_ret

Create your own custom user file which creates and loads entries into new sets (one to match source, one to match destinations) and creates nft rules for matching/routing matched traffic.

1 Like