How to Check for DNS Leaks in Clash: Read Test Results and Configure fake-ip and nameserver-policy
Learn what DNS leak test results mean, compare fake-ip and redir-host, and configure nameserver, fallback, and nameserver-policy to control DNS routing.
1. What Counts as a DNS Leak?
Seeing your proxy exit IP in the browser does not mean DNS lookups follow the same route. A visit involves at least two kinds of requests: DNS queries that resolve the domain, and traffic that connects to the destination server. Clash system proxy settings, TUN interception, the core's DNS module, and browser Secure DNS each affect a different stage. Troubleshoot them separately.
Here, a “DNS leak” means a query that should go to a specified resolver or follow a specified proxy route instead reaches an unexpected resolver. For example, if domains for websites outside mainland China are meant to be resolved through the proxy, but tests consistently show a local ISP's recursive DNS, that warrants investigation. If your configuration intentionally sends local domains to your ISP's resolver, seeing it in the results is expected.
Define what you expect before checking the results: Which domains may be resolved locally? Which must use a proxy? Can the browser use DoH on its own? Without clear answers, seeing resolvers in multiple countries is not enough to identify a leak.
What a DNS Leak Test Can Show
| Test item | What it can tell you | What it cannot prove on its own |
|---|---|---|
| Public IP shown by the test site | The address seen by the site for your current connection | That every app on your system uses the proxy |
| DNS server IP | The recursive resolver's public-facing address as seen by the authoritative server for the test domain | That your device connects directly to this address for DNS |
| Country and ISP | A location estimate from an IP geolocation database | Every network hop taken by the DNS query |
| Multiple resolvers detected | Queries may be sent in parallel, or there may be multiple upstreams or cluster egress points | That a result count greater than one always means a leak |
Public DNS services commonly use Anycast and distributed recursive resolver clusters. Your device connects to a service address, while the test may report a different recursive resolver's egress IP; country labels can also be out of date. So a proxy exit in Japan and a DNS result labeled as the United States are not, by themselves, proof of a leak. Check the resolver provider, configured upstreams, and connection logs together.
2. Retest Consistently to Isolate System and Browser DNS
Record the core name and version, client version, enabled configuration, proxy mode, system proxy status, and TUN status. The examples below are for mihomo; older Clash cores may not support every field. Settings can move between sections in different Clash Nyanpasu versions. If you cannot find an option, inspect the effective configuration rather than relying on the original subscription file.
- Establish a baseline: On a network where direct testing is acceptable, turn off the system proxy and TUN, run a DNS test, and record the public IP, resolver IP, and provider. Skip the direct-connection baseline if you have strict DNS privacy requirements.
- Enable only the system proxy: Keep the browser settings unchanged and test again. The system proxy mainly covers apps that honor proxy settings; it does not automatically capture system UDP port 53 queries.
- Enable TUN and DNS hijacking: Make sure the core starts successfully, then run the test again. If the results change only at this stage, first investigate DNS traffic that was not reaching the core before.
- Temporarily standardize browser DNS: Note the original setting, then temporarily turn off browser Secure DNS and test again. In Chrome, look under Settings → Privacy and security → Security for “Use secure DNS.” Your organization may lock this setting through policy.
- Run two rounds: Trigger a fresh test each time instead of just refreshing an old results page. If needed, clear the cache and restart the browser so cached DNS results are not mistaken for the current route.
Browser DoH resolves domain names over HTTPS. It may bypass mihomo's DNS module, while its HTTPS connection can still be handled by the proxy or TUN. “Bypassing the core's DNS” and “sending queries directly to the local ISP” are not the same thing; check each separately.
Check Whether the Core's DNS Is Responding
Assuming the core's DNS listener is at 127.0.0.1:1053, use the commands below to query it directly. On Windows, run the PowerShell cache-clearing command with the required system permissions. On systems with dig installed, use the second command to query. example.com is a diagnostic domain, not a proxy node.
# Windows PowerShell: clear the system DNS cache
Clear-DnsClientCache
# macOS / Linux with dig installed: query the core's DNS directly
dig @127.0.0.1 -p 1053 example.com A
# Query IPv6 records as well and compare the results
dig @127.0.0.1 -p 1053 example.com AAAA
In fake-ip mode, a standard A query may return an address in the 198.18.0.0/16 range. This is usually a normal mapping, not DNS poisoning. The response may differ for domains covered by fake-ip exclusion rules, special domain handling, or cached results. A successful command only confirms that the listener is reachable; it does not prove that the browser or system's default DNS queries use it.
3. fake-ip vs. redir-host: The Difference Is When Resolution Happens
| Mode | Address returned to the app | What to check |
|---|---|---|
| fake-ip | A regular query returns a virtual address, and the core maintains a domain-to-address mapping | Subsequent connections must pass back through the core; keep the exclusion list short |
| redir-host | Usually returns the real address obtained from the upstream resolver | Upstream resolution quality, domain associations, and IP rule matches |
With fake-ip, the core uses a virtual address to recover the domain when it receives an app connection, then applies the rules to choose an egress route. For connections where a remote proxy resolves the destination, the local device may not need to resolve the destination's real IP first. Direct connections, IP-based rules, and some protocols may still require resolution. fake-ip is not a switch that automatically sends all DNS traffic through the proxy.
redir-host is closer to the traditional flow of resolving a real address. It can work with reliable encrypted upstreams, and using this mode alone does not mean DNS is leaking. Choose a mode based on app compatibility, whether connections are fully intercepted, and your routing rules—not on the mode name as a measure of privacy.
Don't Use Broad Exclusions to Fix One App
If a LAN service, game, or device discovery feature does not work with fake-ip, add the specific domain to fake-ip-filter. Do not start by excluding an entire common public suffix. The broader the exclusions, the more queries return to real-address resolution, which can also change behavior that depended on virtual mappings. After switching modes, restart the affected apps so they do not keep using cached virtual addresses.
4. Configure nameserver, fallback, and DNS Policies
First, understand what each field does: nameserver lists the regular DNS upstreams; nameserver-policy assigns upstreams to matching domains; and fallback works with filtering rules to choose a result. These fields determine which resolver to query, but do not inherently determine which egress route the query uses. Encrypted DNS controls how queries are transmitted; proxy routing controls the connection path. Configure and verify them separately.
Start with a Verifiable DNS Baseline
The following DNS snippet is meant to be merged into your existing configuration; it is not a complete subscription. Using an IP-based DoH URL reduces reliance on bootstrap resolution for the upstream's hostname. If your network cannot connect directly to the listed services, configure a proxy route as needed. Do not mistake a timeout for a YAML parsing error.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
nameserver:
- https://1.1.1.1/dns-query
fake-ip-filter:
- "*.lan"
- "*.local"
default-nameserveris mainly used to resolve the hostnames of DNS upstreams; it does not mean all destination domains are sent to that resolver. Here,223.5.5.5is a plaintext bootstrap resolver. If you also need encrypted bootstrap queries, use an encrypted bootstrap upstream supported by your current core and reachable from your network, then test it.listenbinds only to the loopback address, so this example does not expose a DNS resolver to your LAN. System DNS settings usually cannot specify a custom port such as 1053; interception or local forwarding is required.ipv6: falsecontrols AAAA responses from the core's DNS. It does not disable IPv6 in the operating system or prevent apps from connecting to known IPv6 addresses. IPv6 connections still need to be handled correctly by routing or TUN.
Use nameserver-policy to Separate LAN and Public Domains
Place the following under the same dns object. The example assumes the router's DNS address is 192.168.1.1; check your current network for the actual address. PROXY must exactly match the name of a policy group in your configuration, including capitalization. Replace it with the actual group name before applying the snippet.
nameserver-policy:
"+.lan":
- 192.168.1.1
"+.github.com":
- "https://1.1.1.1/dns-query#PROXY"
+.github.com matches the domain and its subdomains. #PROXY in quotes is mihomo's syntax for specifying the outbound policy for a DNS upstream, so this DoH connection uses the selected policy. If that group is set to DIRECT, the request still connects directly; if the selected node is unavailable, it will time out. Policy-based resolution applies only to the listed domains; it does not automatically cover every public website.
The fake-ip exclusion list and policy-based resolution do different things: the former controls whether a virtual address or a real DNS response is returned, while the latter selects the resolver. If you add *.lan to the exclusion list, make sure the LAN resolver actually knows those records.
fallback Is More Than a Simple Timeout Backup
With fallback configured, the core may send queries in parallel and use fallback-filter to decide which result to keep. Do not assume fallback will never receive a query while the primary resolver is available. The snippet below shows one result-filtering approach that uses GeoIP data; it is not meant to be enabled alongside the minimal configuration above.
fallback:
- https://8.8.8.8/dns-query
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
This example uses GeoIP's CN classification and specified IP ranges to help choose a result. An outdated database or changes in CDN IP ownership can affect the choice. fallback is not a proxy route by default; its HTTPS connections follow the configured outbound routing. If your goal is to limit which resolvers receive queries, start troubleshooting with one clearly defined upstream, then decide whether fallback is necessary.
5. TUN Interception and DNS Egress: Check Both Legs
There are two legs to check: app to core, then core to upstream. Setting dns.enable alone does not make every app use the core's DNS; enabling TUN alone is not enough either—check that DNS hijacking is actually working. The following is a common mihomo TUN snippet. Before enabling it, confirm the client has the required system permissions and that its routes do not conflict with another VPN.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
This covers regular UDP/TCP traffic on port 53 that enters TUN. Browser DoH usually uses HTTPS on port 443, while DoT commonly uses port 853; neither is automatically sent to the core's DNS just because port 53 is hijacked. LAN routes, interface binding, and multi-homed system behavior can also affect interception. Check logs and retest to confirm what is happening.
When DNS Should Follow Routing Rules
mihomo's respect-rules option lets DNS upstream connections follow routing rules. When enabling it, also configure proxy-server-nameserver to provide a separate resolver for proxy node hostnames. This avoids the circular dependency of needing the proxy to resolve a hostname before the proxy can connect.
respect-rules: true
proxy-server-nameserver:
- https://1.1.1.1/dns-query
These two lines also belong under the dns object. The node-hostname resolver in the example must be reachable before the proxy is established. If your network cannot connect to it directly, use an accessible resolver instead and account for the resulting DNS visibility. Do not force every DNS upstream through a proxy group that cannot connect yet.
Keep only one top-level dns key when merging configuration. Do not append multiple sections with the same name. Subscription updates may overwrite manual changes, so use the client's supported override or merge mechanism and check the effective configuration after reloading. The exact menu location varies by client version; see the user guide for instructions.
6. Troubleshoot by Symptom and Run a Final Test
| Symptom | Check first | Next step |
|---|---|---|
| The site shows a proxy IP, but the DNS result still shows a local ISP | System DNS is not intercepted, or bootstrap resolution or a policy is using a direct route | Check TUN, port 53 hijacking, and the outbound route for each upstream |
| Only one browser shows a different resolver | Browser Secure DNS, an extension, or separate proxy settings | Temporarily standardize the settings and run the test again |
| All DNS queries time out after enabling respect-rules | A node hostname resolution loop, an incorrect group name, or an unreachable upstream | First verify that proxy-server-nameserver is reachable |
| LAN domains no longer resolve | Public upstreams do not know internal records | Add a precise policy and any necessary fake-ip exclusions |
| IPv6 connections still appear after disabling IPv6 DNS | App cache, hard-coded addresses, or the system's IPv6 routing | Clear the cache and check how IPv6 traffic is intercepted |
When checking logs, watch for three things around a newly triggered query: whether the core received it, which upstream it selected, and which policy routes the upstream connection. DoH requests typically appear in the connection panel as HTTPS connections to the resolver. A single port 443 connection is not enough to conclude that website traffic is taking the wrong route. If necessary, temporarily increase the log level and restore it after troubleshooting. Before sharing logs, remove subscription URLs, credentials, and private domain names.
- Save the configuration and reload the core. Check for unknown fields, YAML indentation errors, and port conflicts.
- Use
dig @127.0.0.1 -p 1053to verify the listener, then use a real browser to test whether DNS is fully intercepted. - Repeat the DNS test and record results in a regular browser window, another browser, and over IPv4 and IPv6.
- Restore the original browser Secure DNS settings, apps, and network environment one at a time to identify which setting changes the results.
- Retest after restarting the client or updating the subscription to confirm the override is still in effect, not just for the current session.
The goal is not to make the test page show only one address. It is to ensure each type of query follows its intended path: LAN domains go to the internal resolver, domains that require a proxy use the specified policy, and node hostnames have a reachable bootstrap resolver. Verifying interception, upstreams, and outbound routing separately is usually more effective than repeatedly switching between fake-ip and redir-host.