Skip to content

fix: drop 8.8.8.8 from default-nameserver to survive enterprise SSL VPN UDP/53 interception#73

Merged
mixc6763-prog merged 1 commit into
mainfrom
fix/default-nameserver-drop-public-udp53
May 7, 2026
Merged

fix: drop 8.8.8.8 from default-nameserver to survive enterprise SSL VPN UDP/53 interception#73
mixc6763-prog merged 1 commit into
mainfrom
fix/default-nameserver-drop-public-udp53

Conversation

@mixc6763-prog
Copy link
Copy Markdown
Contributor

Summary

Removes 8.8.8.8 from the bootstrap default-nameserver list in two code paths, eliminating the last UDP/53 dependency on a public foreign DNS server. Companion to ClashX-Pro/ClashX#20 — which fixed the same class of issue in our sister project.

Background

default-nameserver is the bootstrap resolver used before DoH/DoT can come online — it's the resolver that turns doh.pub into an IP so the real nameserver list can be queried over HTTPS. Because of that bootstrap role, mihomo requires default-nameserver entries to be plain IPs (not URLs), so they always go over plain UDP/53.

Two locations still listed 8.8.8.8:

Users on networks that intercept dport 53 UDP — most prominently SangFor Easy Connect (Chinese enterprise SSL VPN), which installs a PF DNAT rule redirecting all UDP/53 traffic to its internal DNS proxy at 127.0.0.1:5373 — see the bootstrap query to 8.8.8.8:53 time out. The downstream DoH/DoT lookups never get a chance because their server hostnames can't be resolved.

The nameserver / fallback lists in the same file already prefer DoH (https://) + DoT (tls://...:853), so once bootstrap completes, in-flight DNS is safe. This PR just patches the remaining bootstrap-stage hole.

Change

Two-line replacement: 8.8.8.8119.29.29.29 (Tencent DNSPod, domestic) in both default-nameserver lists.

```diff
if len(rawCfg.DNS.DefaultNameserver) == 0 {
rawCfg.DNS.DefaultNameserver = []string{
"114.114.114.114",
"223.5.5.5",

  • "8.8.8.8",
  • "119.29.29.29",
    }
    }
    ```

```diff
if dns["default-nameserver"] == nil {

  • dns["default-nameserver"] = []string{"114.114.114.114", "223.5.5.5", "8.8.8.8"}
  • dns["default-nameserver"] = []string{"114.114.114.114", "223.5.5.5", "119.29.29.29"}
    }
    ```

Now field-for-field consistent with nameserverPolicyForConvertedProxies (lines 491-495), which has been domestic-only since day one.

Why Domestic Plain UDP/53 Is Safe

Enterprise VPN clients on macOS commonly DNAT dport 53 to a corporate DNS forwarder. That forwarder will resolve domestic names (the corporate resolver itself almost always forwards to upstream domestic resolvers like Aliyun/CNNIC), it just can't reach 8.8.8.8 directly. So:

  • 223.5.5.5 (Aliyun) — resolved by the corporate forwarder, returns correct A record for doh.pub
  • 114.114.114.114 (114DNS) — same
  • 119.29.29.29 (Tencent) — same

After bootstrap completes, the real nameserver list (DoH/DoT) takes over, and from then on everything goes over TCP/443 or TCP/853, completely bypassing the PF DNAT rule on UDP/53.

Verification

LSP clean. The only remaining 8.8.8.8 literal in main.go is tls://8.8.8.8:853 (Cloudflare/Google DoT fallback at line 508), which intentionally stays — DoT is encapsulated in TCP/853 and is unaffected by UDP/53 interception.

Impact

  • No new dependencies, no API surface change.
  • No template-version migration needed (existing user configs are untouched; this only affects in-process defaults applied when default-nameserver is empty).
  • Bundle size delta: zero (string-for-string substitution).
  • Behavior on healthy networks: identical (any of the three resolvers works fine).
  • Behavior on enterprise SSL VPN networks: now survives bootstrap-stage DNS.

…PN UDP/53 interception

The default-nameserver list (used to bootstrap-resolve DNS server
domains like doh.pub before DoH/DoT can be used) included 8.8.8.8 in
two code paths:

  - applyTunConfig (Enhanced Mode/TUN bring-up)
  - clashWriteEnhancedConfig (writing enhanced config to disk)

When users run an enterprise SSL VPN that intercepts UDP/53 (e.g.
SangFor Easy Connect, which DNATs all dport 53 UDP to its internal
DNS proxy), the bootstrap query to 8.8.8.8:53 times out, blocking
DoH/DoT from coming online. nameserver/fallback lists already
preferred DoH (https://) + DoT (tls://...:853) so the in-flight
queries themselves are safe — but bootstrap is still UDP.

Replace 8.8.8.8 with 119.29.29.29 (Tencent DNSPod, domestic) for
parity with nameserverPolicyForConvertedProxies (lines 491-495,
already domestic-only). Domestic DNS UDP/53 is generally allowed
by enterprise VPN policies because corporate DNS itself usually
forwards to upstream domestic resolvers.

No new dependencies, no API change, no template-version bump
required. Companion to ClashX-Pro/ClashX#20 (which aligned that
project's share-link Go DNS defaults with our DoH/DoT design).
@mixc6763-prog mixc6763-prog merged commit 78b88cd into main May 7, 2026
1 check passed
@mixc6763-prog mixc6763-prog deleted the fix/default-nameserver-drop-public-udp53 branch May 7, 2026 08:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant