DNS — mihomo
mihomo's dns: block is large and flat. The core idea: declare a primary resolver list (nameserver) and a fallback list, then filter which queries go to fallback via fallback-filter. Per-domain overrides via nameserver-policy. Optional fake-IP engine for sniffing-friendly routing.
Top-level options
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
enable | bool | false | true | false | Master switch. When false the rest of the block is ignored and the OS resolver is used. |
prefer-h3 | bool | false | true | false | Prefer DNS-over-HTTPS/3 (over QUIC) when a server URL supports both H2 and H3. |
ipv6 | bool | false | true | false | Resolve AAAA records. When false, only A queries are issued. |
ipv6-timeout | uint | 100 | <milliseconds> | Maximum time to wait for a AAAA answer before falling back to IPv4-only. 100ms is the documented default. |
use-hosts | bool | false | true | false | Consult the top-level `hosts:` map before going to network. |
use-system-hosts | bool | false | true | false | Also consult the OS hosts file (`/etc/hosts`). |
respect-rules | bool | false | true | false | Run the **routing rules** against DNS queries themselves. When true, a query's outbound is decided by the rules list — useful to route DNS traffic to a specific tunnel. |
nameserver | []string | [] | [<URL>] | Primary resolver list. Each entry is a URL: `udp://...`, `tcp://...`, `tls://...`, `https://...`, `quic://...`, `system://`, `dhcp://<iface>`, or `rcode://...`. |
fallback | []string | [] | [<URL>] | Fallback resolver list — consulted when a primary answer is filtered by `fallback-filter` (e.g. domestic-IP answer for a non-domestic query). |
fallback-filter | RawFallbackFilter | {geoip: true, geoip-code: "CN"} | RawFallbackFilter | Filter that decides when to consult `fallback`. Carries `geoip`, `geoip-code`, `ipcidr`, `domain`, `geosite`. |
listen | string | (disabled) | <host:port> | If set, run a local DNS server on this address. The server obeys the same rules as the internal resolver. |
enhanced-mode | C.DNSMode | normal | normal | redir-host | fake-ip | DNS-engine mode. `normal` returns real answers; `redir-host` returns the IP but tags the connection with the original domain (for sniffing-friendly routing); `fake-ip` returns synthetic IPs from `fake-ip-range`. |
fake-ip-range | string | 198.18.0.1/16 | <CIDR> | IPv4 range allocated for fake IPs (mode `fake-ip` only). |
fake-ip-range6 | string | (unset) | <CIDR> | Optional IPv6 range. |
fake-ip-filter | []string | [] | <domain pattern> | Domains that should **not** receive a fake IP — pass through to the real resolver instead. Wildcards supported. |
fake-ip-filter-mode | C.FilterMode | blacklist | blacklist | whitelist | Whether `fake-ip-filter` is a blacklist (filtered domains skip fake-ip) or whitelist (only filtered domains get fake-ip). |
fake-ip-ttl | int | 1 | <seconds> | TTL in seconds for fake-IP answers. Low values force clients to re-resolve often, which keeps the fake-ip mapping fresh. |
default-nameserver | []string | [114.114.114.114, 223.5.5.5, 8.8.8.8, 1.0.0.1] | [<URL>] | Bootstrap resolvers used to resolve the hostnames of the entries in `nameserver`/`fallback` themselves. **Must** be plain IPs — no further resolution allowed. |
cache-algorithm | string | lru | lru | arc | Eviction algorithm. `arc` (Adaptive Replacement Cache) is occasionally better for workloads with bursty access patterns. |
cache-max-size | int | 0 (unbounded) | <int> | Maximum cached entries. |
nameserver-policy | *orderedmap.OrderedMap[string, any] | {} | {<domain or rule>: <URL or [URL]>} | Per-domain-pattern routing. Keys are domain patterns or `geosite:`/`rule-set:`/`+./` notations; values are resolver URLs. Higher priority than `nameserver`. |
proxy-server-nameserver | []string | [] | [<URL>] | Resolvers used **specifically** to resolve proxy-server hostnames. Avoids the chicken-and-egg problem of routing a proxy hostname through the proxy that uses it. |
proxy-server-nameserver-policy | *orderedmap.OrderedMap[string, any] | {} | {<pattern>: <URL>} | Per-domain override of `proxy-server-nameserver`. |
direct-nameserver | []string | [] | [<URL>] | Resolvers used for DIRECT-routed destinations. Avoids leaking domestic-DNS lookups through the proxy. |
direct-nameserver-follow-policy | bool | false | true | false | Apply `nameserver-policy` to `direct-nameserver` queries too. |
Source: config/config.go:218-244 · pinned at v1.19.27 (5184081)
Nameserver URL schemes
The nameserver, fallback, default-nameserver, proxy-server-nameserver, and direct-nameserver lists all accept the same URL grammar:
| Scheme | Example | Notes |
|---|---|---|
| (bare IP) | 223.5.5.5 | UDP/53 |
udp:// | udp://8.8.8.8:53 | Explicit UDP, optional port |
tcp:// | tcp://8.8.8.8:53 | DNS-over-TCP |
tls:// | tls://1.1.1.1:853 | DNS-over-TLS |
https:// | https://doh.pub/dns-query | DNS-over-HTTPS (H2) |
quic:// | quic://dns.adguard-dns.com | DNS-over-QUIC |
h3:// | h3://1.1.1.1/dns-query | DoH over HTTP/3 |
system:// | system:// | OS resolver |
dhcp:// | dhcp://eth0 | DHCP-provided resolver for eth0 |
rcode:// | rcode://refused | Return a fixed RCODE |
URL paths after the host can carry an #<proxy> suffix to force the DNS traffic through a named proxy:
nameserver:
- https://cloudflare-dns.com/dns-query#proxynameserver-policy
The most powerful field. Keys are matchers; values are resolver URL or URL list:
nameserver-policy:
"geosite:cn,private": # GeoSite category match
- 223.5.5.5
- 114.114.114.114
"+.cn": # Suffix match — note the +. prefix
- https://doh.pub/dns-query
"rule-set:cn": # Rule-set reference
- 223.5.5.5
"www.example.com": # Exact domain
- https://example-dns.com/dns-querynameserver-policy is consulted before the main nameserver list, so matched domains skip the standard resolver entirely.
fallback-filter
Decides when a primary answer is "suspicious" and triggers a fallback query:
fallback-filter:
geoip: true # Apply GeoIP filtering
geoip-code: CN # Treat answers in this country as suspicious-foreign-domain
ipcidr:
- 240.0.0.0/4 # Specific CIDR triggers
geosite:
- gfw # GeoSite categories that must always go to fallback
domain:
- +.google.com # Domain patterns that must always go to fallbackWhen a primary answer matches geoip-code/ipcidr and the query domain doesn't match geosite/domain, the result is rejected and the fallback list is queried.
Examples
Classic CN-bypass DNS:
dns:
enable: true
prefer-h3: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '+.lan'
- '+.local'
- 'localhost.ptlogin2.qq.com'
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
fallback:
- https://1.1.1.1/dns-query
- https://dns.google/dns-query
- tls://8.8.4.4:853
fallback-filter:
geoip: true
geoip-code: CN
geosite:
- gfw
nameserver-policy:
'geosite:cn,private':
- https://doh.pub/dns-query
'geosite:gfw,geolocation-!cn':
- https://1.1.1.1/dns-query
- https://dns.google/dns-query
proxy-server-nameserver:
- https://doh.pub/dns-query
direct-nameserver:
- https://doh.pub/dns-queryLocal DNS server for downstream devices:
dns:
enable: true
listen: 0.0.0.0:53
enhanced-mode: redir-host
nameserver:
- https://1.1.1.1/dns-queryNotes
enhanced-mode: fake-ipis the standard mode for transparent-proxy setups. Real IP resolution happens at the proxy side, not the client side — which means sniffing-aware routing rules can see the original domain.default-nameservermust contain plain IP addresses only. They are used to resolve the hostnames innameserver/fallbackthemselves; allowing hostnames here would be a bootstrap cycle.fake-ip-filteraccepts the same domain-pattern syntax as routing rules (+.example.comfor suffix,geosite:applefor category).proxy-server-nameserveris critical for setups where the proxy server hostname is also a domain in your routing rules. Without it, resolving the proxy hostname can recursively try to route through itself.direct-nameserverkeeps direct-bound queries from leaking to the fallback (overseas) resolver. Useful whenfallbackis your only uncensored path.
Cross-core notes
- Xray-core uses a flat block with URL-string-or-object servers and per-server
domains/expectedIPs/unexpectedIPs. See DNS — Xray-core. - sing-box uses typed servers (
type: "https",type: "fakeip", …) and a structured DNS rule chain with explicit actions. See DNS — sing-box.
Source: config/config.go:218-244 · v1.19.27 (5184081)
