First, define what counts as a DNS leak
Before a browser connects to a domain, the domain must be resolved to an IP address. After Clash is enabled, the web connection may already be proxied, while DNS queries can still go directly to the router, the ISP's DNS, a system-configured public DNS service, or encrypted DNS enabled by the browser. The proxy exit and DNS query exit then follow different paths.
The key is not simply comparing whether the DNS addresses shown by a test page match the proxy node's IP. Public DoH services usually respond from separate servers, and Anycast may route queries to a nearby data center, so the two can legitimately differ. What matters is whether the results show resolvers operated by a local ISP, company network, campus network, or home router, and whether those queries bypass the intended proxy and rule path.
Four common DNS paths
| Request source | Possible destination | What to check |
|---|---|---|
| Standard system DNS | UDP or TCP port 53 | Whether TUN captures port 53 and whether system proxy mode covers the application |
| Browser Secure DNS | The browser's selected DoH endpoint | Whether browser settings override system DNS and whether the same policy is used during testing |
| Clash built-in DNS | nameserver, fallback, or policy-selected servers | Whether upstream addresses, proxy routing, and rules are correct |
| Application-resolved DNS | Hard-coded DNS, DoH, or DoT | Whether TUN routing covers the application and whether it bypasses the system proxy |
Build a repeatable DNS leak testing process
A single test can be affected by caches, browser connection reuse, and upstream Anycast routing. For reliable results, record a baseline, clear caches, then test repeatedly with and without the proxy. Keep the browser, network, and configuration unchanged throughout so only one variable changes at a time.
Step 1: Record a baseline with Clash disabled
- Fully quit the Clash client and confirm that both the system proxy and TUN are disabled.
- Open dnsleaktest.com or browserleaks.com/dns, then run one standard test and one extended test.
- Record the detected DNS providers, countries or regions, and number of servers. Home broadband commonly returns 1 to 4 resolver addresses.
- Then open your operating system's network details and record the DNS addresses assigned to the current network adapter. A common value is the router address, such as
192.168.1.1, though it may also be a public address supplied by the network.
Use these results to identify local resolvers. After enabling Clash, if the same provider and addresses appear again, you can determine whether queries are still leaving through the local network.
Step 2: Clear caches and enable the proxy
On Windows, run ipconfig /flushdns in a terminal. On macOS, run sudo dscacheutil -flushcache, followed by sudo killall -HUP mDNSResponder. On Linux, the method depends on the resolver service; with systemd-resolved, run resolvectl flush-caches.
Next, start the client, import the target configuration, and enable the proxy. To verify DNS for all applications, go to “Settings” → “Network” → “TUN Mode” and enable TUN. To test only the browser's system-proxy path, leave TUN disabled and note that the result represents only that browser's traffic.
Step 3: Run two rounds of tests
- Use a regular window for the first round to confirm the result in your everyday browsing environment.
- Use a new private window for the second round to reduce the effect of page caches, Service Workers, and existing connections.
- Run at least one extended test in each round. Extended tests typically trigger more random subdomain queries, making mixed resolution paths easier to expose.
- If the first round shows two specified DoH resolvers but the second suddenly adds three local ISP resolvers, treat it as an intermittent leak rather than trusting only the more favorable result.
How Fake-IP takes over domain resolution
In the mihomo core, enhanced-mode: fake-ip returns a reserved address for ordinary domains and maintains a domain-to-Fake-IP mapping in the core. When an application connects to that reserved address, the core can recover the original domain, then apply domain rules, select a policy group, and resolve the actual destination. The commonly used default address pool is 198.18.0.1/16, which comes from the range reserved for network benchmark testing and should not be used as a public destination.
The value of Fake-IP is that it preserves domain information through the connection stage. Compared with returning a real IP directly to the application, it makes it easier for DOMAIN, DOMAIN-SUFFIX, GeoSite, and other rules to match consistently. It also reduces rule mismatches caused when an application obtains a real address on its own before opening a connection.
A DNS configuration to use as a starting point
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter-mode: blacklist
fake-ip-filter:
- "*.lan"
- "*.local"
- "localhost.ptlogin2.qq.com"
- "+.stun.*.*"
- "+.stun.*.*.*"
default-nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver:
- https://dns.alidns.com/dns-query
- https://1.1.1.1/dns-query
proxy-server-nameserver:
- https://223.5.5.5/dns-query
- https://1.1.1.1/dns-query
The example listens on port 1053 to avoid directly occupying the system's commonly used port 53. When taking over system DNS, TUN's dns-hijack typically redirects port 53 queries to the core instead of requiring an ordinary user process to listen on a privileged port.
default-nameserver handles bootstrap resolution
default-nameserver is mainly used to resolve the hostnames of upstream servers such as DoH and DoT endpoints. For example, if nameserver is set to https://dns.alidns.com/dns-query, the core must first resolve dns.alidns.com to an IP before it can establish the HTTPS connection. Prefer directly reachable IP addresses here to avoid the circular dependency of needing DNS to resolve the DNS server.
It is not the primary resolver list for all domain traffic, nor is it the same as the DNS setting on the system network adapter. Adding a dozen addresses to default-nameserver does not automatically improve reliability; it only expands the test variables. In most cases, two stable and directly reachable addresses are enough.
nameserver handles primary domain queries
nameserver contains the main upstream resolvers for ordinary queries. You can use UDP DNS, DoH, or DoT. To reduce the chance of the local network reading plaintext queries on port 53, a common choice is a DoH endpoint such as https://1.1.1.1/dns-query. Encryption protects transmission between the client and DNS service, but it does not mean every domain should use the same upstream or that requests will necessarily go through the proxy.
If DNS connections need to follow rules, versions of mihomo that support the relevant field can use respect-rules: true. You should also configure proxy-server-nameserver to resolve proxy node hostnames; otherwise, the node hostname itself may enter a resolution loop.
Use nameserver-policy for precise routing
When specific domains need designated resolvers, use nameserver-policy. It works well for internal domains, LAN services, or regional sites that require particular results, and is easier to verify than sending every request to multiple parallel upstreams.
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- https://1.1.1.1/dns-query
nameserver-policy:
"geosite:cn":
- https://dns.alidns.com/dns-query
"+.internal.example":
- 192.168.1.1
The final entry should be used only when internal domains genuinely require it. If 192.168.1.1 is your home router, querying it means that those requests use the local network. That is an explicit policy choice, not an accidental leak.
Which domains should fake-ip-filter exclude?
Not every domain is suitable for Fake-IP. LAN discovery, device casting, some STUN probes, operating-system connectivity checks, and a few applications that require real addresses may need exceptions. fake-ip-filter makes matching entries use real resolution; it does not disable Fake-IP mode altogether.
Start with the smallest exception set
*.lan,*.local: commonly used for local devices and LAN services.- Router administration domains: add them only when actually needed; do not copy vendor domains unrelated to your device.
- If voice, video, or online-play features fail, add rules for the STUN domains found in the logs.
- If an application works only after filtering a domain, record that specific domain instead of excluding the entire top-level domain.
An overly broad filter weakens Fake-IP's domain mapping. For example, adding *.com directly makes a large number of sites return real IPs and makes domain-rule matching harder to trace. Add one entry at a time, recording the symptom, logged domain, and retest result so obsolete exceptions can be removed later.
Key TUN mode and DNS hijacking settings
The system proxy mainly affects programs that honor HTTP or SOCKS proxy settings. Many games, command-line tools, background services, and applications with their own network stacks do not read the system proxy, so enabling it alone cannot ensure their DNS enters Clash. TUN mode captures IP traffic through a virtual network adapter and is better suited to verifying the DNS path for the entire device.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
strict-route: true
dns-hijack:
- any:53
- tcp://any:53
any:53 captures conventional DNS queries on port 53, while tcp://any:53 also covers TCP DNS. auto-route adds routes automatically, and auto-detect-interface identifies the default exit interface. strict-route can reduce the chance of queries bypassing TUN, but may affect existing routes in virtual machines, corporate VPNs, LAN sharing, and multi-adapter environments, so verify each setting individually.
A check sequence in the client
- Open the “Configuration” page and confirm that the active configuration loaded successfully without YAML parsing errors.
- Go to “Settings” → “Network” → “TUN Mode”, enable TUN, and grant network or administrator permissions when prompted.
- Open “Settings” → “Preferences” and confirm that the intended core and configuration are selected, rather than a previously cached copy.
- Open “Logs”, temporarily set the level to Debug, and search for
dns,fake-ip, or the test domain. - After testing, restore the log level to Info to avoid recording large amounts of debug data over time.
Menu labels may differ slightly between client versions, but the checks are the same: the active configuration, core DNS, TUN switch, route capture, and logging must all belong to the same running instance. If another Clash client is still in the system tray, both processes may modify the proxy, ports, and routes at the same time.
Common leak causes and fixes
System proxy enabled, TUN disabled
Browser connections may use the proxy while system resolution still goes to the network adapter's DNS. Fix this by enabling TUN and DNS hijacking, or explicitly pointing system DNS to the client's listening address. For full-device capture, the former is usually easier to manage consistently.
The browser enabled DoH on its own
The browser may connect directly to its selected DoH service, bypassing Clash's domain routing. First disable Secure DNS for comparison. If the test returns to normal, decide whether the browser should follow the system resolver or whether rules should explicitly capture that DoH connection. Do not infer the behavior of every application from one browser's result.
nameserver uses plaintext UDP directly
If nameserver contains only IPs such as 8.8.8.8 or 1.1.1.1, queries usually leave over UDP 53. TUN routing may still handle them, but the transport is not encrypted DNS. To reduce local network visibility, switch to the corresponding DoH endpoint and confirm in the logs which policy the HTTPS connection actually uses.
The node hostname enters a resolution loop
If a proxy node address is a hostname, the core must resolve it before establishing the proxy. If that lookup is itself required to use a proxy that has not yet been established, a loop results. The usual symptom is a configuration that loads successfully while every node times out. Set proxy-server-nameserver specifically for node hostnames and ensure those resolvers are reachable before the proxy comes up.
IPv6 queries or connections take another path
Setting ipv6: false only affects whether the core DNS returns AAAA records; it does not necessarily disable all IPv6 traffic on the operating system. If the local network provides IPv6 while TUN routes cover only IPv4, applications may switch to IPv6. During testing, check IPv4 and IPv6 addresses along with DNS results. Temporarily disabling IPv6 on the network adapter can provide a comparison, but the final fix should cover IPv6 in TUN and routing.
Old caches create a false impression
The system, browser, application, and mihomo core may all cache resolution results. Refreshing an old page immediately after changing the configuration may not trigger a new query. Clear system caches, restart the browser, and use a random subdomain or the extended mode on a testing site to trigger fresh resolution.
Complete post-fix verification checklist
During verification, do not look only at whether a webpage opens. A successful connection proves only that at least one path works; it does not prove that every DNS query follows the intended route. Run the checks below in order and record the result of each step.
- Check configuration loading: Logs contain no errors related to
yaml,parse, ordns config. - Check the listening port: Confirm that
1053in the example, or the port in your actual configuration, is being served by the current core and is not occupied by another process. - Check Fake-IP: Queries for ordinary domains should return values in the
198.18.0.0/16range; domains in the filter list should return real addresses. - Check rule matches: On the connections or logs page, inspect the rule and policy group used by the test domain and confirm that it has not unexpectedly fallen through to DIRECT.
- Run an extended test: Run it twice in succession; the results should no longer include the local ISP resolvers recorded during the baseline.
- Retest with browser settings changed: Test once with Secure DNS enabled and once with the browser following the system resolver to identify the source of any difference.
- Test a non-browser application: Start a connection with a command-line tool or another application to confirm that TUN capture is not effective only for the browser.
- Retest after restarting: Restart the client and system to confirm that TUN, DNS, and configuration selection recover as expected.
nslookup example.com 127.0.0.1
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA
Adjust the address and port in commands to match the actual listening value. If the client listens only on 127.0.0.1:1053, do not omit -p 1053. In Fake-IP mode, an A record returning 198.18.x.x is usually normal; it is not the target site's real public IP address.
A safer order for making changes
For troubleshooting, follow this order: establish a baseline, unify traffic capture, minimize exceptions, then verify the logs. Start with two clearly defined nameservers, enable Fake-IP and TUN DNS hijacking, and stabilize the basic path. Only then add nameserver-policy, LAN resolution, and application compatibility entries.
Do not copy a large DNS configuration all at once. The more fields it contains, the harder the resolution path is to explain. For most personal devices, being able to explain each upstream's purpose, the source of every exception, and whether each query uses the proxy matters more than stacking numerous resolvers. After editing, repeat the test with the same site, browser state, and network before deciding that the leak is truly fixed.