Advanced 12-minute read

Clash DNS Configuration Explained: nameserver, fallback Groups, and fake-ip Hijacking

Learn how Clash DNS settings work, including nameserver, fallback-filter, fake-ip vs. redir-host, and when system DNS hijacking takes effect. Includes ready-to-use config.

The short version: check DNS upstreams, returned addresses, and traffic interception separately

Clash DNS configuration is easiest to understand as three separate questions: which servers resolve domain names, which addresses are returned to apps, and whether app DNS requests reach the core. nameserver and fallback handle the first; enhanced-mode handles the second; system DNS, the listening port, and TUN dns-hijack determine the third. Switching to fake-ip alone does not automatically route all device DNS traffic through the core.

The main configuration below targets mihomo. Clash is a common name for the client ecosystem, but similar-looking interfaces do not guarantee identical underlying fields. Support for TUN and DNS extension fields varies between the original Clash, older forks, and current mihomo. Check the core information shown by your client or its startup logs. For command-line deployments, run mihomo -v to identify the core in use; don't infer its capabilities from the client version.

  • Subscription imported successfully: This only confirms that the configuration can be read; it doesn't mean the system is using its DNS settings.
  • Node latency test passed: This only tests the selected target; it doesn't confirm that every domain resolves correctly.
  • A 198.18-range address was returned: This can be expected in fake-ip mode and shouldn't automatically be treated as DNS pollution.

nameserver vs. default-nameserver: regular and bootstrap DNS

dns.nameserver is the list of upstream servers used for regular domain lookups. An upstream can be a plain DNS server IP or a DoH or DoT address supported by the core. The list isn't a fixed queue where the first server always takes priority and the second is used only if the first goes offline. The core handles multiple upstreams according to its own query and response logic, so don't rely on their written order for strict primary/backup behavior.

Why can regular DNS still be used when DoH is configured?

For example, https://dns.alidns.com/dns-query is a DoH endpoint, but its HTTPS connection can't be established until dns.alidns.com has been resolved to an IP address. default-nameserver provides bootstrap resolution for DNS service hostnames like this. The example below uses 223.5.5.5 and 119.29.29.29 to make the dependency clear; these addresses aren't suitable for every network.

FieldWhat it doesCommon misconception
enableEnables the core's DNS featureThe system is guaranteed to use it once enabled
listenSets the DNS service's listening address and portPort 1053 automatically works with the system's default port 53
default-nameserverProvides bootstrap resolution for DNS upstream hostnamesIt's the preferred resolver for every domain
nameserverProvides regular upstream resolutionThe list order is a strict failover sequence
enhanced-modeSelects a handling mode such as fake-ip or redir-hostThe mode itself intercepts system traffic

DoH encryption only protects the connection between the client and that DNS service; it doesn't automatically mean requests go through a proxy node. Check upstream reachability, the outbound route used by DNS connections, and the rules matching application traffic separately. mihomo also provides extension fields such as proxy-server-nameserver for resolving proxy server hostnames separately. Don't make requests to resolve a proxy node's hostname depend on that same node unless you understand the dependency.

fallback and fallback-filter: filtering candidate results, not proxy rule groups

Although fallback is often called a “backup DNS,” it's not simply a list that waits for nameserver to time out completely. With fallback configured, the core can query the regular and fallback groups at the same time, then choose a result based on the filters. These “groups” are sets of DNS upstreams, not node selection or automatic latency-test groups in proxy-groups.

What do geoip, ipcidr, and domain check?

  • geoip: true with geoip-code: CN: Checks the region of addresses returned by the regular group; results outside the specified region can trigger the fallback result. This depends on the core having usable geolocation data.
  • ipcidr: Treats certain returned address ranges as results to filter, such as 240.0.0.0/4. It checks DNS results; it doesn't add a proxy rule for application connections.
  • domain: Uses the fallback result for matching domain names. This is an explicit domain-based condition and doesn't require the regular group to return an unusual IP first.

These conditions don't form a chain where every check must pass before fallback is triggered. Don't assume the only trigger is a domain on the list that also resolves outside CN and falls within a reserved range. Another easy-to-miss limitation: if an incorrectly returned address is also classified as CN by the geolocation data, geoip alone may not detect the problem. Fallback selects results; it doesn't guarantee they're correct.

When you need to explicitly route certain domains to a particular DNS server, mihomo's nameserver-policy is usually clearer. It selects the DNS upstream; rules select the outbound route for application connections. Don't use one in place of the other. Even if a domain is resolved by a DNS server outside mainland China, its application traffic won't automatically match a proxy rule.

fake-ip vs. redir-host: virtual or real addresses

fake-ip: Preserve domain context with a mapping

enhanced-mode: fake-ip returns virtual addresses for eligible queries and keeps a mapping between each domain and its virtual address in the core. When an app connects to that address, the connection must reach the same core so it can recover the destination from the mapping. The example uses 198.18.0.1/16, a reserved address range for benchmarking—not the real address of a remote website.

This approach helps preserve domain information when a connection is made and can avoid waiting for the real destination address to be resolved first. It doesn't mean “real DNS is no longer needed for any domain,” though. Direct connections, IP-based rules, and the handling paths of specific cores may still trigger real lookups. Assuming fake-ip eliminates the need for upstream DNS can lead to hard-to-diagnose connection failures.

redir-host: Return real addresses and check domain association

