I have been pondering on the interface setup part lately and @egc has previously looked into using the netifd support that OpenWrt provides, so if you have any ideas on how to implement the failover/balancing aspect, please lmk.
I’m not sure I can be of any help with under-the-hood details. But, on the UI/UX side, I’d start with separating the concepts of a policy and a rule (like in mwan3). This would allow for bulk management of a large set of rules and provide a framework for policies more flexible than just setting the destination interface (e.g., tun0 → wan → blackhole in order of priority), which could later be expanded to balancing and route health-based failover.
first_domain="$(awk -F'/' 'NF>=2 && $2 != "" {print $2; exit}' "$nftset")"
if [ -n "$first_domain" ]; then
logger -t pbr-dns-prefetch "Waiting for dnsmasq to resolve $first_domain..."
for i in $(seq 1 20); do
if nslookup "$first_domain" 127.0.0.1 >/dev/null 2>&1; then
logger -t pbr-dns-prefetch "dnsmasq resolved $first_domain after $i s"
break
fi
sleep 1
done
else
logger -t pbr-dns-prefetch "No domain found in $nftset, skipping wait"
fi
Actually, I’m not sure waiting after dnsmasq restart was even necessary in the first place. When the dnsmasq.dns object has been added to ubus, it stands to reason that dnsmasq is ready to serve DNS queries too. With or without sleep 3, the prefetching begins after the following line has appeared in syslog:
Sat Sep 6 22:03:35 2025 daemon.info dnsmasq[1]: using nameserver 127.0.0.1#5054
So, I dropped the sleep 3. + Some cleanup in gist.
Ah, but for cases like that there is the boot_timeout option in the pbr config. And when restarting pbr manually, interfaces don’t reset. BTW, good idea to check nslookup’s exit code, I borrowed it.
I have switched to SNAPSHOT today and I’m having two dumb questions.
First of all, this is because on the SNAPHOT, I am stuck on Version 1.1.8-r36.
And there is nothing about the tunnel details below the service status.
`echo '``https://apk.openwrt.melmac.ca/packages.adb``' > /etc/apk/repositories.d/apk.openwrt.melmac.ca.list wget ``https://apk.openwrt.melmac.ca/apk.openwrt.melmac.ca.pem`` -O /etc/apk/keys/apk.openwrt.melmac.ca.pem
``
cd /tmp
wget https://dev.melmac.ca/apk/pbr-1.1.9-r23.apk
wget https://dev.melmac.ca/apk/luci-app-pbr-1.1.9-r23.apk
service pbr stop
apk del luci-app-pbr pbrapk add --allow-untrusted ./*.apk
service pbr start
Put it in any persistent directory (like /opt or /etc), then add the path to the script to the list at the bottom of the luci-app-pbr page and enable it. It should run automatically whenever pbr is restarted.
P.S. Take the updated revision from gist. I had to bring back the wait period before nslookup until a better solution is found to make sure the nft sets are ready.
Hi all, I was wondering if someone could help me out with something. I want to be able to have a sort of “kill switch” when either PBR isn’t up or when my Wireguard client has failed. I’ve had an information leak recently and I realized that I want to make sure I can stop gap it. The first thing I tried was setting Wireguard to be the default route, however this had unexpected consequences as it broke my Homelab being able to recieve WAN communication, and broke the ability for external IPs to ping my OpenWrt router. Is some sort of VPN killswitch dependant on if PBR isn’t running and/or if Wireguard is down? It feels like it may not be currently but I may be overcomplicating the solution.
You can set default route via WireGuard and have access to your homelab if you use PBR to route the correct port out of the WAN.
For WireGuard the PBR app will do this automatically it takes the listen port of the WG interface and routes this via the WAN.
For a simple killswitch with default route via the WAN you just remove the firewall forwarding from lan firewall zone to wan zone and only have forwarding between lan and VPN zone.
For connection from outside you have to make traffic rules to allow that specific traffic to go out via the wan
How would I go about routing ports out of WAN in PBR? Would I use something like CIDR to set every “local” IP except the ones that are routing to the VPN? I apologize in advance if that’s a dumb question, I’m just not sure how to go about it.
Also, for the firewall zones, just so I’m understanding you mean a layout that would be like this:
Zones → Forwards
LAN → VPN
VPN → WAN
and then PBR would route the domains I want bypassed to WAN? (For example, let’s say I want to visit openwrt.org from my home IP address instead of the VPN due to a block, this zone configuration would work?)
And the last one, I’ve currently got my homelab set up in dual-stack (IPv4/IPv6) mode. Instead of port forwarding for IPv4 and traffic rules for IPv6, would I set up traffic rules for both IPv4 and IPv6?
I want to make sure I have everything correct before I start changing my config around. Thank you so much!
But you better start a separate thread in the Installing and using section , describe your problem and what you want to achieve and post your current config e.g.:
Please connect to your OpenWRT device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button
Remember to redact keys, passwords, MAC addresses and any public IP addresses you may have but do not redact private RFC 1918 IP addresses as that is not needed:
ubus call system board
cat /etc/config/network
cat /etc/config/firewall
ip route show
ip -6 route show
ip route show table all
ip rule show
#if you already use the PBR app then :
cat /etc/config/pbr
service pbr status
I think since the firewall trigger was fully removed this issue became more prominent. I’ll try to update the 1.1.9 tree to fully restart at on_interface_reload instead.
I’ve just updated to 1.1.9-r27 and now am in a sort of a bricked state. Pbr is infinitely creating files in my /tmp/ directory named something like pbr_tmp.XX. Due to this the whole system thinks that there is no space left and I can’t even reinstall new image on the router.
I’ve disabled pbr in /etc/config/pbr and rebooted. LuCI shows that the service is disabled, but it’s still running and creating all these files. Need help to get me out of this state.
Using any service pbr anything does not help as the command just hangs indefinitely.
I have updated to the same version and see no issues:
root@DL-WRX36:~# service pbr restart
Resetting chains and sets [✓]
Removing routing for 'wan/192.168.1.1' [✓]
Removing routing for 'wg0/10.5.0.2' [✓]
Removing routing for 'nordvpntun0/tun0/0.0.0.0' [✓]
pbr 1.1.9-r27 (fw4 nft file mode) stopped [✓]
Using uplink interface (on_start): wan [✓]
Found uplink gateway (on_start): 192.168.1.1 [✓]
Processing environment (on_start) [✓]
Setting up routing for 'wan/192.168.1.1' [✓]
Setting up routing for 'wg0/10.5.0.2' [✓]
Setting up routing for 'nordvpntun0/tun0/0.0.0.0' [✓]
Routing 'Via WAN' via wan [✓]
Routing 'Paypal' via wan [✓]
Routing 'chatgpt_via_wan' via wan [✓]
Routing 'stanbic_internet_banking' via wan [✓]
Routing 'aliexpress.com' via wan [✓]
Routing 'odoo.com' via wan [✓]
Routing 'noip.com' via wan [✓]
Routing 'Wyze' via wan [✓]
Routing 'VanessaFireTV' via wan [✓]
Routing 'Panafcon' via wan [✓]
Routing 'eCitizen' via wan [✓]
Routing 'Oraimo' via wan [✓]
Routing 'eBay' via wan [✓]
Routing 'ZA' via wan [✓]
Routing 'Mara.Cloud' via wan [✓]
Routing 'Microsoft Live' via wan [✓]
Routing 'DDNS' via wan [✓]
Routing 'CSL Sophos' via wan [✓]
Routing 'Telenet Solutions' via wan [✓]
Routing 'Sophos' via wan [✓]
Routing 'joinhoney' via wan [✓]
Routing 'Starlink' via wan [✓]
Routing 'RC.ORG' via wan [✓]
Routing 'techpowerup.com' via wan [✓]
Routing 'IAWRT' via wan [✓]
Running /usr/share/pbr/pbr.user.ke.lst [✓]
Running /usr/share/pbr/pbr.dns.prefetch [✓]
Installing fw4 nft file [✓]
Restarting dnsmasq [✓]
Setting interface trigger for wan [✓]
Setting interface trigger for wan6 [✓]
Setting interface trigger for wg0 [✓]
Setting interface trigger for nordvpntun0 [✓]
pbr 1.1.9-r27 monitoring interfaces: wan wan6 wg0 nordvpntun0
pbr 1.1.9-r27 (fw4 nft file mode) started with gateways:
wan/192.168.1.1
wg0/10.5.0.2 [✓]
nordvpntun0/tun0/0.0.0.0
tor/53->9053/80,443->9040
root@DL-WRX36:~#