OpenWrt Policy-Based Routing: Per-Device VPN Checks

OpenWrt Policy-Based Routing: Per-Device VPN Checks

Ryan Foster
October 11, 2026· 10 min read

OpenWrt policy-based routing can send one LAN device through an authorized tunnel while another continues through WAN. Keep the ordinary default route on WAN, identify both devices consistently, and verify DNS, IPv6 and tunnel failure separately from a successful IPv4 browser request.

Key Takeaways

  • Device identity and policy order determine which requests match.
  • A router's own request does not represent a LAN client's request.
  • Strict enforcement covers matching policies; it is not proof of universal leak protection.
  • DNS forwarded by the router becomes a separate locally originated flow.
  • Preserve management exceptions and remove only this exercise's changes.

When is OpenWrt policy-based routing appropriate?

This procedure covers OpenWrt 25.12 stable, fw4/nftables and pbr 1.2.2, using the normal dynamic routing-table mode. The official release feed carries 1.2.2; confirm the package offered for your own architecture and firmware before installation. The maintainer documents preliminary netifd integration separately; this procedure does not enable it or multi-WAN integration.[1][2]

The instructions follow official documents and package configuration; no complete end-to-end device test was performed. They define reader acceptance checks, not observed test results. Use the self-hosting ownership checklist to assign recovery and maintenance responsibility.

If only a single application needs a different path, first compare application proxying and whole-device routing. Device policies introduce another configuration owner and failure mode. They do not create a tunnel or change what a commercial application's settings support.

Step 1: Freeze two device identities and keep management outside the test

Choose device A for the tunnel and device B for WAN. Reserve their existing IPv4 identities in DHCP, for example 192.168.8.10 and 192.168.8.20, and confirm the active leases. Record private-address randomization or multiple adapters that could change the identity. Keep a third, wired management computer outside both policies.

Save /etc/config/pbr, /etc/config/network, /etc/config/dhcp and /etc/config/firewall privately off the router. If pbr was not previously installed, record that instead of inventing an original configuration. Record the previous service-enabled state and any existing policies so rollback does not disable someone else's routing.

Verify the WireGuard client interface and return path first. Name the working interface wg_test in this example. Ensure the test LAN is allowed toward it and the server permits the forwarded traffic, with a deliberate IPv4 translation or return route.

For internet routing, the peer may need 0.0.0.0/0 in AllowedIPs, but keep Route Allowed IPs disabled so it does not install a competing global default route. Replace or remove only earlier test routes you own. Read the peer address and route relationship if these settings seem contradictory. Retain the WAN path to the endpoint and the existing connected LAN route.[3]

Step 2: Check the release packages and select a supported backend

Run installation only on the authorized router, from its configured trusted 25.12 feeds. Confirm that the offered pbr version is 1.2.2 and dependencies resolve for this firmware; stop on mismatches rather than forcing an old package or replacing the firmware in this exercise.[1][2]

apk update
apk list pbr
apk add pbr luci-app-pbr
apk list --installed pbr

Review Services → PBR and its status before enabling it. Confirm fw4/nftables operation, the detected WAN interface and wg_test. If this router already uses netifd extensions, mwan4 or another routing manager, stop: migrating that arrangement is outside this two-device example.

For source-address policies without domains, select resolver_set: none; there is no need to replace dnsmasq merely to match source IPs. Explicitly keep strict_enforcement: 1, and enable nft_rule_counter: 1 if you will use rule counters for observation. Record prior values; counters are not enabled by default in the release configuration. IPv6 support is also disabled there until deliberately configured.[2][4]

Step 3: Build OpenWrt per device VPN policies in order

Add the following policy fragments through LuCI or to the existing pbr configuration. They are not a replacement for the whole file. Use unused section names and your actual logical interface names. Preserve earlier authorized policies and review whether they overlap this test.[2]

config policy 'sh26_local'
        option name 'SH26 local management destinations'
        option src_addr '192.168.8.10 192.168.8.20'
        option dest_addr '192.168.8.0/24'
        option interface 'ignore'

config policy 'sh26_tunnel'
        option name 'SH26 device A'
        option src_addr '192.168.8.10'
        option interface 'wg_test'

config policy 'sh26_wan'
        option name 'SH26 device B'
        option src_addr '192.168.8.20'
        option interface 'wan'

Place the local exception above the device-wide policies. Policies higher in the configuration have higher priority; ignore leaves matching requests to ordinary routing rather than authorizing firewall access. Add other management networks only when they actually exist and are approved. An overly broad private-network exception could send intended remote private traffic outside the tunnel.[2]

Enable the pbr configuration and start or restart the service through LuCI. Inspect its status and errors immediately. If an interface or gateway is missing, do not accept the configuration as successful merely because it saved. A source policy cannot route a device whose packets never pass through this router.

How can you separate pbr DNS routing from browser traffic?

Begin with an explicit choice: either the client sends DNS directly to an approved resolver whose packets follow the device policy, or the client asks the router and the router performs upstream DNS separately. The second design does not automatically inherit device A's tunnel policy. Record both the resolver address and the route of its outgoing requests.

Optional pbr DNS policies use name, src_addr and dest_dns; the destination can identify a resolver or an interface with a configured resolver. Do not add a made-up resolver address. Such interception concerns matching DNS requests, not every encrypted DNS application, and may bypass dnsmasq's domain-set processing. Our initial source-IP exercise uses no domain policies.[2]

