Client lookups follow the tunnel while the router's own lookups leave by the WAN, and the firewall rule that governs one has no effect on the other. The reason is not a bug: a forwarded request and a request the router generates are two separate flows, and each is matched against a different part of the configuration. Capturing only the client half produces a confident answer about a path the second half never uses. The repair is to point the router's resolver deliberately, then test the two paths apart.

Which flow the packet capture actually belongs to

One lookup involves two exchanges. A LAN client sends a query to the router's resolver, which arrives as forwarded traffic on the LAN interface, so a policy route or NAT rule written for forwarded packets can match it. The router then answers from cache, or, on a miss, opens its own query to an upstream server.

That second query has the router as its source and its own destination, and the platform picks its path from a different configuration block. Both exchanges carry the same name, and neither is a copy of the other. A capture taken on the LAN side therefore proves where the client's packet went and says nothing about the outbound one.

The practical check is to watch both sides at once. On the router, list the resolver socket, query it locally and capture the WAN interface:

sockstat -4 -l | grep :53
dig +short @127.0.0.1 example.com
tcpdump -ni igb0 udp port 53

If the socket list shows a listener bound to the loopback or LAN address, the router is answering locally rather than forwarding to another host. The capture then shows whether the resulting upstream query leaves by the tunnel interface or by the WAN, which is the answer the policy-route rule was never going to give.

Why the policy route never sees the second query

Firewall rules are written against an interface, a source, a destination and a port, and they are evaluated for packets that pass through the box. A query the router originates passes through nothing, because a local process hands it straight to the routing table. Policy routing and NAT therefore apply to the forwarded path only, which is why a rule set can look complete and still leave the router's DNS outside the tunnel.

The distinction survives every firmware rewrite because it follows from the packet path rather than from a feature. Anything the box generates for itself, whether resolver queries, time synchronisation, update checks or package mirror access, is locally originated and lands in the same blind spot. That is also why a test that works from a laptop proves nothing about the router.

Where a pfSense resolver decides its own upstream path

pfSense makes the split visible. Client traffic can be policy-routed through a VPN gateway while the firewall's own traffic follows the resolver's outgoing setting rather than the LAN rules. In the web interface that setting lives under Services > DNS Resolver > Outgoing Network Interfaces, and its value is the list of interfaces the resolver may use for upstream queries.

Naming the tunnel interface there, and only that interface, is what makes the router's own lookups follow the tunnel. Left at the default, the resolver picks an egress from the routing table, which on a dual-WAN or VPN host is often the WAN.

Other firmware exposes the same decision under a different label: an upstream server list bound to a source address, a forwarding-only mode, or a documented route policy. The setting to hunt for is always the one that chooses an egress or a source for locally generated queries. The resolver configuration reference documents that option for pfSense and is worth reading before the change.

Choose the failure behaviour before the setting

Two behaviours are defensible when the tunnel drops: stop upstream queries so nothing leaks, or fall back to an approved resolver on a known path. Both are policies, and neither is what you get by default. Decide which one the network needs before touching the interface list.

Fail-closed is simpler to defend, but it turns a tunnel outage into a name-resolution outage for every device behind the router. Fallback keeps the office usable, at the cost of an upstream exchange outside the tunnel that has to be acceptable on purpose rather than by accident. Write the choice down, because the next person to see a resolver address outside the VPN will read it as a leak unless a note says otherwise. That note is what separates a documented fallback from an unexplained finding in next quarter's review.

Two cases complicate the decision. Private names may need an internal resolver that the tunnel can reach, and a browser or application with its own encrypted DNS can bypass the router entirely, so the resolver you configured is not always the one a given app uses.

Test both paths and keep the results apart

A browser-based DNS test answers a narrow question: which resolvers did that browser use, under that test's conditions. It does not inventory the devices on the network and it cannot see a query the router generated for itself. Treat its output as one data point rather than as an audit.

From a LAN client, ask the router for a public name and then for a private one that only your internal zone should answer. A failure on the second query alone points at name forwarding rather than at the tunnel:

dig @192.168.1.1 example.com
dig @192.168.1.1 intranet.example.lan

Then bring the tunnel down and repeat both queries. Refused answers mean the resolver is fail-closed; a successful answer points at a fallback resolver and the path it used. Compare that with the note you wrote and with a capture on the WAN interface taken during the same minute.

Keep the observations separate in the record: the client-to-router exchange, the router-to-upstream exchange, and the configuration that decided the second one. A later routing change will exercise that second exchange without warning. An answer that arrives from somewhere other than the VPN endpoint is not by itself a leak; it becomes a leak only when the configuration chose that path by accident.

Nsɛm a ɛfa ho