Blog

OpenWrt: VPN for chosen devices only

Send only some devices through a VPN on OpenWrt: pbr by address, or the ForestVPN client's device modes. Lab results for address changes and tunnel loss.

Published October 16, 2026 · 12 minutes read

Key takeaways

  • 2 ways compared here to send only some devices through a VPN on OpenWrt: pbr, which chooses by source, destination, port or domain, and the ForestVPN client's three device modes, which choose by device only.
  • pbr by hardware address kept a client in the tunnel when only its lease changed, and lost it when the hardware address changed: 5 of 5 lookups went direct in our run.
  • strict_enforcement is the pbr setting that decided a tunnel drop: set to 1, 0 of the chosen client's probes answered direct; set to 0, 115 did.
  • Every device except is the one of the two modes we re-addressed that kept a re-addressed client in the tunnel, and it also pulled a re-addressed Direct client into it.
On this page (8)

You can send one phone through a VPN on OpenWrt and leave the rest of the house alone. Two ways are compared here: pbr, OpenWrt's policy-based routing package, which chooses by where traffic comes from or goes to, and the ForestVPN client's device modes, which choose by device only.

A third way, a separate guest network or VLAN whose whole subnet is routed into the tunnel, is not covered. The two we compared fail in different places, so we ran both on the same two clients to see where.

One router, two clients, two roads. The rule that picks the road is what each tool builds differently.

How do I send only some devices through a VPN on OpenWrt?

Pick the devices by source address and send that address into a routing table whose way out is the tunnel. Strict enforcement or the kill switch is what keeps it there when the tunnel stops. That is the whole mechanism, and both tools build it.

pbr is third-party software in the OpenWrt package feeds. Its documentation says it routes by IP, MAC address, port, protocol or domain, and supports WireGuard and OpenVPN interfaces.

The ForestVPN client does the same job with a smaller menu, the ForestVPN device modes:

  • all devices
  • only the ones you tick
  • all except the ones you list

If you came for a route by website, jump to the last table.

