Policy-Based-Routing (pbr) package discussion

Hi!
What is the easiest way to include this in a custom build?
Thanks.

Generally speaking: https://docs.openwrt.melmac.net/#how-to-use

If you have any specific questions about either of those 3 options, let us know the details.

Hi @stangri,
Firstly, thank you for creating pbr.

I have a few questions as i am just starting out experimenting with this and testing on VM.
I have followed your instructions, i installed your repo on Openwrt 22.03.2.
As i am using Wireguard Client to connect to a VPN Provider. (not using Wireguard Server)
My intention is to give specific devices or IP's or IP ranges access to use WG Client VPN.

As we all know, by default, when setting WG Client the whole router connects all devices to the VPN.
According to your FAQ section https://docs.openwrt.melmac.net/pbr/#wireguard-tunnel, after setting option route_allowed_ips '0' in /etc/config/network, I am now getting the inverse. So all devices are connecting direct to the WAN (ISP).

Then after i installed pbr, and only set the last 2 Policies to test as below screenshot:

I could see after setting these policies, that on TunnelVM1 i was getting the WAN IP from ISP, and on TunnelVM2 i was getting the VPN IP.
Thats all i did, and it seems to have worked so i can see the difference from the two VM's, according to my intention.
Is this simple setup that i did correct? Are the policies correctly configured? Is this all that needs to be configured for setting up specific network IP's on the network to use the VPN ?

I got a bit confused regarding the documentation. The only thing that made sense to me was setting option route_allowed_ips '0' in /etc/config/network, after which i just played around and guessed how to do the policies. Maybe option route_allowed_ips '0' should be mentioned first in the documentation, and then following the rest of your guide about the WG Scenarios 1 & 2.

Under here: https://docs.openwrt.melmac.net/pbr/#local-wireguard-server--wireguard-client-scenario-1
I dont understand why you put option interface 'ignore' ? and the only way to set up a random word such as ignore, was to do it via UCI.

I never set up any additional firewall settings. Basically these are my settings for my WG Client:

/etc/config/network

config interface 'wg0'
	option proto 'wireguard'
	list addresses 'X.X.X.X/32'
	option peerdns '0'
	list dns '1.1.1.1'
	list dns '1.0.0.1'
	option private_key 'XXXXXXXX='

config wireguard_wg0
	option public_key 'XXXXXXXX='
	list allowed_ips '0.0.0.0/5 8.0.0.0/7 11.0.0.0/8 12.0.0.0/6 16.0.0.0/4 32.0.0.0/3 64.0.0.0/2 128.0.0.0/3 160.0.0.0/5 168.0.0.0/6 172.0.0.0/12 172.32.0.0/11 172.64.0.0/10 172.128.0.0/9 173.0.0.0/8 174.0.0.0/7 176.0.0.0/4 192.0.0.0/9 192.128.0.0/11 192.160.0.0/13 192.169.0.0/16 192.170.0.0/15 192.172.0.0/14 192.176.0.0/12 192.192.0.0/10 193.0.0.0/8 194.0.0.0/7 196.0.0.0/6 200.0.0.0/5 208.0.0.0/4 1.0.0.1/32 77.88.8.1/32'
	option persistent_keepalive '25'
	option description 'WG'
	option endpoint_host 'XX.XX.XX.XX'
	option route_allowed_ips '0'

/etc/config/firewall

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wan'
	list network 'wan6'
	list network 'wg0'

/etc/config/pbr

config policy
	option name 'IgnoreVM1'
	option dest_addr '192.168.2.101'
	option interface 'ignored'
	option enabled '0'

config policy
	option name 'TunnelVM1'
	option src_addr '192.168.2.101'
	option interface 'wg0'
	option enabled '0'

config policy
	option name 'TunnelVM2'
	option src_addr '192.168.2.102'
	option interface 'wg0'

PS: Please ignore 'IgnoreVM1' - that Policy didnt seem to have worked when i disabled option route_allowed_ips '0' - and i also dont know why.

Yes.