Test a fresh name under your control from A and B, then inspect the router's own resolver behavior separately. Record browser DoH, operating-system private DNS and any terminal VPN already present. Do not turn off unrelated software to produce a clean-looking result. If settings revert after renewal or reboot, follow the persistent router DNS checks before adding more policies.

What happens to IPv6 and a failed tunnel?

IPv4 source policies do not prove IPv6 coverage. An IPv6 privacy address can change independently of the DHCPv4 reservation. For dual-stack acceptance, enable pbr IPv6 support, establish a supported IPv6 tunnel and return route, and define matching IPv6 identities or an appropriate supported device selector. Check all current addresses used by A and B; do not assume one fixed address covers them all.[2][4]

If that branch is unavailable, restrict the exercise to an already IPv4-only test segment, or stop before describing it as a whole-device VPN. Do not disable IPv6 across a shared network. WAN-bound IPv6 is a failure if the agreed policy requires all device traffic through the tunnel; it can be intentional only if that exception was explicitly chosen.

Strict enforcement should make matching traffic unreachable when its target interface goes down. It does not establish that an interface which remains up but has a dead remote peer is correctly detected, nor does it cover unmatched IPv6, router DNS or periods when the service is stopped. Test interface down and remote nonresponse while the interface remains up as separate failures.[2]

Check methodExpected observationFailure response
Create new public requests from A and BA uses the authorized tunnel exit; B uses WANCheck identities, order, marks and routing tables
Inspect pbr status and enabled nft countersMatching policy counters change for the relevant deviceConfirm packets reach this router; avoid inferring success from status alone
Compare direct client DNS and router-originated DNSEach follows its documented designRestore resolver changes and isolate the separate flow
Repeat using IPv6 from both devicesResults match the explicit IPv6 decisionStop acceptance on unplanned WAN bypass
Bring down only wg_testMatching A requests fail with strict enforcement; B and management workCheck unmatched traffic and conflicting policies
Restore tunnel, then perform an authorized restartPolicies and identities persist; fresh requests match againRestore the baseline and examine saved settings

From each device, compare the visible exit address. Pair that with policy and resolver evidence. A public IP can be shared by both paths, so identical addresses alone do not prove that the rule failed or succeeded. Existing connections, hardware/software flow offloading and caches may complicate observation; examine fresh flows before changing additional settings.

Step 4: Restore the original policy and verify management

Undo optional DNS policies and only the three sh26_ policies added here, restore the saved pbr options and previous service state, and reload through the service owner. If pbr was newly installed solely for this exercise, stop and disable it before removing it; if it served existing rules, keep it and reload the preserved configuration.

Restore any WireGuard route options, reservations, resolver settings or test firewall permissions changed specifically for this exercise. Do not flush nftables, delete all policy tables, or restore a whole old file over later changes. Check fresh WAN requests from A and B, normal DNS and a new wired management session.

The maintainer notes that a disruption during service processing can leave LAN-to-WAN forwarding disabled. service pbr enable_forward is a documented recovery action, not a universal repair: first verify that this is the failure, restore the intended safe firewall/policy baseline and decide whether WAN fallback is authorized. Otherwise stop and recover locally rather than silently opening the path.[2]

Summary

  • Match stable device identities and retain a narrow management exception.
  • Let pbr own its dynamic tables while WAN remains the ordinary default.
  • Test DNS, IPv6 and two different tunnel failures independently.
  • Roll back only the policies and options changed for this exercise.

FAQ

Can I verify a device policy by running a request on the router?

No. A locally originated request has a different source and processing path. Generate fresh traffic on the actual LAN device and correlate it with policy evidence.

Does the first or last policy take priority?

Higher policies have higher priority in the documented pbr configuration. Put the narrowly scoped management exception above broad device policies and check for earlier overlapping rules.

Do source-IP policies require dnsmasq-full?

This exercise does not require domain-set resolution and uses resolver_set: none. Domain policies have separate resolver requirements; do not replace a working DNS service just to match a device address.

Is strict enforcement a complete kill switch?

It applies to matching policies and target-interface state. Unmatched address families, router DNS, a stopped service and an apparently up but unresponsive peer need separate acceptance checks.

Why does device A change path after reconnecting to Wi-Fi?

Its active IP, randomized MAC or adapter may have changed. Compare the current lease and IPv6 addresses with the policy's selectors before modifying routing tables.

Can I deliberately allow WAN fallback?

Yes, if the owner explicitly accepts that failure behavior and tests it. Record which devices, address families and DNS requests may fall back; do not describe that arrangement as strict blocking.

Should I clear every nftables rule to recover?

No. That can remove other services' protections and does not restore configuration ownership. Remove the exercise's sections, restore saved options and inspect a fresh management connection instead.

Sources:

  1. OpenWrt 25.12 — pbr release package definition — https://raw.githubusercontent.com/openwrt/packages/openwrt-25.12/net/pbr/Makefile
  2. MOSSDeF — pbr 1.2.2 documentation — https://docs.mossdef.org/pbr/1.2.2/
  3. OpenWrt — Policy-based routing — https://openwrt.org/docs/guide-user/network/routing/pbr
  4. OpenWrt 25.12 — pbr default configuration — https://raw.githubusercontent.com/openwrt/packages/openwrt-25.12/net/pbr/files/etc/config/pbr

Sources checked 11 October 2026.


Related Articles:

Start your 3-day free trial

Sign up to experience all premium features at no cost.

*Available only to new users. Each user is limited to one trial.

OpenWrt Policy-Based Routing: Per-Device VPN Checks | AethoVPN