Preventing DNS leaks means checking the request source, resolver, and outbound route. This guide is for users who can connect to a server but aren’t sure whether DNS queries follow the proxy. Start by comparing direct and proxied connections, then configure DNS in v2rayN or v2rayNG, and finally check FakeDNS, browser Secure DNS, and routing exceptions. Match test results against your actual rules; the resolver’s location alone isn’t enough.
1. Identify DNS Leaks: Decide Which Queries Should Use the Proxy
Visiting a domain usually involves two separate paths: resolving its IP address, then establishing the connection. A web connection going through the proxy doesn’t mean the preceding DNS query did too. A system proxy mainly changes how proxy-aware apps connect; it usually doesn’t intercept UDP 53 queries from the entire device.
This guide focuses on domain queries that should use the proxy but are sent over the local network instead. If your routing policy explicitly sends LAN domains, local domains, or specified sites direct, resolving those queries locally is expected. To route all public DNS queries through the proxy, you’ll also need to prevent local fallback and app-level bypasses.
| Test result | What it doesn’t prove | What to check next |
|---|---|---|
| The website’s exit IP has changed | All DNS queries use the proxy | Which resolver the browser, system, and core use |
| The resolver appears to be a public DNS service | The query definitely went through the proxy | Whether the DoH connection uses a direct or proxied outbound route |
| Multiple resolvers are detected | A leak definitely occurred | Whether split routing, fallback, or a resolver cluster is in use |
| A local ISP resolver appears | The server configuration is definitely wrong | Whether system queries, browser fallback, or direct-routed domains are involved |
How to interpret results: define the expected path first
If your expectation is “public domains resolve through the proxy, while LAN names resolve locally,” test each type of query separately. Resolver names and locations offer clues, but they can’t replace outbound logs or packet captures.
2. Compare Results: Check the Browser and Capture Traffic on Your Device
Disable the proxy and record the resolver details shown by a DNS test page. Then enable the proxy and run the same test in the same browser. Test pages typically trigger queries for random subdomains, reducing the effect of cached results. However, they mainly test the current browser’s DNS path and can’t confirm that other apps are covered.
-
Record a baseline
Note your current network, proxy mode, browser Secure DNS setting, and system Private DNS setting. Test the direct connection first, then enable the proxy. Keep all other settings unchanged between tests.
-
Clear the cache
On Windows, run the command below to clear the system DNS cache. Browsers may keep their own cache, so close and reopen the relevant pages. Clearing the cache won’t reroute connections that are already open.
-
Test a fresh random domain
Run a new test on the DNS test page instead of refreshing the previous results. Record the resolver addresses and providers, then compare them with the direct-connection results. Don’t draw conclusions from a single location shown on the page.
-
Check outbound traffic
Monitor UDP/TCP 53 traffic on the physical network adapter. Check whether queries for the test domain go directly to your router or ISP resolver, and use core logs to confirm the outbound route for remote DNS.
ipconfig /flushdns
nslookup example.com
nslookup example.com shows system-level DNS behavior; it does not test an HTTP or SOCKS proxy. With only the system proxy enabled, the query may still go to the DNS server configured on your system. Whether TUN intercepts it depends on that mode’s DNS hijacking and routing settings.
3. v2rayN: Configure the System Proxy, TUN, and Remote DNS Separately
v2rayN is a desktop client. The selected core and generated configuration determine how DNS resolution and routing work. First, confirm that the current server is available on the main screen, then check Settings → DNS Settings. Field layouts vary between builds. If the option you need isn’t in the current UI, inspect the generated configuration rather than treating screenshots from another version as a definitive menu guide.
-
Confirm what the proxy covers
For browser-only testing, start with the system proxy. To cover apps that ignore system proxy settings, enable TUN mode on the main screen and confirm that system authorization succeeds. Turning on TUN doesn’t necessarily mean DNS hijacking is active.
-
Set the remote resolver
Go to Settings → DNS Settings and enter a supported resolver address in the remote DNS field for the current core. For example,
https://1.1.1.1/dns-queryis a DoH URL; don’t enter it in a field that only accepts a plain IP address. -
Check DNS routing
Review Settings → Routing Settings and the currently enabled rule sets. Make sure an earlier direct rule doesn’t intercept the remote DNS connection. Also preserve the bootstrap resolution path needed for the server address.
-
Restart and retest
Save your changes, restart the current service, clear the cache, and repeat the same comparison tests. After switching to TUN, test system-level queries separately; a successful browser test alone doesn’t prove that DNS is intercepted for the whole device.
In system proxy mode, also check the local listening address. The HTTP or SOCKS port used by an app must match the value shown in the client; DNS port 53 is not a SOCKS endpoint. Don’t enter a remote DNS address in an app’s proxy server field, and don’t expose a LAN listening address just to troubleshoot DNS.
4. v2rayNG: Check Local DNS, Remote DNS, and App Coverage
v2rayNG routes app traffic through Android’s VPN interface and uses Xray as its core. “Local DNS” here usually means a local-side server in the resolution policy; it doesn’t necessarily mean a server bound only to the loopback address. Use the setting descriptions and generated configuration to understand how it works—don’t infer whether traffic leaves the device from the name alone.
-
Check which apps are covered
Go to Settings → Per-app proxy and check whether the current mode proxies only selected apps or bypasses selected apps. The browser used for testing must be covered by the proxy; otherwise, you’re testing that app’s direct connection.
-
Enable core DNS resolution
Go to Settings and find Enable Local DNS and the DNS configuration options. If this build provides the toggle, enable it and check the values under Remote DNS and Local DNS. Menu wording may vary slightly by version.
-
Set a remote resolver
Enter a server supported by the current core under Remote DNS, such as
https://1.1.1.1/dns-query. Test a single remote resolver first; don’t add multiple unverified fallback servers at the same time. -
Check system DNS
Search Android Settings for “Private DNS.” Note its current setting, then temporarily turn it off for comparison. Restore it after testing, and confirm that the encrypted DNS connection follows the expected route once it’s back on.
-
Reconnect and check the logs
Disconnect and start the connection again, then check for DNS resolution errors and request timeouts. If only excluded apps still use a local resolver, fix the app coverage first instead of continuing to change DNS servers.
5. Routing Remote DNS: Encryption Doesn’t Mean Proxied Traffic
DoH encrypts query data in transit; the connection’s route determines whether it uses the proxy. With Xray’s built-in DNS, ordinary https:// queries can go through core routing. The https+local:// scheme uses local queries and shouldn’t be mixed in when queries must follow the core’s proxy route.
The Xray configuration snippet below illustrates how these pieces fit together; it isn’t a complete client configuration. It tags built-in DNS queries as dns-query, then routes traffic with that tag through an existing proxy outbound. Before using it, confirm that your core supports these fields and that the actual proxy outbound is named proxy.
{
"dns": {
"tag": "dns-query",
"servers": [
"https://1.1.1.1/dns-query"
],
"queryStrategy": "UseIPv4"
},
"routing": {
"rules": [
{
"type": "field",
"inboundTag": ["dns-query"],
"outboundTag": "proxy"
}
]
}
}
- Merge, don’t overwrite: Add the DNS rule in the appropriate place in the existing rule list, usually before any broad direct rules that would match it. Don’t replace the entire client-generated
routingconfiguration. - Distinguish internal from external traffic:
dns.tagmarks queries sent by built-in DNS. It doesn’t automatically send every app’s UDP 53 packet to the built-in resolver. System-level traffic still needs DNS hijacking or a dedicated DNS inbound. - Preserve bootstrap resolution: If the server address is a domain and remote DNS is only reachable through that server, startup can become a dependency loop. Provide reachable bootstrap resolution for the server domain, or use a suitable static mapping once you’ve confirmed the address is valid.
- Set an explicit IPv6 policy:
UseIPv4in the example only limits the variables in this resolution test. It doesn’t disable system IPv6 and isn’t a general-purpose DNS leak prevention switch. If you need IPv6, also verify AAAA resolution and the route for IPv6 connections.
Practical takeaway: verify one route before adding split rules
First, get a single remote DNS resolver working reliably through the proxy. Then add local-domain rules, backup resolvers, and IPv6 one at a time. Retest after each change to identify which exception changes the outbound route.
6. FakeDNS: Virtual Addresses Still Need Traffic Interception
FakeDNS assigns a virtual address instead of returning the destination site’s real IP, and stores a mapping between the domain and that address. When an app connects to the virtual address, the core uses the mapping to recover the domain and pass it to routing and outbound processing. This can avoid real DNS lookups in some situations, but it doesn’t replace encrypted remote DNS.
A common IPv4 virtual address pool is 198.18.0.0/15, covering 198.18.0.0 through 198.19.255.255. These aren’t public IP addresses for destination websites. If FakeDNS handles a query but the subsequent connection bypasses interception, the app will try to reach a virtual address that can’t route to the intended site.
| What must work together | What to check | What happens if it’s missing |
|---|---|---|
| Query path | The app’s DNS queries actually reach FakeDNS | The app still gets a real IP; its DNS traffic isn’t covered |
| Connection interception | Traffic to virtual addresses returns to the same core | Resolution succeeds, but connections keep timing out |
| Mapping recovery | The inbound supports FakeDNS domain recovery | Routing can’t match the original domain |
| Cache lifetime | Old virtual addresses aren’t reused after a restart | Some apps temporarily stop working after the core restarts |
In v2rayNG, if Settings includes Enable Virtual DNS, first enable Local DNS as required by your build, then enable Virtual DNS. Check whether the sniffing settings support FakeDNS recovery. In v2rayN, check how TUN works with FakeDNS in the current core. Adding a virtual address pool alone doesn’t complete DNS interception or domain recovery.
7. Troubleshooting Logs: Tell Resolution Errors from Connection Errors
First, note when the error occurred and the destination address, then check the logs from the same period. The strings below may appear in the log chain; prefixes and full messages vary by core version. A single timeout proves neither a DNS leak nor that the DNS server itself is unavailable.
Error: failed to lookup ip for domain
Cause: The core couldn’t obtain a usable address for the domain. Possible causes include an unreachable remote resolver, failed bootstrap resolution, or a query policy that excludes usable records.
Fix: Check the domain named in the log. First confirm that the server domain can be resolved during bootstrap, then check the remote DNS route and the IPv4/IPv6 query policy.
Error: context deadline exceeded
Cause: An operation didn’t finish within the allowed time. If the error is associated with a DoH request, the HTTPS connection to the resolver or its upstream response may have timed out.
Fix: Test the resolver address over the same proxy route. Replace only one remote DNS server at a time, and check for a dependency loop where DNS needs the proxy but the proxy needs DNS.
Error: network is unreachable
Cause: There’s no usable route from the current network to the destination, for example when trying to connect to an unreachable IPv6 address.
Fix: Check the address family of the destination in the error and temporarily compare results using an IPv4 query policy. Also check TUN routing, the physical network, and IPv6 support on the proxy outbound.
8. FAQs and Final Checks
Does seeing a local resolver on a test page always mean there’s a leak?
First check whether the test browser is covered by the proxy, then review local DNS split-routing rules. You have clearer evidence of a bypass only if the test domain is supposed to use the proxy and you can see its query going directly out through the physical adapter.
Why didn’t anything change after I entered a DoH URL?
Make sure you changed the DNS configuration used by the active core, then restart the service. Temporarily turn off browser Secure DNS and test again; if the browser resolves domains on its own, it may not use the core DNS settings you just changed.
FakeDNS resolves domains, but webpages won’t load. What should I do?
First check whether connections to virtual addresses follow the same interception path and whether the inbound enables domain recovery. Disable FakeDNS, clear the app cache, and test again. If that fixes the problem, focus on mapping and interception instead of changing servers first.
Will blocking all port 53 traffic fix the problem?
No. It may block necessary bootstrap resolution, and it won’t stop DoH on port 443 or DoT on port 853. First establish a working, controlled DNS path, then restrict bypasses as needed while keeping essential LAN services available.
Include proxy reconnects, client restarts, and network changes in your final tests. Wi-Fi and mobile networks may provide different resolvers and IPv6 routes, so a test on one network doesn’t represent results on another. Keep a record of configuration changes and roll them back one at a time if issues arise.
- Browser test results match expectations, and the browser’s own Secure DNS settings have been checked.
- System queries that should be intercepted aren’t being sent directly from the physical adapter to an unexpected resolver.
- The remote DNS connection uses the proxy outbound, and the server address can still be resolved during startup.
- LAN domains, direct-routed sites, and proxied sites have each been tested.
- With FakeDNS enabled, clear old caches after restarting the core and retest connections to virtual addresses.