It is needed to not route local wg server traffic outside. It is only needed when you have wg server and wg client on your router. As far as I understood your setup it's not applicable to you.

Will be fixed in the next update. I've cleaned up most of the WebUI-specific settings when I transitioned to javascript from Lua, because in the javascript framework all the elements fit, whereas in the Lua version I've had to allow hiding certain WebUI elements to make the policy table fit the screen, and sadly webui_show_ignore_target which used to be configurable from WebUI fell victim.

1 Like

Thanks.
How to add git as source in feeds.conf?

I tried git sparse checkout to only checkout the pbr and luci-app-pbr folder from https://github.com/stangri/source.openwrt.melmac.net/
But then the feeds scripts throws the following error:

ERROR: please fix feeds/pbr/luci-app-pbr/Makefile - see logs/feeds/pbr/luci-app-pbr/dump.txt for details

Makefile:17: ../../luci.mk: No such file or directory
gmake[1]: *** No rule to make target '../../luci.mk'.  Stop.

It's literally at the link I posted: https://docs.openwrt.melmac.net/#sdk.

If you wait a week or so, both packages should be merged by then.

1 Like

So there is no way to make this work with feeds.conf?
That's a bit inconvenient to have to check out each time on the package folder and the luci folder.

I'd imagine that if you're building OpenWrt from source you are well equipped to automate sparse checkouts. You can also set up your own feeds and do sparse checkout into them once.

It's way more inconvenient for me to maintain my code in two separate feeds when most of the code is merged into OpenWrt repo anyways and have to traverse the feeds folder structure every time I need to actually develop/update packages.

1 Like

This works for me:

1- opkg update
2- put stangri.sh on /tmp and permission 755
2- run /tmp/stangri.sh
3- opkg update

stangri.sh:

if ubus -S call system board | grep -q '15.05'; then
  opkg install ca-certificates wget libopenssl
elif ubus -S call system board | grep -q '19.07'; then
  opkg install uclient-fetch libustream-mbedtls ca-bundle ca-certificates
else
  opkg install wget-ssl
fi
echo -e -n 'untrusted comment: OpenWrt usign key of Stan Grishin\nRWR//HUXxMwMVnx7fESOKO7x8XoW4/dRidJPjt91hAAU2L59mYvHy0Fa\n' > /etc/opkg/keys/7ffc7517c4cc0c56
sed -i '/stangri_repo/d' /etc/opkg/customfeeds.conf
echo 'src/gz stangri_repo https://repo.openwrt.melmac.net' >> /etc/opkg/customfeeds.conf

I am using vpn-policy-routing since my router uses its manufacturer repo, and the new package is not available yet.

I have WAN as default gateway.
I want everything to be routed through VPN, except something like Youtube and Netflix video.

With the configuration below, I have noticed Youtube video traffic goes through VPN.
Is it for remote destination, IP address has higher piority than domain name?

config policy
        option interface 'wan'
        option name 'Youtube'
        option dest_addr 'googlevideo.com'

config policy
        option name 'Default'
        option dest_addr '0.0.0.0/0'
        option interface 'VPN'

And also, Youtube data URL is something like:

https://rr5---sn-oguesn6k.googlevideo.com/videoplayback?

Is setting "googlevideo.com" enough?

Thanks.

yeah true.
I have one problem though.
The luci-app-pbr folder is present in package/luci/applications but it wont show up in menuconfig.
The pbr package works fine.

Hi, no matter what i do, i can't get pbr to work. It starts up fine then a few seconds later i get

Failed to setup all_my_interfaces

  • content of /etc/config/dhcp

config dnsmasq
option domainneeded '1'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option ednspacket_max '1232'
option localservice '0'
option confdir '/tmp/dnsmasq.d'
list rebind_domain 'plex.direct'
list server '8.8.8.8'
list server '8.8.4.4'
list address '/local.home/private_ip'
list address '/local.yg/private_ip'

config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
list ra_flags 'none'

config dhcp 'wan'
option interface 'wan'
option ignore '1'
list ra_flags 'none'

config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'
option loglevel '4'
.
....

  • content of /etc/config/firewall

