First, define what counts as a DNS leak
When a browser visits a domain, it must first resolve that domain to an IP address. Routing the proxy connection through Clash does not guarantee that DNS queries follow the same path. If Windows still sends UDP 53 or TCP 53 queries to a resolver provided by your broadband connection, workplace network, or public Wi-Fi, the network provider can see which domains were queried. This is the most common DNS leak found during troubleshooting.
Seeing a local ISP in the results does not automatically mean the configuration is wrong. Rule mode may intentionally use a local resolver for domains in mainland China and another resolver group for domains outside China, so a test page may show multiple DNS exits. The key questions are whether domains that should use the proxy are still queried directly through the physical network adapter, and whether the DNS exit remains on the local network after switching nodes.
Common leak paths
- Only “System Proxy” is enabled, so browser traffic enters Clash while other applications continue using the system DNS.
- The profile enables
dns.enable, but the Windows network adapter does not send queries to Clash’s listening port. - TUN is enabled, but
dns-hijackis missing, allowing applications’ UDP 53 queries to bypass the core. - With
redir-host, the system or application keeps its own resolution path, so the local resolver and Clash DNS operate at the same time. - The encrypted DNS hostname must itself be resolved first, but no usable
default-nameserveris available, creating a resolution dependency during startup. - The browser has its own Secure DNS enabled, sending queries directly to its configured DoH service instead of following the expected Clash rules.
Run three rounds of comparison tests with an online DNS checker
Online DNS tests are useful for quickly confirming symptoms, but one result is not enough to draw a conclusion. Browser and system DNS caches, along with the test site’s database of node locations, can affect what is shown. Use the same browser and test page for three consecutive rounds, recording the proxy exit IP, number of DNS servers, provider names, and regions.
- Fully exit Clash, wait 30 seconds, then run a standard test and record the DNS baseline for the local network.
- Start Clash, enable only the system proxy, choose a node in a region different from the local network, and run another complete test.
- Keep the same node, enable TUN and DNS hijacking, clear the caches, then run a third test and compare the changes.
Clear the Windows DNS and browser caches
Open PowerShell or Command Prompt as an administrator and run the following command to clear the Windows DNS cache:
ipconfig /flushdns
Chromium-based browsers may also retain their own host cache and connection pools. Closing every browser window and reopening the browser is usually the simplest approach. Do not run another VPN, game accelerator, virtual machine network, or corporate security client during testing, or another network component may take control of DNS.
| Test result | Possible cause | Next step |
|---|---|---|
| Only the local ISP’s DNS is shown | Clash DNS is not taking control, or the browser is still using the system resolver | Check TUN, dns-hijack, and system proxy status |
| Both local and remote DNS are shown | Rule-based routing, cached results, or multiple resolution paths are active | Clear the cache, then capture port 53 traffic |
| DNS remains unchanged after switching nodes | The resolver connects directly by design, or the configuration intentionally uses fixed DoH | Confirm that DNS requests follow the proxy rules |
| The test looks clean, but an individual app still leaks | The app uses its own DNS or bypasses the system proxy | Switch to TUN and enable DNS hijacking |
Check for direct DNS connections locally on Windows
Windows includes pktmon, which can quickly check for cleartext port 53 requests. No additional tools are required, making it useful for confirming whether packets still leave through the physical network adapter before and after enabling TUN. First stop any active capture, then open PowerShell as an administrator.
pktmon stop
pktmon filter remove
pktmon filter add DNS -p 53
pktmon start --etw -m real-time
Leave the window running, open several websites you have not visited before, and watch the destination addresses and network adapters. When finished, press Ctrl+C, then run:
pktmon stop
pktmon filter remove
If the destination is a router address such as 192.168.1.1:53, or a public DNS server assigned by your broadband provider, and the packets come from a physical Wi-Fi or Ethernet adapter, cleartext queries are still bypassing Clash. A few requests seen only when Clash starts may be bootstrap lookups for encrypted DNS hostnames; if they continue while browsing, keep adjusting the configuration.
Check which resolvers the system is currently using
The PowerShell command below lists DNS addresses for every network adapter. Focus on the Wi-Fi or Ethernet adapter currently online, as well as virtual adapters such as Clash, Wintun, and Mihomo:
Get-DnsClientServerAddress |
Where-Object {$_.ServerAddresses.Count -gt 0} |
Format-Table InterfaceAlias, AddressFamily, ServerAddresses -AutoSize
nslookup is better for establishing the system DNS baseline than for proving that a browser is leaking. It usually calls the resolver configured by the system and may not reproduce requests sent through SOCKS, an HTTP proxy, or the browser’s own DoH. During troubleshooting, review the nslookup output together with pktmon and the Clash logs.
Tune nameserver, fallback, and fake-ip settings
The goal of DNS configuration is not to pile up server addresses, but to define three things: which resolver Clash uses for ordinary domains, which resolver performs the initial lookup for encrypted DNS endpoints, and how results are handed to the rule engine. The basic example below is intended for checking the structure; keep indentation consistent when using YAML.
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query
fallback:
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
- "+.stun.*.*"
- "+.stun.*.*.*"
default-nameserver: for bootstrap lookups only
default-nameserver normally contains directly reachable IP addresses used to resolve the DoH server itself. For example, the system must know the IP address of dns.alidns.com before it can establish an HTTPS connection. Do not use hostnames here or add a large list of addresses. Two stable IP resolvers are enough for failover.
nameserver and fallback: define the routing purpose
nameserver is the primary resolver, while fallback is the backup resolver in classic Clash configurations. With fallback-filter, the core selects a result set based on conditions such as GeoIP data and returned address ranges. Clash Meta and mihomo versions differ in their DNS policy extensions; when using a subscription with overrides, also confirm that the client preserves the local DNS section.
DoH encrypts DNS content, but does not automatically ensure that its connection uses the proxy. If the remote resolver should connect according to proxy rules, use a recent mihomo core that supports respect-rules, proxy-server-nameserver, and nameserver-policy. Prepare a separate resolver for the proxy server’s hostname first to avoid the circular dependency of needing the proxy to resolve the proxy server.
fake-ip: send domains through the rule engine first
In fake-ip mode, applications first receive mapped addresses from the 198.18.0.0/16 range. When an application opens the connection, Clash restores the original domain and applies the rules. This reduces cases where an app resolves a domain itself and submits only the destination IP, making rule routing and DNS interception more reliable. This range is reserved for benchmark networks and should not conflict with an actual home or corporate subnet.
Local device discovery, printers, online gaming, STUN, and some login domains may not work well with fake-ip and should be added to fake-ip-filter. Do not copy hundreds of unverified rules into the filter list. Each entry makes that domain use real-IP resolution instead. If local devices cannot be found or an app gets stuck in a login loop, add the specific domain from the logs for easier maintenance.
Use TUN and DNS hijacking to cover apps that ignore the proxy
The system proxy affects only programs that honor Windows proxy settings. Command-line tools, games, Store apps, and some launchers may open connections directly, so System Proxy alone rarely provides complete DNS control. TUN creates a virtual network adapter to process traffic at the IP layer, while dns-hijack captures port 53 queries sent by applications.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
strict-route: true
dns-hijack:
- any:53
In Clash for Windows 0.20.39, go to “General” → “Service Mode” to install service mode, then open “General” → “TUN Mode”. The active profile is available under “Profiles”; use the “Edit” context-menu item to inspect its DNS section. Menu names vary between mihomo GUI clients, but verify all three items: core permissions, the TUN switch, and DNS hijacking.
On Windows, strict-route: true helps restrict bypass paths such as multi-homed DNS, but it can change routing for corporate VPNs, Hyper-V, WSL, virtual machine bridges, and LAN sharing. If printers or NAS devices become unreachable, check the routing table and Clash logs after enabling it; do not immediately send every private address through the proxy.
IPv6 must be evaluated in the same way
dns.ipv6: false means Clash DNS does not return AAAA records, which is suitable when the proxy node or current network lacks stable IPv6. If the local network and proxy node both support IPv6, change it to true, but confirm that TUN, routing, and rules can handle IPv6. Disabling AAAA responses in DNS does not disable IPv6 at the system level.
Retest in a fixed order to isolate remaining issues
After making changes, do not switch multiple nodes, modes, and browsers at once. Keep one node fixed, reload the configuration, and repeat the tests in a consistent order so you can identify which change made the difference.
- Check the client logs to confirm that the YAML loaded successfully, with no indentation, field, or resolver-address errors.
- Confirm that
dns.enableistruein the active configuration and that listening port1053is not occupied by another program. - Enable TUN and
dns-hijack, then runipconfig /flushdns. - Close and reopen the browser, then visit three domains you have not opened before.
- Run a complete online test and record the DNS count, region, and provider.
- At the same time, use
pktmonto check whether the physical adapter is still sending UDP 53 or TCP 53 traffic outward. - Test once more in both rule mode and global mode. If local DNS appears only in rule mode, inspect the DNS policy and direct-connection rules.
Local DNS still appears in the test results
- Check the browser’s Secure DNS settings. During troubleshooting, temporarily disable the browser’s own DoH so queries enter the system and TUN consistently, then decide whether to restore it.
- Check whether Windows has other VPN virtual adapters installed. When two TUN drivers run at the same time, route priority may change with the startup order.
- Check whether a subscription update overwrote the DNS section. The interface showing TUN as enabled does not mean the currently loaded configuration still contains the expected settings.
- Look for repeated DNS timeout, connection refused, or no such host errors in the logs. After a timeout, an app may fall back to its own resolution path.
- Confirm that the firewall allows Clash or the mihomo core to establish TCP 443 connections to the DoH service.
Websites no longer open, but the leak is gone
This usually means DNS is being intercepted but Clash cannot resolve through its upstream server; it is not a normal sign that testing succeeded. First check that default-nameserver contains only IP addresses, then confirm that the DoH endpoint is reachable. If the proxy server uses a hostname, also provide a directly reachable bootstrap resolution path. Once connectivity is restored, add fallback, policy-based resolution, and filter entries gradually instead of enabling every advanced field at once.