How to Detect Clash DNS Leaks: Browser Tests, Log Analysis, and Leak Prevention
Use test results, system resolution paths, and client logs to configure fake-ip, remote resolution, and fallback behavior step by step.
First, define what counts as a DNS leak
When you visit a website, the application typically sends the domain name to a DNS resolver first, then uses the returned IP address to establish a connection. A proxied connection has passed through Clash, but that does not mean the domain lookup followed the same path. The system may still send requests to the router, an ISP resolver, or an internal DNS server on a corporate network. The website traffic then travels through the proxy while the domain lookup leaves through the local network. That is the key behavior to investigate when troubleshooting Clash DNS leaks.
Do not judge the result solely by whether the test page lists multiple DNS servers. Public DNS services use anycast, forwarding clusters, and different egress points, so the server addresses shown by a test site may not match the addresses in your configuration. Multiple results may also belong to the same DNS provider. A more reliable approach is to compare the resolver's network owner and geographic location with Clash logs captured during testing and the actual 53, 853, or HTTPS requests sent by the device.
You must also distinguish DNS leaks from WebRTC address exposure and proxy egress changes. A WebRTC test may show a LAN address or a public candidate address, but that belongs to the browser's real-time communication path and does not mean DNS queries bypassed the proxy. If an egress test shows your local public IP, check proxy mode, rule matching, and UDP handling first rather than changing DNS immediately. These three issues require separate evidence.
Common signs of a leak
- After enabling the proxy, the DNS test page still shows resolvers operated by your home broadband or mobile carrier.
- After switching to a proxy node in another region, DNS queries continue to leave directly through the local network.
- Clash logs show the website connection but no corresponding domain entering the built-in DNS module.
- Browser and command-line tests produce different results, meaning one application is bypassing the intended resolution path.
- Web traffic works in system proxy mode, but a packet capture still shows UDP 53 requests sent to the router.
Run browser tests, command-line queries, and packet captures in layers
A browser-based DNS test is a useful starting point. These pages usually generate a batch of random subdomains, forcing the browser to make fresh queries while the authoritative DNS server records the recursive resolvers involved. Before testing, close other applications that are using the network, clear the operating system and browser DNS caches, and use a new private window. A cache hit can skip the lookup and make the results look cleaner than they really are.
After running both the standard and extended tests, record the resolver IPs, network operators, and countries or regions. The expected result depends on your configuration goal. If Clash uses a designated remote DoH service, the results should correspond to that service's recursive egress. If domain rules send domains in mainland China to a local encrypted resolver and other domains to a remote resolver, the test may show two groups of services. The key is whether each group matches an intentional configuration, not whether the page shows only one address.
Use the command line to distinguish system DNS from a specified resolver
The browser may have Secure DNS enabled, so you should also test the operating system's resolution path. On Windows, use nslookup or PowerShell's Resolve-DnsName; on macOS and Linux, use dig. First query a domain you have not visited before, then inspect the server address in the command output. If it shows your home router's address, such as the LAN gateway, the system is still handing the query to the router. This does not by itself prove that the query ultimately leaked, but it shows that Clash has not yet become the direct DNS entry point for that command.
nslookup example.net
Resolve-DnsName example.net
dig example.net
dig @127.0.0.1 -p 1053 example.net
Finally, explicitly query the local listening port used by Clash or mihomo and compare it with the system's default lookup. If the explicit query behaves as expected but the default query still goes to the router, the problem lies with the system DNS target or TUN DNS hijacking. If both queries reach an unexpected resolver, continue checking the kernel configuration and upstream DNS.
Capture ports and destination addresses
To determine whether the device is sending traditional DNS directly to the LAN or the public internet, capture UDP/TCP 53 traffic during the test window. On Linux, use tcpdump; on Windows, use the built-in network tracing tools; on macOS, you can also run tcpdump on the active interface. Replace the interface name according to your actual environment.
sudo tcpdump -ni any 'port 53 or port 853'
sudo tcpdump -ni en0 'udp port 53 or tcp port 53'
A packet capture showing port 53 requests sent to the router or an ISP DNS server is strong evidence that direct resolution is still occurring. The absence of port 53 traffic does not end the investigation, because an application may use DoH and encapsulate DNS in HTTPS on port 443. In that case, correlate Clash connection logs with the browser's Secure DNS settings and the destination address.
Trace the path through the system, Clash kernel, and upstream resolver
A DNS path can be divided into three points: who receives the application's query, whether Clash receives it, and which network path Clash uses to reach the upstream resolver. Confirming these questions separately is more effective than repeatedly swapping public DNS addresses.
Stage one: from the application to the system or browser resolver
Most desktop applications call the operating system's resolver, but browsers may enable independent DoH, and some command-line programs can query a specified server directly. A system proxy only sets an HTTP, HTTPS, or SOCKS proxy address; it usually does not rewrite every system DNS lookup. In a system-proxy setup, the browser commonly resolves the destination locally before handing it to the proxy.
If only the browser test is abnormal, check the browser's Secure DNS first. You can turn it off and let the system and Clash manage resolution, or explicitly set it to a DoH service consistent with your Clash setup. If multiple applications generate local DNS requests, prioritize checking the operating system DNS settings, TUN interception, and the client's DNS switch.
Stage two: determine whether the query enters Clash's built-in DNS
Confirm that dns.enable is enabled in the configuration, and check that the local listening address matches the one shown in the client interface. Some graphical clients generate a runtime configuration from their interface, so DNS fields in the subscription file may be overwritten. During troubleshooting, inspect the configuration actually loaded by the kernel rather than only the original subscription text.
Temporarily set the log level to debug, clear the logs, and query a random subdomain. Log formats vary across Clash branches and clients, but look for DNS queries, rule matches, upstream failures, timeouts, and fallback selections. If the domain is completely absent from the logs, the request has not entered the kernel. If the domain appears but the upstream request uses a direct connection, check the dialing path for the DNS upstream.
Stage three: the connection from Clash to upstream DNS
Even when a query enters the built-in DNS, upstream DoH or DoT may still be reached through DIRECT. Encryption protects the query's integrity and limits its visibility in transit, but the upstream connection still reveals the resolver's destination address. If the goal is to send remote DNS connections through the proxy policy, use the proxy-routing method supported by the current kernel, or enable rule-based upstream DNS connections and provide a separate bootstrap resolver for the proxy server's domain.
If the proxy node itself is specified by hostname, the kernel must resolve the node's IP address before it can establish the proxy tunnel. This startup dependency cannot recursively require a proxy connection that does not exist yet. In mihomo, proxy-server-nameserver handles proxy server hostname resolution, while default-nameserver handles foundational tasks such as resolving the hostnames of DoH upstreams. Their responsibilities are different.
Consolidate queries with fake-ip, remote resolution, and fallback policies
In the mihomo kernel, which supports Clash Meta configuration, fake-ip is a commonly used enhanced resolution mode. When an application queries a domain, the built-in DNS first returns a mapped address from a reserved pool. When the application connects to that address, the kernel restores the original domain from the mapping, then applies rule matching and selects the proxy. This reduces the chance that an application obtains the real IP locally in advance and makes domain-based traffic splitting more practical.
The following is a basic snippet for understanding how the fields relate. The public resolver endpoints are structural examples only; in deployment, choose services based on reachability from your network, their terms of service, and your privacy requirements. Different clients may bundle different mihomo versions and support different syntax, so check the documentation for the current kernel and preserve the original configuration before editing.
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter-mode: blacklist
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
- "time.*.com"
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://dns.alidns.com/dns-query
respect-rules: true
listen determines where the built-in DNS listens. When it is intended for local use only, apply the access restrictions supported by the client. In TUN mode, the client usually manages the listener and hijacking automatically. fake-ip-range uses a dedicated address range for domain mappings and must not overlap with the local LAN, container networks, or corporate routing.
fake-ip-filter excludes domains that are unsuitable for fake-ip. LAN device discovery, time synchronization, some game platforms, and services that depend on real local addresses may need the real IP returned. Add exclusions one at a time based on actual failures. Placing broad domain ranges in the filter list sends many requests back through real-IP resolution and weakens fake-ip's ability to consolidate the resolution path.
respect-rules makes upstream DNS connections follow the rules, but after enabling it you must ensure that proxy server hostnames can be resolved through proxy-server-nameserver. Otherwise, the kernel may wait for DNS to establish the proxy while DNS waits for the proxy, creating a circular dependency. Older Clash versions and some unmaintained branches may not have a field with the same name, so follow the capabilities of the actual kernel.
Use nameserver-policy for precise domain resolution
When different domains need different resolution paths, use nameserver-policy. It generally takes precedence over the general nameserver setting and is useful for assigning resolvers to internal domains, specific rule sets, or regional domains. An overly broad policy can make the test page show multiple recursive egress points, so every rule should have a clear purpose.
dns:
nameserver-policy:
"geosite:cn":
- https://dns.alidns.com/dns-query
"+.internal.example":
- 192.168.10.1
nameserver:
- https://1.1.1.1/dns-query
When internal domains are sent to a corporate or home DNS server, those requests enter the local network. This is intentional split resolution and should not be confused with an accidental leak. However, avoid letting wildcard rules cover ordinary public domains, and confirm that the internal resolver is used only on trusted networks.
Understand fallback instead of copying templates mechanically
Some configurations use fallback and fallback-filter. The kernel can query the primary and fallback resolvers concurrently, then choose a result based on geographic IP data, domain categories, or reserved addresses. This mechanism is mainly for handling DNS poisoning, incorrect results, or availability differences between networks; it does not inherently ensure that DNS queries travel through the proxy.
dns:
nameserver:
- https://dns.alidns.com/dns-query
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
geoip-code: CN
geosite:
- gfw
If both primary and fallback resolvers connect directly from the local network, testing may still reveal an unwanted path. When configuring fallback, also verify how upstream connections are routed, whether remote endpoints are stable, and whether the rule set loads correctly. Modern mihomo configurations can use nameserver-policy for clearer domain-level selection, so whether to retain fallback should depend on the use case.
TUN mode must address both DNS hijacking and application bypasses
System proxy settings mainly affect applications that honor proxy configuration. Games, system services, some command-line programs, and software that creates its own connections may ignore them. TUN mode uses a virtual network interface to capture a broader range of IP traffic, making it better suited to handling UDP, proxy-unaware applications, and system DNS consistently. It also depends on administrator privileges, routing settings, and the platform network stack.
mihomo TUN configurations typically include auto-route and DNS hijacking. The exact fields vary by version and client packaging; a typical structure looks like this:
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
dns-hijack sends traditional port 53 queries passing through TUN into the built-in DNS. After enabling it, capture traffic again to confirm that requests are not still leaving directly from the physical network adapter to the router. Security software, virtual machines, containers, VPNs, or corporate network clients on some platforms may install higher-priority routes or filtering drivers, causing some traffic to bypass TUN. Check the routing table, interface priorities, and interface selection in the client logs.
DNS hijacking usually targets traditional UDP/TCP 53. A browser's built-in DoH uses HTTPS on port 443 and cannot be captured by hijacking port 53 alone. If the browser's Secure DNS points to an independent service, it may connect through DIRECT or follow ordinary connection rules. There are two ways to handle this: disable independent browser resolution so requests enter the system and Clash together, or keep browser DoH enabled and create an explicit proxy rule for its endpoint. When mixing both approaches, document each path to avoid mistaking browser test results for a failed kernel DNS setup.
Include IPv6 in testing
When the local network supports IPv6, an application may prioritize AAAA queries and establish an IPv6 connection directly. Checking only the IPv4 egress and A records can miss this path. If the proxy node, rules, and TUN fully support IPv6, keep IPv6 enabled in DNS and test A and AAAA queries along with dual-stack egress separately. If the current proxy chain does not support IPv6, handle it consistently at the kernel, system-interface, and routing layers rather than deleting one DNS record while leaving a directly reachable IPv6 route.
Retest after changes using a fixed checklist
To verify that leak prevention works, generate fresh queries after clearing caches. Merely refreshing an open page may continue using cached results from the browser, system, or Clash. Restart the client kernel, clear the system DNS cache, close old browser processes, and begin with a random subdomain.
- Confirm that the kernel configuration is active: Inspect the client's runtime configuration and startup logs to ensure that DNS, fake-ip, and TUN loaded without errors.
- Check the proxy egress: Test the browser separately from applications that do not follow the system proxy, and confirm that connections follow the rules into DIRECT or the intended policy group.
- Run a browser DNS test: Record the network ownership of each recursive resolver and compare it with the nameserver, policy resolution, and browser DoH settings.
- Run system command-line queries: Compare the default resolution result with a direct query to Clash's local port and confirm that the system entry point is unified.
- Review kernel logs: Trigger a lookup with a new domain and confirm that the query enters the DNS module, the upstream request succeeds, and the rules and proxy chain behave as expected.
- Capture traffic on the physical interface: Check for unexpected port 53 or 853 requests sent to the router or public servers.
- Test dual-stack operation and failover: Check IPv4 and IPv6 separately, then temporarily disable one upstream to confirm that fallback does not switch to an unplanned local resolver.
Common failures and what to check
| Symptom | Check first | Recommended action |
|---|---|---|
| The browser shows a local resolver, but the command line is normal | Browser Secure DNS, extensions, and cache | Hand resolution to the system, or explicitly proxy the browser's DoH |
| System queries go to the router, but direct queries to the local port work | System DNS addresses, TUN, and dns-hijack | Correct the system entry point or enable effective DNS hijacking |
| The node cannot connect after enabling respect-rules | Proxy server hostname resolution | Configure proxy-server-nameserver to remove the startup dependency |
| LAN devices stop working after enabling fake-ip | fake-ip-filter and local address ranges | Add exclusions only for the affected LAN domains |
| The test shows two unexpected groups of resolvers | fallback, nameserver-policy, and browser DoH | Disable them one at a time and use the logs to confirm the actual selection |
| Only IPv6 shows a local egress | AAAA resolution, TUN IPv6 routing, and node capabilities | Capture both stacks consistently, or disable IPv6 consistently according to network conditions |
The goal is not to make the test page show a particular country or a fixed number of DNS addresses. It is to make the resolution path match the configuration: application queries enter the intended endpoint, Clash selects an upstream according to the rules, upstream connections follow the planned DIRECT or proxy policy, and neither fallback nor IPv6 bypasses that design. DNS leak troubleshooting is complete only when all four stages can be cross-validated through logs, command-line queries, and packet captures.
Continue with installation and configuration
Choose the Clash client that matches your operating system and processor architecture, then follow the quick start guide to import a subscription and configure proxy modes and DNS.