Is Your VPN DNS Actually Used? Capture Port 53 and See
A pushed DNS option is not a query path. Check what the interface holds, watch the query leave, and stop trusting a leak-test page for proof.
Ask most people what a VPN client does with DNS and they will say it sets the resolver, so queries travel inside the tunnel. The push is real; the assumption that it becomes a query is not. Between a pushed option and a packet on the wire sit three stages, and each fails independently in ways that all look like a broken DNS server. That is why a leak-test page and a working browser can disagree about the same machine at the same moment.
A pushed option is not a query
Stage one is the server offering settings, for example a pushed DNS option naming a resolver inside the tunnel. Stage two is the client applying those settings to an interface. Stage three is an application actually sending a query to that address. A failure at stage two leaves the option visible in the connection log while the resolver list stays unchanged, and a failure at stage three leaves a perfectly correct resolver list unused.
Most troubleshooting collapses those three into one and blames the VPN server, which is the only party that can usually prove it did its part. Read the client's real resolver state instead, then watch one query leave. Those two observations separate configuration from routing from policy, and they cost about five minutes. Keep the captures, because the next engineer wants the before and after rather than a description of them.
Check what the interface actually holds
On Linux the system resolver may be the plain file, NetworkManager or systemd-resolved, and which of them owns it decides where a pushed server lands. A command-line OpenVPN process does not update the system resolver on its own, so the documented integration is an up/down script or a connection manager that already knows how to apply the settings. Running both is an efficient way to create a race.
resolvectl status
cat /etc/resolv.conf
On Windows the list is per adapter, so the tunnel adapter can hold the internal servers while the physical adapter keeps the local ones and wins for some names. Compare both adapters rather than the one you assume is active.
Follow one query off the machine
Capture both interfaces simultaneously, then resolve one name that should use the internal resolver. That pair of captures answers what no configuration output can.
sudo tcpdump -ni tun0 port 53
sudo tcpdump -ni any port 53
A query that appears on the physical interface and never in the tunnel means the client picked the wrong resolver. A query on neither means the application answered from cache, asked a stub listening on loopback, or used an encrypted resolver whose traffic never appears as port 53 at all. Capture answers as well as queries, since a query leaving through the tunnel with an answer from a public address is a different fault from no answer arriving.
The firewall that accepts only its own DNS
Commercial clients sometimes install filter chains of their own. One documented pattern permits DNS to the client's own resolver and discards all remaining UDP port 53 traffic that tries to leave a non-loopback interface, including traffic the user deliberately routed elsewhere. Daemon queries vanish without a trace, which reads as a resolver failure rather than as a filter.
sudo iptables -S OUTPUT
sudo iptables -S | grep -i -E 'dns|53'
If a discard rule is evaluated before your exception, an appended rule is never reached, so insert at position one and limit the destination to the resolver you actually intend.
sudo iptables -I OUTPUT 1 -p udp --dport 53 -d 172.20.8.1 -j ACCEPT
That exception is diagnostic rather than policy. If the vendor rule is deliberate, the supported repair is to configure the client to permit that resolver and to record the decision, because an inserted rule will not survive the next client upgrade.
Why a leak page proves less than it seems
What a leak-test page shows is the resolver that spoke to the test operator, not the one your machine consulted. A local forwarder that recurses outward puts its own egress address on that page, and encrypted queries may leave the page blank altogether. Both results get misread, one as a leak and the other as a guarantee, and neither reading follows from the observation.
The defensible evidence is the capture: interface, destination address, answer and timestamp. Take one before the tunnel comes up and one after, and compare them the next time a name fails. That pair also tells the next person whether the fault was resolution, routing or the resolver's own access policy.