DNS Leak Test and Prevention: Remote DNS, FakeDNS, and Routing Rules

Learn how to detect DNS requests bypassing your proxy and configure remote DNS, FakeDNS, and DNS routing rules in v2rayN and v2rayNG.

At a glance

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 resultWhat it doesn’t proveWhat to check next
The website’s exit IP has changedAll DNS queries use the proxyWhich resolver the browser, system, and core use
The resolver appears to be a public DNS serviceThe query definitely went through the proxyWhether the DoH connection uses a direct or proxied outbound route
Multiple resolvers are detectedA leak definitely occurredWhether split routing, fallback, or a resolver cluster is in use
A local ISP resolver appearsThe server configuration is definitely wrongWhether 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  1. 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.

  2. 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-query is a DoH URL; don’t enter it in a field that only accepts a plain IP address.

  3. 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.

  4. 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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"
      }
    ]
  }
}

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 togetherWhat to checkWhat happens if it’s missing
Query pathThe app’s DNS queries actually reach FakeDNSThe app still gets a real IP; its DNS traffic isn’t covered
Connection interceptionTraffic to virtual addresses returns to the same coreResolution succeeds, but connections keep timing out
Mapping recoveryThe inbound supports FakeDNS domain recoveryRouting can’t match the original domain
Cache lifetimeOld virtual addresses aren’t reused after a restartSome 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.

Download v2rayNCompare clients for four platforms