9 min read

Clash DNS Leak Test & Fix: Step-by-Step Leak-Proof Setup Guide

Run an online leak test first, then lock down leaks with three fixes: nameserver config, DNS hijack listening, and rule-based fallback for a fully leak-proof setup.

What a DNS Leak Actually Is: Proxy's On, But Queries Still Go Local

Domain resolution is the first step of loading any page: your browser turns a domain name into an IP address, and DNS handles that translation. A DNS leak means the proxy shows "Connected," but resolution requests still go out through your real network and land on your ISP's or router's DNS server. That causes two problems. First, privacy: your local network provider can see exactly which domains you visited and when. Second, reliability: if the local DNS returns a tampered result, your browser gets the wrong IP — the classic symptom of "Clash says connected, but the page won't load, or loads the wrong content."

If the proxy is on, why does it still leak? Four common causes:

  • System proxy mode only intercepts browser-level web requests. It doesn't touch the system's DNS settings, so the ISP-assigned DNS on your network adapter keeps working as usual.
  • Clash's built-in DNS server isn't enabled, or it's enabled but the listen address doesn't cover the resolution path your system actually uses.
  • Browsers ship with their own "Secure DNS" (DoH) feature that bypasses the system resolver and connects straight to a DoH server, which also throws off leak test results.
  • IPv6 traffic isn't being intercepted, so AAAA queries slip out through the IPv6 DNS server — patching only IPv4 DNS won't close this gap.

Step 1: Test First to Confirm You're Actually Leaking

Gather evidence before you fix anything. Follow this order to confirm whether a leak exists and which path it's leaking through.

  1. Open the Clash client, confirm the proxy is connected, and note the current mode (Rule, Global, or Direct).
  2. Temporarily disable your browser's Secure DNS: in Chrome, go to Settings → Privacy and security → Security → Use secure DNS and turn it off; Edge follows the same path; in Firefox, go to Settings → Network Settings and uncheck "Enable DNS over HTTPS." Skip this and the test will only reflect your browser's DoH traffic, not the system-level path.
  3. Open any public DNS leak test site (such as dnsleaktest, ipleak, or the DNS test on browserleaks). Run the standard test first, then the extended test.
  4. Check the results: if your ISP's regional DNS resolvers show up in the list, you have a leak. If you only see overseas public DNS providers like Cloudflare or Google, or resolvers tied to your proxy's exit location, you're leak-free.
  5. Test both system proxy mode and TUN mode separately — they intercept different scopes of traffic, so results often differ.
Note

Flush your system DNS cache before testing so stale entries don't skew the result. On Windows, run ipconfig /flushdns as administrator; on macOS, run sudo dscacheutil -flushcache followed by sudo killall -HUP mDNSResponder.