config defaults
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'
option synflood_protect '1'

config zone
option name 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
option masq '1'
list network 'APACCESS'
list network 'lan'

config zone
option name 'guest'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'GUEST'

config zone
option name 'wan'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
list network 'wan'

config zone
option name 'world'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'WORLD'

config forwarding
option src 'lan'
option dest 'wan'

config include
option path '/etc/firewall.user'

config include 'pbr'
option fw4_compatible '1'
option type 'script'
option path '/usr/share/pbr/pbr.firewall.include'
.
....

  • content of /etc/config/network

config interface 'loopback'
option device 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'

config globals 'globals'
option ula_prefix 'fd42:2523:ac4f::/48'

config device
option name 'br-lan'
option type 'bridge'
list ports 'lan2'
list ports 'lan3'
list ports 'lan4'

config interface 'lan'
option proto 'static'
option ipaddr '192.168.1.1'
option netmask '255.255.255.0'
option device 'lan1'
option type 'bridge'

config device
option name 'wan'
option macaddr 'mac_address'

config interface 'wan'
option device 'wan'
option proto 'dhcp'
option peerdns '0'

config bridge-vlan
option device 'br-lan'
option vlan '1'
list ports 'lan2:t'
list ports 'lan3:t'
list ports 'lan4:t'

config bridge-vlan
option device 'br-lan'
option vlan '20'
list ports 'lan2:t'
list ports 'lan3:t'
list ports 'lan4:t'

config bridge-vlan
option device 'br-lan'
option vlan '30'
list ports 'lan2:t'
list ports 'lan3:t'
list ports 'lan4:t'

config bridge-vlan
option device 'br-lan'
option vlan '100'
list ports 'lan2:t'
list ports 'lan3:t'
list ports 'lan4:t'

config interface 'APACCESS'
option proto 'static'
option device 'br-lan.1'
option ipaddr '192.168.0.1'
option netmask '255.255.255.0'

config interface 'GUEST'
option proto 'static'
option device 'br-lan.20'
option ipaddr '192.168.20.1'
option netmask '255.255.255.0'
.
....

  • content of /etc/config/pbr

config pbr 'config'
option verbosity '2'
option strict_enforcement '1'
option ipv6_enabled '0'
list ignored_interface 'vpnserver'
list ignored_interface 'wgserver'
option boot_timeout '30'
option rule_create_option 'add'
option procd_reload_delay '1'
option webui_show_ignore_target '0'
list webui_supported_protocol 'all'
list webui_supported_protocol 'tcp'
list webui_supported_protocol 'udp'
list webui_supported_protocol 'tcp udp'
list webui_supported_protocol 'icmp'
option enabled '1'
option resolver_set 'dnsmasq.ipset'

config include
option path '/usr/share/pbr/pbr.user.aws'

config include
option path '/usr/share/pbr/pbr.user.netflix'

config policy
option name 'Plex/Emby Local Server'
option interface 'wan'
option src_port '8096 8920 32400'
option enabled '0'

config policy
option name 'Plex/Emby Remote Servers'
option interface 'wan'
option dest_addr 'plex.tv my.plexapp.com emby.media app.emby.media tv.emby.media'
option enabled '0'

config policy
option name 'WireGuard Server'
option interface 'wan'
option src_port '51820'
option chain 'output'
option proto 'udp'
option enabled '0'

the output of /etc/init.d/pbr status

the output of /etc/init.d/pbr reload with verbosity setting set to 2

I'm using dnsmasq.ipset and have installed all the dependencies listed in the README.

Most streaming services are a PITA to create policies for based on domains, if you have a dedicated streaming device, it's better to use its IP/MAC address in the policy.

For everything to be router through VPN you'd be better off using VPN as a default gateway. README has more information on this.

Uhm, yeah, I don't have a solution for that. If it's any consolation I'm planning on merging new packages into main OpenWrt tree soon.

Where are all these interfaces from the reload log are defined:

