Where an Android Firewall Rule Has to Live When a VPN Is On
Only one VpnService can be active, so a firewall app and a VPN app do not stack. Walk one work request and put each rule where its traffic really passes.
You have one sentence of policy: this app may reach the work service, and nothing else. The next question looks like a product choice, but it is a location question, because each candidate enforcement point sees a different subset of the phone's traffic. A gateway sees only what enters the tunnel. A phone-side filter sees only what it is permitted to observe. Walking a single request through both makes the answer obvious.
Start with the sentence, not the product
Expand the requirement before choosing anything. That means the package and the profile it runs in, because a work-profile app is a different user from the same app in the personal profile. It means the destination: host, port and protocol, not a service name. It means the DNS path that resolves that name, and it means what should happen when the tunnel is not available.
Written out, the policy for the example is four lines: the work app may reach the work service; the work app may reach nothing else; other apps are unchanged; with no tunnel, the work app is denied rather than falling back. Each line has an owner, and they are not all the same owner.
Step 1: what the phone itself can enforce
A non-root Android firewall is a VpnService that captures traffic locally, even when there is no remote tunnel behind it. Android permits one active VPN service per user profile, so a second firewall app does not chain behind the first. It replaces it, and the interface the first app was filtering goes away.
That is why installing a firewall beside a VPN client rarely produces the combination people expect. If the firewall starts and the VPN disconnects, nothing was combined; the two swapped places. An interface replacement is not cooperation, and the symptom is a tunnel that keeps dropping whenever the other app is opened.
Supported arrangements do exist: filtering built into the VPN client you already run, managed platform controls through a device policy controller or work profile, or an architecture the vendor documents. Anything else is an experiment that has to be re-verified after every app update.
Step 2: what the gateway can enforce
Once traffic is decrypted at the far end, the gateway can restrict forwarded packets to approved addresses, services or authenticated VPN identities. That is genuine enforcement for everything that exits through it, and it is the right place to limit access to private subnets.
What it does not receive is the phone's app identity attached to each ordinary IP packet. Several apps sharing one tunnel address are one subject to the gateway unless the design gives them separate addresses or separate authenticated identities. A per-user rule at the gateway is therefore not a per-app rule on the phone, however the management console labels it.
Step 3: list what never arrives
An app excluded from the VPN that contacts a nearby device never reaches the gateway, so an exit firewall cannot refuse a packet it never receives. The same applies to an unintended direct route during an outage and to inbound exposure on the local access network. Those are local boundaries by definition.
The converse also holds: a local rule that permits a connection does not grant access through the gateway's private-network ACL. One request can be subject to both boundaries, and satisfying one says nothing about the other.
Step 4: assign each rule to a path
Put the decision in a table before configuring anything, because the blank cells are where designs fail.
| Path | Who can enforce it | Blind spot |
|---|---|---|
| Work app to the work service, tunnel up | Gateway ACL on address and service, plus a local block on other paths | The gateway cannot see which app sent the packet |
| Work app to other destinations, tunnel up | Local app-aware filter, or the gateway if those destinations are addressed there | The local filter must be the active VpnService |
| Work app with no tunnel | Local deny, so the app cannot take a direct path | Requires the filter to survive the tunnel going away |
| Nearby LAN device | Local policy only | The gateway never sees it |
The workable shape is two boundaries with two jobs. A local app-aware boundary governs phone behaviour, including the direct fallback, and a gateway boundary governs remote resources. The gateway side can allow the work service and refuse every other private subnet, while the phone-side policy makes its own decision about a direct path the app might otherwise take.
Step 5: keep the transport alive, then verify
Whatever local policy you land on has to permit the transport that establishes and maintains the VPN. Blocking that transport strands the phone with no tunnel and no policy, which enforces nothing coherently and is hard to diagnose because the app simply has no network.
Then verify each line of the original sentence rather than the overall impression: the work app reaches the work service, the same app is refused at another destination, a non-work app behaves as before, and with the tunnel stopped the work app does not fall back to a direct connection. Check the DNS path separately, since private DNS or an encrypted resolver can bypass a filter that only inspects addresses.
If one of those steps cannot be satisfied on the phone, the requirement is an architecture question and not a firewall setting. Splitting the policy across a device you control and a gateway you control is usually the honest answer, and the Android VPN connectivity documentation is the place to confirm what the platform will and will not let a single service do.