redir-host returns the real IP provided by the upstream, then the core uses information such as its DNS cache to associate the IP with a domain. This can be more compatible with programs that need to see real addresses, but it doesn't prevent incorrect DNS results or guarantee that domain context is preserved for every connection. App-level DNS resolution, expired cache entries, or connections that bypass the core can all affect rule matching.

  • Everyday desktop TUN use: Start by testing fake-ip so the same core can handle DNS and subsequent connections.
  • Issues with LAN devices, printers, or internal services: Check LAN DNS and filter lists first, then consider switching modes.
  • An app requires real IPs: Add the relevant domains to fake-ip-filter; you don't need to switch every app to redir-host right away.

fake-ip-filter means “don't return fake IPs for these domains,” not “don't proxy these domains.” The example below excludes localhost, *.lan, and *.local. Excluding them won't make public DNS able to resolve private router hostnames; internal domains still need a working LAN resolver. .local often involves mDNS, which can't be fixed just by changing regular DNS upstreams.

Ready-to-use DNS snippet: verify it first at 127.0.0.1:1053

Replace only the dns: section in your full configuration with the snippet below. It doesn't include nodes, proxy groups, or traffic rules. Keep the rest of your existing subscription configuration. If it already contains dns:, merge or replace the section to avoid duplicate top-level keys. Graphical clients may overwrite subscription fields at startup, so save changes through their persistent override mechanism and check the final active configuration.

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "localhost"
    - "*.lan"
    - "*.local"
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
  fallback:
    - https://cloudflare-dns.com/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4
      - 0.0.0.0/8

The loopback listener is used here to limit initial testing to this machine; the configuration does not listen on 0.0.0.0:53 or expose DNS to the LAN. ipv6: false narrows the scope of this DNS test. It doesn't disable IPv6 in the operating system and doesn't mean all IPv6 connections are blocked.

Check the syntax, then verify the listener

In a command-line environment, run the following checks from the configuration directory. If a graphical client manages its own configuration path, don't replace its startup arguments with these commands. Use the client's configuration checker and confirm in the logs that the DNS service starts successfully.

mihomo -t -f config.yaml

dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp

example.com is a public example domain for testing the query path. A 198.18.x.x response can be normal for a fake-ip-capable setup. If both UDP and TCP time out, check the listener, port conflicts, and core logs first. If dig isn't installed on Windows, specify the server and port in the interactive nslookup prompt:

nslookup
server 127.0.0.1
set port=1053
set type=A
example.com
exit

When TUN DNS hijacking works: port 53 requests must pass through the core

Operating systems typically use UDP or TCP port 53 for DNS. The 1053 port used above is for testing; the system won't automatically forward requests from port 53 to it. Most system DNS settings don't let you specify a custom port either. To intercept regular DNS, use the client's TUN DNS interception feature or configure an explicit local forwarder. Setting system DNS to 127.0.0.1 alone won't send requests to port 1053.

On mihomo setups that support the following fields, merge this section into the existing tun: configuration. Before enabling it, grant the permissions required by the client or operating system to create a virtual network interface and modify routes. If the client already manages TUN, use its configuration interface to avoid conflicts with manually added settings.

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

any:53 matches UDP DNS; tcp://any:53 covers TCP DNS. Hijacking here means DNS requests entering the TUN processing path are handed to the core's DNS module; it doesn't simply rewrite all requests to local port 1053. Whether requests enter that path also depends on system routes, other VPNs, interface selection, and platform limitations.

Traffic that dns-hijack won't intercept automatically

  • Browser DoH: This usually looks like HTTPS traffic, so port 53 rules can't identify it as regular DNS.
  • System or app DoT: This typically uses port 853, outside the scope of these two port 53 matches.
  • Traffic that doesn't enter TUN: For example, requests routed through another VPN, a separate route, or a platform-restricted path.
  • Cached results: An app may not make a new query and may continue using an old address or an existing connection.

Don't confuse a system proxy with TUN either. When a browser sends a domain through an HTTP proxy, the proxy may resolve the destination. Apps that ignore the system proxy may use system DNS directly. For troubleshooting, temporarily disable the browser's built-in Secure DNS to establish a controlled baseline, then restore your preferred settings once you've confirmed the setup.

Troubleshooting: diagnose by symptom and change one variable at a time

SymptomCheck firstNext step
Local query to port 1053 times outWhether DNS is enabled, the configuration is active, and the port is availableCheck startup logs and test UDP and TCP separately
Local queries work, but apps still fail to resolve domainsWhether the app is using the core's DNSCheck system DNS, TUN routes, and app-level DoH
A 198.18 address is returned, but the connection times outWhether the subsequent connection returns to the same coreCheck virtual network routes, TUN status, and connection logs
A few domains take noticeably longer to loadWhether fallback is reachable and selected by the filterCheck resolution errors and test the backup upstream separately
Internal domains don't resolveWhether public upstreams can resolve private hostnamesConfigure a LAN upstream or a domain-specific DNS policy
Changes have no effectSubscription overrides, system cache, and persistent app connectionsCheck the active configuration, clear caches, and reconnect

Clear caches when switching modes

After switching from fake-ip to redir-host or disabling TUN, apps may still have virtual addresses cached. On Windows, run ipconfig /flushdns. On Linux with systemd-resolved, run resolvectl flush-caches. These commands have specific requirements and aren't cross-platform alternatives. Browser DNS caches and connection pools must be cleared separately; if needed, fully quit and reopen the app.

Use one fixed domain for testing: make a query, visit the corresponding page, and check the connection panel for the destination domain, matched rule, and outbound policy. Don't rely only on a public IP lookup page to assess DNS. The exit IP shows where that web connection went, but doesn't tell you which server handled the DNS request.

To revisit subscription imports and basic connection setup, see the subscription guide in Getting Started. For how DNS relates to rules, see the DNS section of the user guide. The key is to confirm that requests reach the core first, then review upstreams and filters, and only then adjust compatibility lists.

Download the latest Clash