Tell DNS leaks apart from resolver location differences
If Clash is using a proxy but a DNS test still shows your local ISP, some queries may still be leaving over your local network. However, seeing resolvers in multiple countries does not necessarily mean you have a leak. First decide which domains can use local DNS and which must be resolved through the proxy, then check each path.
This configuration is for the Clash Meta (mihomo) core. Older Clash versions, some mobile clients, and other proxy tools may support different fields. Before making changes, check the core name in your client’s core information or runtime logs, and back up your current configuration. Don’t assume respect-rules or the TUN settings below are supported based on the client’s name alone.
| What you see | What it may mean | Next step |
|---|---|---|
| The site shows the proxy node’s exit IP | The web connection uses the proxy, but the DNS path is still unconfirmed | Run an extended DNS test |
| The resolver is identified as your local ISP | The system, browser, or core may be sending DNS queries directly | Compare logs and capture traffic on port 53 |
| The resolver is identified as a public DNS provider | The request reached a public recursive resolver | Check the outbound route to that resolver |
| Both expected local and overseas resolvers appear | This may be intentional split-domain DNS | Judge by policy, not by the number of resolvers |
Establish a baseline: use the same node, browser, and test conditions
Record results under three sets of conditions
- Proxy off: Record your public IP, ISP name, and DNS test results as a baseline for your local network.
- System proxy only: Keep the same node, turn off TUN, and run the standard and extended tests again. A system proxy mainly covers apps that honor proxy settings; it does not automatically handle all system DNS traffic.
- TUN on: Keep the node, rules, and browser unchanged. Enable DNS hijacking and test again. Record the resolver addresses, test time, and whether your local ISP appears.
You can use the DNS leak test or BrowserLeaks DNS test page. Start a fresh test each time; don’t treat results left on a previous page as new. Run two tests in a row. If an issue appears only once, first check the browser cache, whether the node changed, and whether the configuration was reloaded.
Temporarily rule out browser-level DNS
In desktop Chrome, go to Settings → Privacy and security → Security → Use secure DNS. In Firefox, look under Settings → Privacy & Security → DNS over HTTPS. Turn off browser-level DoH while testing; menu names may vary by version. If you turn it back on after fixing the issue, verify the DoH connection’s outbound route separately.
Incognito mode does not automatically turn off Secure DNS. When a browser connects to a separate resolver over HTTPS, it typically uses port 443. Even if TUN captures that connection, the dns-hijack rule for port 53 will not turn it into a DNS query handled by the core.
- On Windows, clear the system DNS cache with
ipconfig /flushdns. - On Linux with systemd-resolved, run
resolvectl flush-caches. For other distributions, use the command for your DNS service. - Also clear or restart the client’s DNS cache, then close and reopen the test page. Clearing only the system cache does not clear every app’s cache.
What fake-ip does: preserve domain mappings, not automatically hide queries
enhanced-mode: fake-ip returns a synthetic address for eligible domains; a common address pool is 198.18.0.1/16. When an app connects to that address, mihomo looks up the mapped domain and applies its rules and outbound routing. So seeing a DNS result starting with 198.18 on your device is usually expected; it does not mean the remote server is actually on that subnet.
fake-ip changes the answer returned to the app. Whether a real lookup is needed, which resolver handles it, and whether the query goes direct or through a proxy still depend on the connection method, outbound protocol, and DNS configuration. Enabling fake-ip alone does not guarantee that all upstream queries use the proxy.
Use filter lists only for compatibility exceptions
LAN device discovery, printers, and some apps that require real addresses may need entries in fake-ip-filter. For example, +.lan and +.local can be starting points for checking local domain names, but a local DNS service that can resolve those names is still required. Adding names to the filter does not enable mDNS or automatically find your router.
Don’t add every domain to the filter to fix one app. Identify the affected domain first, add the narrowest possible exception, then test that domain’s DNS path again. Returning a real IP and leaking DNS are two different issues.
Configuration example: split DNS and upstream routing
The following mihomo dns and tun sections are examples to adapt, not a complete subscription. Keep your existing nodes, proxy groups, and rules; merge fields with matching names, and don’t add two top-level dns sections to the YAML. Save changes as a local override or merged configuration in your client to avoid having a subscription update overwrite them.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '+.lan'
- '+.local'
respect-rules: true
default-nameserver:
- 223.5.5.5
- 119.29.29.29
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
nameserver:
- https://1.1.1.1/dns-query
nameserver-policy:
'+.cn':
- https://dns.alidns.com/dns-query
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
| Field | Purpose in this example |
|---|---|
default-nameserver | Resolves the DNS server’s hostname; it is not the default upstream for all domain lookups |
proxy-server-nameserver | Resolves proxy-node hostnames separately to reduce DNS dependency loops before the proxy connects |
nameserver | Handles regular domain queries that do not match a DNS policy |
nameserver-policy | Chooses a resolver based on the query domain; it does not select the proxy node for web traffic |
respect-rules | Makes DNS upstream connections follow routing rules; you still need to verify which outbound is actually selected |
What to check in this example
- Upstream routing: To resolve ordinary domains through a proxy, confirm that connections to
1.1.1.1:443use the intended proxy group, notDIRECT. If they go direct, adjust the order and targets of your existing rules;respect-rules: truealone is not enough. - China-specific DNS:
+.cnmatches only the relevant domain names; it does not mean “all websites in mainland China.” Services in mainland China may use .com, and services outside China may use .cn. Add precise policies for the domains you actually need. - Bootstrap queries: This example keeps bootstrap and proxy-node resolvers that are reachable locally. Those queries may go out directly. If you need every lookup, including proxy-node hostnames, to avoid your local network, design a separate reachable bootstrap route rather than copying this section as-is.
- DoH reachability: HTTPS encrypts the connection, but does not mean it goes through a proxy. If your current network cannot reach the resolver directly, fix the route or choose a reachable upstream first.
TUN DNS hijacking: captures port 53, not every DNS protocol
The example includes hijacking for both UDP and TCP on port 53. These rules work only if the relevant packets enter TUN; they won’t apply if another VPN, a static route, or an app-bound interface bypasses it. auto-route configures routes automatically, while auto-detect-interface identifies the outbound interface. Check both against system permissions and the actual routing table.
Don’t confuse the listening port with the hijack target
listen: 127.0.0.1:1053 sets up a local DNS listening address for the core. dns-hijack hands specified DNS requests entering TUN to the core. Enabling TUN hijacking does not mean you need to set system DNS to “127.0.0.1:1053”; most system DNS settings do not support specifying a port this way.
Listening only on the loopback address prevents other devices from connecting. If you want to provide DNS to devices on your LAN, plan the listening address, firewall, and gateway separately. Don’t expose the service on every interface just to fix a leak on your own device.
- DNS over TLS: Usually uses TCP port 853, so it is not covered by the two port 53 rules above.
- DNS over HTTPS: Usually uses HTTPS on port 443; check its outbound route like any other network connection.
- Android Private DNS: For troubleshooting, first turn off any custom provider under the system’s Private DNS settings, then test the client’s DNS.
- IPv6:
dns.ipv6: falsecontrols how the core handles AAAA queries. It does not disable system IPv6 or automatically capture existing IPv6 connections.
Retest and troubleshoot: trace the path from the local entry point to the upstream connection
First confirm the configuration is actually active
- Save the override and reload the configuration. Check the logs for unknown fields, YAML indentation errors, or port binding failures.
- Check that the TUN adapter and related services are running. On Windows, this usually requires the client service or appropriate permissions; turning on a switch in the UI does not guarantee that routes have been set up.
- Temporarily increase log verbosity and watch the domains, rules, and outbound records during testing. Restore your usual log level when you’re done troubleshooting.
- Clear the cache and rerun the test with the same node. Compare the new results with your original baseline.
If dig is installed, query the core’s listening address directly to confirm the DNS module responds:
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA
In fake-ip mode, an A query may return a synthetic address. With DNS IPv6 disabled as in the example, an AAAA query may return no address. These commands query the core directly and verify only the listening endpoint, not whether system requests are captured by TUN. You still need to connect from a regular app and observe the route.
Use packet captures to find traffic that still bypasses the proxy
Capture traffic on the physical network adapter, not just the virtual TUN adapter. In Wireshark, you can use the display filter below. Port 853 can help identify common encrypted DNS connections, but it does not cover every encrypted DNS method.
udp.port == 53 || tcp.port == 53 || tcp.port == 853
If you still see your device sending ordinary domain queries to your ISP’s DNS, check the system resolver, browser, other VPNs, and TUN exclusion routes. If you see only bootstrap or proxy-node hostname lookups, decide whether they are expected based on the scope you set earlier. DoH uses port 443, so an empty result from this filter does not mean every issue is fixed.
Common questions and how to confirm the fix
The test still shows my ISP after enabling fake-ip. What should I do?
First confirm that the test request reaches the core. If it does, check the upstream DNS connection’s outbound route and any existing fallback settings. If it does not, start with browser-level DNS, system Private DNS, and TUN routing. Changing the fake-ip address pool repeatedly usually won’t fix a routing problem.
Does nameserver-policy make matching websites connect directly?
No. It determines which resolver handles a domain. The website’s outbound route is still determined by rules, the mode, and proxy-group settings. Verify the DNS resolver connection’s outbound route and the target website connection’s outbound route separately; they are not the same connection.
Why does the issue come back after switching networks?
Switching between Wi-Fi and Ethernet changes the gateway, interface, and system DNS. A stale route may also remain after waking from sleep. Check the TUN service, default interface, and local DNS listener, then clear the cache and test again. If the system can’t resolve domains after you close the client, restore system DNS and routes first. Confirm basic connectivity before loading the configuration again.
What counts as a successful fix?
- For test domains that should use proxy DNS, the upstream connection uses the expected proxy outbound.
- Port 53 queries from regular apps reach the core, and the physical network adapter shows no plaintext domain queries that violate your policy.
- Browser DoH, system Private DNS, and IPv6 routes have each been checked separately—not just one of them turned off.
- After subscription updates, client restarts, and network changes, rerun the test to confirm the override and routes still work.
Effective DNS protection means having a DNS path you can explain and test. fake-ip maps domains, nameserver-policy selects resolvers, and TUN hijacking centralizes the entry point. Routing rules then determine how upstream connections leave your device. The test results are meaningful only when all four pieces work together.