ERROR: Failed to set up 'PECOS/10.0.10.4'
ERROR: Failed to set up 'OC_PECOS/0.0.0.0'
ERROR: Failed to set up 'OC_HOMEVPN/0.0.0.0'
ERROR: Failed to set up 'DIGO/10.90.0.2'
ERROR: Failed to set up 'HOMEVPN/10.6.0.2'
ERROR: Failed to set up 'XFINITY/10.70.0.2'
ERROR: Failed to set up 'ANOTHER/10.7.0.4'

?

So if you reboot, the first pbr start is successful?

It appears to be successful, but after i refresh luci page it shows the couldn't set up error.

The listed interfaces are just my wireguard interfaces defined in/etc/config/network.

I have just enabled "Route allowed IPs" "0.0.0.0/0" on the VPN interface.

With these policies set:

config policy
        option interface 'wan'
        option name 'Youtube'
        option dest_addr 'googlevideo.com'

config vpn-policy-routing 'config'
        option verbosity '2'
        option strict_enforcement '1'
        option src_ipset '0'
        option dest_ipset '0'
        option resolver_ipset 'dnsmasq.ipset'
        list ignored_interface 'vpnserver wgserver'
        option boot_timeout '30'
        option iptables_rule_option 'append'
        option procd_reload_delay '1'
        option webui_enable_column '0'
        option webui_protocol_column '0'
        option webui_chain_column '0'
        option webui_show_ignore_target '0'
        option webui_sorting '1'
        list webui_supported_protocol 'tcp'
        list webui_supported_protocol 'udp'
        list webui_supported_protocol 'tcp udp'
        list webui_supported_protocol 'icmp'
        list webui_supported_protocol 'all'
        option enabled '1'
        option ipv6_enabled '1'
        option wan_dscp '1'

/etc/sysctl.conf

net.ipv4.conf.VPN.rp_filter = 2

And router rebooted.

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         0.0.0.0         0.0.0.0         U     0      0        0 VPN
xx.xx.xx.xx     xxx.xxx.xxx.1    255.255.255.255 UGH   0      0        0 eth0
192.168.9.0     0.0.0.0         255.255.255.0   U     0      0        0 br-guest
192.168.50.0    0.0.0.0         255.255.255.0   U     0      0        0 br-lan
xxx.xxx.xxx.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0

I see handshake was done on remote VPN server.
However, traffic went through WAN.

/etc/init.d/vpn-policy-routing support
https :// paste.ee/p/imdEI

(Sorry I have VPN interface name, VPN server, WAN IP masked in this forum reply.)

Thanks a lot.

I have made Google Chrome running in Docker container, and giving the container a separated IP, so watching Youtube in that Chrome could be routed throigh WAN. Thanks.

They were not part of the network file you posted.

https://pastebin.com/DqeHDDi5

dnsmasq 2.87 with dnsmasq.nftset.
One of my rules:

config policy
	option name 'Antizapret'
	option src_addr '!192.168.4.0/24'
	option dest_addr 'redacted.com'
	option interface 'tgvpnwg'

As you can see, !192.168.4.0/24 is used as the source address. Because of this, an error occurs when creating a rule:

# nft 'add rule inet fw4 pbr_prerouting ip != saddr @pbr_tgvpnwg_4_src_ip_cfg0c6ff5 ip daddr @pbr_tgvpnwg_4_dst_ip_cfg0c6ff5 goto pbr_mark_0x030000 comment "Antizapret"'
Error: syntax error, unexpected !=
add rule inet fw4 pbr_prerouting ip != saddr @pbr_tgvpnwg_4_src_ip_cfg0c6ff5 ip daddr @pbr_tgvpnwg_4_dst_ip_cfg0c6ff5 goto pbr_mark_0x030000 comment "Antizapret"
                                    ^^

Apparently, we need to correct the rule when negating, instead of
ip != saddr @pbr_tgvpnwg_4_src_ip_cfg0c6ff5
use
ip saddr != @pbr_tgvpnwg_4_src_ip_cfg0c6ff5

@stangri
Now with version: 0.9.9-25 no more

 * pkg_hash_check_unresolved: cannot find dependency ipset for pbr-iptables

So, everything works!