PBR WG bootup leak & bootup Killswitch Scripts

@stangri Thank you for PBR once again.

There's just a couple of things ive noticed.

Firstly, in the README, (unless i missed it) i dont see anywhere where you talk about a Killswitch in PBR in its default mode when a LAN device has a policy to WG, if "strictly enforce policies when their gateway is down" ACTUALLY means this is an actual Killswitch which really, does what it says and indeed there is no traffic unless WG is connected. Is there a reason you dont state this in the README? The only thing stated is that PBR doesnt support a Killswitch in router mode, and that footnote is a bit confusing when someone first reads it.

Secondly, i noticed an ISP IP leak to any device that has a policy to WG when the router boots up just before pbr starts up and just after the network is up, so for about 10 seconds the real IP is leaked to these devices.

I managed to fix this by adding 2 custom service scripts which start on bootup and basically blocks the WAN Output before pbr starts, for anyone who is interested here they are:

Stage 1: The early kill switch script (S20)
This script runs after the main firewall service has started but before the network interfaces are fully up, implementing a strict DROP policy.

vi /etc/init.d/S20-pbr-early-killswitch

S20-pbr-early-killswitch
#!/bin/sh /etc/rc.common

# This script creates an early kill switch that blocks all traffic
# until the PBR watchdog script removes it.

START=20
STOP=90

start() {
    logger -t pbr-early-killswitch "Applying PBR early kill switch..."

    uci set firewall.@zone[2].output='DROP'
    uci commit firewall
    /etc/init.d/firewall restart

    logger -t pbr-early-killswitch "PBR early kill switch active."
}

stop() {
    # The watchdog script will trigger a firewall reload,
    # which automatically removes the rules added here.
    logger -t pbr-early-killswitch "PBR early kill switch stop called. Firewall will be reloaded."
}

Prepare script:

chmod +x /etc/init.d/S20-pbr-early-killswitch
/etc/init.d/S20-pbr-early-killswitch enable

Stage 2: The PBR watchdog script (S99)
This script runs later in the boot process. It continuously checks for the PBR's VPN interface to be active. When it is, the script reloads the firewall, removing the kill switch and allowing normal PBR routing.

vi /etc/init.d/S99-pbr-watchdog

S99-pbr-watchdog
#!/bin/sh /etc/rc.common

# This script waits for the PBR VPN interface to come up,
# then reloads the firewall to disable the early kill switch.

START=99
STOP=10

INTERFACE="wg0" # <<< Set this to your PBR's VPN interface

start() {
    logger -t pbr-watchdog "Starting PBR watchdog. Waiting for interface $INTERFACE..."

    # Loop and wait for the VPN interface to be detected and up
    while true; do
    if ip link show "$INTERFACE" 2>/dev/null | grep -q ",UP,"; then
        break
    fi
    sleep 5
    done
    sleep 5
    logger -t pbr-watchdog "Interface $INTERFACE is up. Reloading firewall to remove early kill switch."

    # Reloading the firewall causes it to flush all existing rules
    # and re-apply the full configuration, including PBR rules.
    uci set firewall.@zone[2].output='ACCEPT'
    uci commit firewall
    /etc/init.d/firewall restart

    logger -t pbr-watchdog "PBR watchdog finished. Kill switch disengaged."
}

stop() {
    : # This script is a one-shot process and does not need a complex stop handler.
}

Prepare script:

chmod +x /etc/init.d/S99-pbr-watchdog
/etc/init.d/S99-pbr-watchdog enable
reboot

To test this working, on CLI from a LAN device thats on pbr, keep entering the following: curl wtfismyip.com/text few seconds after router bootup until your WG connects

If there is anyone that knows the equivalent firewall rule in nftables, that i think would be better and faster than using UCI.

If this issue can somehow be fixed on pbr to stop bootup IP leaks, before pbr starts, then it would be great to do without these scripts.

1 Like

Very valid point. It would be good to see the improvements applied upstream in the package.

Do you need to raise perhaps a PR request in Github so that your proposal gets reviewed?

The OUTPUT chain is used by the router itself the router needs that for DNS and time resolution.

A killswitch is usually done by removing lan > wan forward.

I do this on an other firmware by using for IPv4
sysctl -w net.ipv4.ip_forward=[0,1]
for Ipv6
sysctl -w net.ipv6.conf.all.forwarding=[0,1]