One easy misread: if your nameserver config points to a local public DNS (like Alibaba's 223.5.5.5), the test site may show that provider's resolver. That means your real IP reached the request directly, and it's technically exposed to that DNS provider — but it's not an ISP-level leak. Whether that matters depends on whether you're going for "standard split routing" or "strict leak-proofing"; both configs are covered below.

Fix 1: Get the nameserver Config Right

Clash's DNS behavior is controlled by the dns block in your config file. Understand each field before you touch anything.

  • enable: the master switch for the built-in DNS server — must be true for leak-proofing.
  • listen: the listen address and port. Set 0.0.0.0:53 to intercept queries sent to port 53 on this machine.
  • enhanced-mode: either fake-ip or redir-host. fake-ip returns a virtual address in the 198.18.0.1/16 range; Clash resolves the real domain internally when the connection is intercepted, so resolution never leaves Clash — the most airtight anti-leak mode. redir-host has the client resolve the real IP first, then connect.
  • nameserver: the default upstream, used to resolve domains going through direct connection. Use DoH addresses with a bare IP, such as https://223.5.5.5/dns-query or https://119.29.29.29/dns-query.
  • fallback: the upstream used when a domain matches overseas rules, typically https://1.1.1.1/dns-query or https://8.8.8.8/dns-query — these queries go out through the proxy.
  • default-nameserver: the "bootstrap DNS" used to resolve the domain names of the DoH servers above. Use plain IPs (like 223.5.5.5, 119.29.29.29) to avoid the chicken-and-egg problem of needing DNS to resolve your DNS server's own domain.
  • proxy-server-nameserver (mihomo): dedicated to resolving your proxy node's server domain. Point it to a trusted local DoH server so node domains aren't tampered with, which would otherwise make nodes unreachable.

A complete example for standard split routing:

dns:
  enable: true
  listen: 0.0.0.0:53
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://223.5.5.5/dns-query
    - https://119.29.29.29/dns-query
  fallback:
    - https://1.1.1.1/dns-query
    - https://8.8.8.8/dns-query
  proxy-server-nameserver:
    - https://223.5.5.5/dns-query

For strict leak-proofing, drop the local upstream from nameserver entirely and route everything through fallback via the proxy — at the cost of slightly slower first-time resolution for local sites. A middle-ground option is splitting by domain with nameserver-policy:

  nameserver-policy:
    "geosite:cn":
      - https://223.5.5.5/dns-query
    "geosite:geolocation-!cn":
      - https://1.1.1.1/dns-query
Tip

Subscription files usually ship with their own dns block, so editing the subscription directly gets overwritten on the next update. The recommended approach: back up your original config, then inject the dns block using your client's config override feature (Clash Verge Rev's "Global Merge," Clash Nyanpasu's Merge, etc.) — that way your settings survive subscription updates.

Fix 2: Make Sure Queries Actually Reach Clash (Hijack Listening)

Even a perfectly correct config is useless if the system never sends queries to Clash. Here are three interception methods, ranked by how hands-off they are.

Method 1: TUN Mode (Recommended)

TUN mode in the mihomo (Clash Meta) core creates a virtual network adapter that intercepts all traffic on the machine, including UDP port 53 DNS queries; dns-hijack redirects any query sent to port 53 on any address into the built-in DNS. Clients like Clash Verge Rev, Clash Nyanpasu, and FlClash let you enable this with one toggle in settings — once it's on, your system DNS setting no longer matters.

tun:
  enable: true
  stack: mixed
  dns-hijack:
    - any:53
    - tcp://any:53
  auto-route: true
  auto-detect-interface: true

Method 2: Manually Change System DNS

Set your network adapter's IPv4 DNS to 127.0.0.1 and IPv6 DNS to ::1 (or just disable IPv6), paired with dns.listen bound to port 53. Watch out: Windows' Internet Connection Sharing and some virtual machine network services can occupy port 53, causing Clash to fail on startup. Either find and stop whatever's using the port, or just switch to TUN mode — don't try to force a different listen port, since Windows' network adapter DNS setting doesn't support ports other than 53.

Method 3: System Proxy Only + redir-host

This is the weakest form of interception: only traffic from apps routed through the proxy gets intercepted, while every other process on the system still resolves DNS the old way. If TUN mode isn't an option for now, at least make sure browser DoH is disabled, and accept that this setup only covers your browser.

Fix 3: Rule-Based Fallback and a Recheck Checklist

The final layer is rules. DNS config decides how queries get resolved; rules decide where traffic that slips through actually goes.

  • Make sure the MATCH rule at the end of your rule list points to a proxy policy group, not DIRECT — that way any traffic that doesn't match a rule (including an app's own DoH requests) won't go out directly.
  • Don't add a DIRECT rule for port 53. In TUN mode, dns-hijack already handles it, and extra rules just create confusion.
  • Built-in app DoH is the most common leak path that slips past everything else. You can route public DoH domains like dns.google, cloudflare-dns.com, and mozilla.cloudflare-dns.com to REJECT, forcing the app to fall back to system resolution, which Clash then handles.

Once everything's set, work through this recheck checklist:

  1. Run the leak test again and confirm only overseas resolvers show up.
  2. Switch networks (say, from home Wi-Fi to a phone hotspot) and test again to rule out a fluke on a single connection.
  3. Manually update your subscription once, confirm the dns override still applies, then test again.
  4. Watch for broken sites over the next few days: some services don't play well with fake-ip. Just add the affected domain to fake-ip-filter — no need to fall back to redir-host over it.

A DNS leak isn't a one-and-done fix: switching clients, changing networks, or updating your subscription can all reset your config. Make "test after every change, test after every update" a habit, and your leak-proofing actually holds.

Download Clash

Clients for Windows, macOS, Linux, and Android are all on the downloads page, free and open source, with versions checked daily against official releases.

Clash Update