You will need:

  • an OpenWrt router with a tunnel interface already up
  • SSH or LuCI (OpenWrt's web interface) with uci, OpenWrt's command-line configuration tool
  • the hardware addresses of the devices you want, which look like aa:bb:cc:dd:ee:ff

On OpenWrt 22.03 and later the firewall is fw4, and pbr builds nftables rules in it. Netifd, OpenWrt's network daemon, owns the tunnel interface it routes into.

How can you check which devices use the VPN on OpenWrt?

An echo server returns the address a request came from, so an answer with the tunnel's address means the tunnel and an answer with the router's address means direct. We ran two LAN clients behind an OpenWrt router container and asked such a server from each. Read the box first, because the limits matter more than the results.

How this was tested

Product
pbr 1.2.2-r20 and the ForestVPN OpenWrt adapter (device modes, Direct switch, kill switch), unreleased adapter files from the main branch on 2026-10-16
Version
adapter files only, not a built package, the fv daemon did not run
System
OpenWrt 25.12.5 r33051 rootfs container (armsr-armv8-25.12.5), fw4, dnsmasq (not dnsmasq-full), in a virtual machine on a Mac
Checked
Runs
1
Not tested

One run, 2026-10-16, 10:15 to 10:35 UTC, on private lab networks, with no real ForestVPN account, no real exit and no third-party server. The router is a container, not a router: no Wi-Fi, no flash, no LuCI session driven. The clients are containers with fixed hardware addresses. The tunnel is a stand-in, an IPIP tunnel on device fvpn0 to a second container that masquerades; it is not the Noise_IKpsk2 tunnel and not the fv program, and the harness played the daemon's part by sending the router the signal the client sends on a state change. Lookups went to a small echo server that returns the address a request came from: an answer of "stand-in exit" means through the tunnel, "router" means out of the router directly. The pbr tunnel-loss run with strict_enforcement 1 still held the MAC policy from the earlier step; that does not change the result path. Not tested: pbr domain policies (they need dnsmasq-full), pbr on a real WireGuard or OpenVPN interface, IPv6, a DHCP server in the loop, overlapping devices, passwall2 or podkop, and any speed. OpenWrt 21.02.7 and 24.10.8 are the releases ForestVPN's help page names for its lab leak suite; we do not transfer those results to 25.12.5 or back. In this run, under this configuration, on this date.

Tip for your own test: a destination on the router's own connected network is routed by the main table before pbr's rules apply, so test against an address outside the LAN and WAN subnets. Every result below used such an address.

How does pbr pick a device: by IP or by MAC address?

pbr takes either one in the same field, so a policy can name an IP address or a colon-separated MAC address. The pbr documentation lists IP addresses, CIDRs, host names and MAC addresses as valid entries for the source field, and in our run each form became a different packet-matching rule.

Steps for the pbr arm, in the order we did them:

  1. Install pbr from the OpenWrt feed. We used apk, which OpenWrt 25.12 ships in place of opkg.
  2. Enable pbr: it ships disabled.
  3. Add the tunnel interface to pbr's supported interfaces and put the tunnel device in a firewall zone. Only a hand-made tunnel needs a zone: the ForestVPN client already puts its forestvpn interface in its own forestvpn zone (see the coexistence page).
  4. Add one policy per device.
  5. Look up an address from the chosen client and from a client you left alone, and compare.

Here is the policy we ran, first keyed on the client's IP address. The network name forestvpn is the ForestVPN client's own interface; if you built the tunnel by hand, use your own interface name (for example wg0) in both blocks.

Adds a pbr policy that sends one LAN address into the tunnel interface

uci set pbr.config.enabled='1'
uci set pbr.config.supported_interface='forestvpn'
uci add pbr policy
uci set pbr.@policy[-1].name='tv_by_ip'
uci set pbr.@policy[-1].src_addr='192.168.1.101'
uci set pbr.@policy[-1].interface='forestvpn'
uci commit pbr
/etc/init.d/pbr restart

Our first attempt failed quietly. The policy and the routing rule were in place, and the packet mark pointed at a table whose default route was fvpn0. Yet all 5 of 5 lookups from the chosen client failed, because the tunnel device was in no firewall zone and the forward chain dropped it.

For a hand-made tunnel the zone is one more block of uci, shown below. The run itself put the device in the wan zone with masquerading, and this separate-zone block was not run. With the ForestVPN client installed, skip it, because the client already has its zone. Keep each network in one zone only.

After the zone was in place and pbr restarted, the chosen client answered "stand-in exit" and the other client "router", in 3 rounds of 5 lookups each, with no exception.

Adds a firewall zone for a hand-made tunnel device

uci add firewall zone
uci set firewall.@zone[-1].name='vpn'
uci set firewall.@zone[-1].network='forestvpn'
uci set firewall.@zone[-1].masq='1'
uci set firewall.@zone[-1].input='REJECT'
uci set firewall.@zone[-1].forward='REJECT'
uci set firewall.@zone[-1].output='ACCEPT'
uci add firewall forwarding
uci set firewall.@forwarding[-1].src='lan'
uci set firewall.@forwarding[-1].dest='vpn'
uci commit firewall
/etc/init.d/firewall restart

Swapping src_addr for aa:bb:cc:00:00:01 gave the same split. pbr rendered that policy as an nftables rule on the source hardware address, so the lease no longer mattered.

What happens when a phone changes its Wi-Fi address?

A policy keyed on a hardware address stops matching the moment the device presents a new one. The device modes page says a phone that uses a changing private Wi-Fi address looks like a new device each time, and the router then sees a device the policy never named.

We changed the chosen client's hardware address and lease together, as a rotation would, then each field alone. The first table covers pbr, the second the ForestVPN modes.

Policy keyWhat changedChosen client answered with
IP addresshardware address and lease both changedthe router, 5 of 5
IP addressboth set backthe stand-in exit, 5 of 5
Hardware addresslease onlythe stand-in exit, 5 of 5
Hardware addresshardware address onlythe router, 5 of 5
Hardware addressboth set backthe stand-in exit, 5 of 5

The failure is silent. Nothing on the phone changes; its traffic just takes the other road. The fix is the one the ForestVPN device modes page gives: turn the private address off for your home network on the phone, or choose by exclusion. Choose by exclusion is a ForestVPN mode, not a pbr option.

How do the ForestVPN device modes pick devices?

They pick by hardware address, in one of three modes, and the router turns the choice into routing rules for the chosen devices. The device modes page carries the steps.

It opens with a status line we quote as written: "Not yet verified on hardware as a whole. The three modes and the Direct switch passed the lab leak suite on OpenWrt 21.02.7 and 24.10.8. They have not yet been followed on a household router with a mix of real devices."

  1. Open Services > ForestVPN > Devices and pick a mode: Every device, Only the devices I choose, or Every device except the ones I choose.
  2. Tick the devices for the second mode, or list the exceptions for the third. Set a device that should stay direct to Direct.
  3. Press Save. The change applies within a few seconds, with no reboot.
  4. Read the mode back with uci -q get forestvpn.main.mode, which prints all, chosen or except.

In the run, the chosen mode behaved like the pbr policy: the ticked client answered "stand-in exit" and the other "router", 3 rounds of 5. Every device put both clients in the tunnel.

ModeWhat changedChosen or unlisted clientClient set to Direct
Only the devices I chooseticked client got a new hardware address and leasethe router, 5 of 5unchanged, router
Every device exceptunlisted client re-addressedstill the stand-in exitunchanged, router
Every device exceptDirect client re-addressedunchangedthe stand-in exit, 5 of 5

Of the two modes we re-addressed, except is the one that did not drop a device, and it cuts both ways. A re-addressed Direct client went into the tunnel, which is the safe failure and still a surprise if that client is a server you reach from outside.

One lab condition matters here. The run had no DHCP server, so the adapter fell back to the router's neighbour table. After repeated address changes it held two addresses for one hardware address and wrote a rule for each.

Shipped code takes a leased device's address from its lease only and uses the neighbour table only for devices without a lease. A device with a lease is therefore matched by its current lease. We did not test that path.

Every device behind the router shares one plan and one location. On the Free plan that is one allowance for the whole home, so tick a few devices rather than all of them.

Prices in USD
PlanPriceBilled
Free–2 GB per connection, 5 connections a day
Monthly$7.99per month
Yearly$49.99per year

What happens to VPN-routed devices on OpenWrt when the tunnel goes down?

With pbr's strict_enforcement at 1, or with ForestVPN's kill switch, none of the chosen client's probes went direct; with strict_enforcement at 0, 115 did. That one pbr setting is the difference between a block and a leak. We removed the tunnel for 12 seconds and probed both clients every 100 ms over 30 seconds, a variant of the stop-and-test idea on the kill switch page, which stops the ForestVPN program instead.

pbr's documentation describes strict_enforcement as: "Drops traffic matching a policy if the target interface is down, functioning as a kill switch to prevent data leaks via the default gateway." The default is 1. We ran it both ways.

SetupChosen client probesDirect client
pbr, strict_enforcement 1169 through the tunnel, 32 failed, 0 answered directunaffected (1 of 285 probes failed)
pbr, strict_enforcement 0171 through the tunnel, 115 answered directunaffected (0 of 286 failed)
ForestVPN chosen mode, Standard kill switch172 through the tunnel, 116 failed, 0 answered directunaffected (0 of 288 failed)

With strict enforcement off, pbr let the chosen client fall back to the router's own connection while the tunnel was down: that is a leak by definition. With it on, the device waited.

The ForestVPN kill switch is never absolute. It covers the devices ForestVPN protects, not the router's own traffic and not a device on Direct, and under the Standard level the kill switch help page lists the cases that release protected devices, such as when you pause, when the client cannot start or after a firmware upgrade. Choose Strict if a protected device must never use your normal connection.

Can pbr and the ForestVPN client run together?

Yes for different devices; for the same one, we make no promise. In our run pbr sent one client into the tunnel by IP address while the ForestVPN chosen mode sent a second client there. Both answered "stand-in exit" while the Direct client answered "router".

The adapter's rule priority was 1901, ahead of pbr's policy rules at 29999 and 30000 and a main-table lookup at 29998; the coexistence page lists the numbers ForestVPN uses.

Overlapping devices, passwall2 and podkop were not tested.

For site-based choice the client can step back and let pbr route into fvpn0: press Let another app route. That button turns ForestVPN's protection and its kill switch off, and the coexistence page says "ForestVPN's kill switch does not cover traffic that pbr sends. pbr's own strict setting does that." It also says the pbr combination "has not been tested end to end". This run did not test it either: the pbr arm used a stand-in tunnel and the ForestVPN arm ran with protection on, in chosen mode.

See beside your other router software for the numbers each program uses and which pairs were tried.

Which should you pick: pbr, device modes or both?

Use the device modes when the question is which devices, and pbr when the question is which destinations. The table maps each need to the tool, with the source of each cell.

NeedpbrForestVPN device modesSource
Choose by deviceyes, by IP or MACyes, by hardware addresspbr docs, device modes page
Choose by destination address, port or protocolyesnopbr docs, our run for destination address
Choose by domainyes, with dnsmasq-fullnopbr docs; not run here
Choose by appno app option in its documented match keysno, neverdevice modes page
Keep a device directleave it without a policyset it to Directour run
Survives a changed hardware addressno (MAC key and IP key both lost it)in the except mode in our run; chosen mode lost it; Every device protects any device that connects (not re-addressed here)our run, device modes page
Blocks a chosen device when the tunnel stopswith strict_enforcement 1with the kill switch, not absoluteour run, kill switch page
  • A handful of fixed devices and a route by site for others: run both and keep their devices apart. pbr by site beside the client was not run here, and the coexistence page sends site routing through Let another app route.
  • Every phone in the house protected without keeping lists: choose Every device except and set the few exceptions to Direct.

For a MikroTik router the same question has a different set of recipes, and the OpenWrt overview covers the three ways to run a tunnel on one. If the tunnel is up and nothing loads, start with the connected-but-no-internet guide.

Questions and answers

How do I route only some devices through a VPN on OpenWrt?

Install pbr, enable it, add the tunnel as a supported interface, and write one policy whose source is the device's IP or hardware address and whose interface is the tunnel. Or use the ForestVPN client's device modes, tick the devices in Services > ForestVPN > Devices and save. Either way the tunnel interface must sit in a firewall zone.

Does pbr route by MAC address or by IP address?

Both. The pbr documentation says a source address entry can be an IP address, a CIDR, a host name or a colon-separated MAC address. In our run a MAC policy was rendered as an nftables rule on the source hardware address.

What is the difference between pbr and the ForestVPN client's device modes?

pbr can choose by source, destination, port, protocol or domain, and you keep the interface, zone and policy consistent yourself. The client's modes choose by device only, never by website or app, and the client keeps the routing table and the kill switch rules.

Why did a phone go direct after I chose it?

A private Wi-Fi address that changes, or is switched on after you set the policy or tick, makes the phone look like a new device, so a policy or tick keyed on the old address no longer matches (see the device modes help page at /help/openwrt-device-modes/). In our run the re-addressed client answered with the router's own address. Turn the private address off for your home network, or, with the ForestVPN client, use the mode that protects every device except the ones you list.

Can I choose devices by website or app on OpenWrt?

Not with the ForestVPN device modes. pbr can choose by destination address and, with a full dnsmasq, by domain. Our run covered destination address only, not domains.

What does a device set to Direct mean for the kill switch?

A device on Direct is never blocked by the kill switch and never uses the tunnel. The kill switch is not absolute: it covers the devices ForestVPN protects, not the router's own traffic and not devices on Direct.

Can pbr and the ForestVPN client run together?

In our run they did, for different devices: one client by pbr, another by a device mode, both reached the tunnel. Overlapping devices, passwall2 and podkop were not tested. The coexistence help page says which pairs were tried.

Sources

  1. pbr (Policy-Based Routing) package documentation (read October 16, 2026)

How this was made

Drafted with AI assistance from a lab run on an OpenWrt router container, the pbr documentation and ForestVPN's router help pages, then checked by automated gates and an editor; the method and its limits are in the Method box.

All posts

Back to top

Ask us anything