0=disabled, 1=enabled

2 Likes

Thanks for that, il try these instead. However just note that although the first script blocks the Output chain in WAN, it only does so for like 15secs, and then the second script re-enables it after pbr has started up, so DNS, NTP, etc should connect right after

Id like that but im unable to do so, id appreciate it if you/someone volunteered

Yes but if you have e.g. an URL as endpoint it does not work as WireGuard cannot connect.

It probably is not to difficult to stop forwarding in the begin of the PBR script and enable it in the end but you still have a gap between the start of the router and firewall setting up and the start of PBR.
You can counter that by doing what you do and add a script at the very early start of the router disabling forward but it is not a very elegant solution.

When I have more time i will have a look at the firewall script, but that can take some time lots of others things come first

On the other hand, my router is rebooted perhaps once in a couple of months when I upgrade so not sure how urgent this

2 Likes

Many thanks. Please keep it in your to-do list if possible.

I can confirm that I have observed the same behaviour with the ISP leak too, for 10-15 seconds between the router powers up and before the policy kicks in.

1 Like

First attempt not tested and no time to further do that.

See: https://github.com/egc112/OpenWRT-egc-add-on/tree/main/stop-wan-leak

Make a backup of your config before testing, not sure if this works it is triggered on ifup of WAN interface as that is what presumably starts the critical period.
It can therefore run multiple times if the wan interface is restarted multiple times

Let me know if it does any good

Have fun

2 Likes

Thanks. Just to confirm:

Is “wan” expected to be replaced by device “eth1” on a standard wan interface? ifconfig only shows devices such as eth0, eth1, …

No it should be the name of the logical wan interface so this is wan in your case, I can see this is somewhat confusing.

so just keep the default setting wan

1 Like

Worked fine! Many thanks.

1 Like

Great to hear the script is useful :slight_smile:

If the problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.
Thanks! :slight_smile:

1 Like

@egc thank you very much! i tested this and it works, but just to verify, i therefore no longer need 2 scripts as in OP, and this one is the only one?

Also another thing, as shown in the logs below (on router bootup), why are they echo'd multiple times? is the script being spawned multiple times in the background? because you can see different ID's but the timestamps are the same..

Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2714]: stop-wan-leak: forwarding disabled during 15 sec but is now enabled after PBR is running
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2670]: stop-wan-leak: forwarding disabled during 15 sec but is now enabled after PBR is running
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3438]: stop-wan-leak: forwarding disabled during 11 sec but is now enabled after PBR is running
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2615]: stop-wan-leak: forwarding disabled during 15 sec but is now enabled after PBR is running
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2714]: net.ipv4.ip_forward = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2670]: net.ipv4.ip_forward = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3438]: net.ipv4.ip_forward = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3351]: stop-wan-leak: forwarding disabled during 11 sec but is now enabled after PBR is running
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3351]: net.ipv4.ip_forward = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2615]: net.ipv4.ip_forward = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2615]: net.ipv6.conf.all.forwarding = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3351]: net.ipv6.conf.all.forwarding = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3351]: stop-wan-leak: forwarding is now enabled after 11 sec.
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2615]: stop-wan-leak: forwarding is now enabled after 15 sec.
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2714]: net.ipv6.conf.all.forwarding = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3438]: net.ipv6.conf.all.forwarding = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[3438]: stop-wan-leak: forwarding is now enabled after 11 sec.
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2670]: net.ipv6.conf.all.forwarding = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2670]: stop-wan-leak: forwarding is now enabled after 15 sec.
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2714]: stop-wan-leak: forwarding is now enabled after 15 sec.
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2443]: stop-wan-leak: forwarding disabled during 16 sec but is now enabled after PBR is running
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2443]: net.ipv4.ip_forward = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2443]: net.ipv6.conf.all.forwarding = 1
Sat Nov  8 11:16:02 2025 user.notice hotplug-call[2443]: stop-wan-leak: forwarding is now enabled after 16 sec.

You need only this script.

It is triggered by the wan interface going up.
Reason I chose this is when the wan goes up the risk of a leak via wan is possible..

The wan interface going up apparantly happens multiple times during e.g. bootup, therefore the script is triggered multiple times.
Maybe there is a smarter trigger possible but if it works it works :slight_smile:

1 Like