Skip to content

fix(tun/dns): bootstrap critical resolvers over DoH-over-IP instead of UDP 53#42

Merged
dododook merged 1 commit into
dododook:mainfrom
Sway-Chan:fix/tun-dns-bootstrap
Jun 8, 2026
Merged

fix(tun/dns): bootstrap critical resolvers over DoH-over-IP instead of UDP 53#42
dododook merged 1 commit into
dododook:mainfrom
Sway-Chan:fix/tun-dns-bootstrap

Conversation

@Sway-Chan

Copy link
Copy Markdown
Collaborator

Problem

In TUN mode every critical name resolution — the proxy node domain, doh.pub, and default_domain_resolver — is bootstrapped through domain_resolver: 'dns-bootstrap-udp' (223.5.5.5:53, UDP).

The DoH-over-IP bootstrap that the code explicitly added "to avoid UDP 53 blocking" (dns-bootstrap, 223.5.5.5:443) was never referenced as a resolver by any of these paths. UDP 53 is therefore a single point of failure for the whole resolution chain: when a network rate-limits / hijacks / poisons UDP 53 (common on mobile, hotel, captive and some ISP networks), the proxy node domain can no longer be resolved once its cached entry expires, the outbound cannot connect, and the entire tunnel drops — an intermittent "works for a while then disconnects" failure.

Changes

  • Re-point the four critical resolvers — dns-domestic, dns-remote, the proxy outbound, and default_domain_resolver — from dns-bootstrap-udp to dns-bootstrap (DoH over the literal IP 223.5.5.5:443). DoH-over-IP is immune to UDP-53 interference, needs no name resolution itself, and already egresses direct via the existing 223.5.5.5 :443 route rule (placed before hijack-dns), so it cannot loop back into TUN.
  • Drop the redundant domain_resolver on dns-bootstrap itself — its server is already an IP, so it is a self-contained terminal node (no resolution required).
  • Keep dns-bootstrap-udp for the non-critical app-query path (doh.pub/dns.google app self-queries), preserving the fast UDP path where it does not matter.
  • Fix two stale comments: the bootstrap bypasses TUN via the route ip_cidr rule (not a DNS detour: 'direct', which it never had), and default_domain_resolver now names dns-bootstrap.

The dns-bootstrap/dns-bootstrap-udp hosts are both 223.5.5.5; a follow-up could add a second-IP DoH backup so the bootstrap host itself is not a SPOF.

Testing

  • tsc -p tsconfig.main.json, eslint, prettier --check: clean.
  • Representative TUN config with the new wiring validated by the bundled sing-box check (1.13.x): EXIT 0. No circular dependency — dns-bootstrap is a terminal IP node (verified that an IP-based DoH server with no domain_resolver is accepted, while a domain-based one without a resolver is rejected).

🤖 Generated with Claude Code

Every critical name resolution -- the proxy node domain, doh.pub, and
default_domain_resolver -- used `domain_resolver: 'dns-bootstrap-udp'`
(223.5.5.5:53/UDP). The DoH-over-IP bootstrap the code added "to avoid
UDP 53 blocking" (`dns-bootstrap`, 223.5.5.5:443) was never referenced
as a resolver, so UDP 53 was a single point of failure: when an ISP
rate-limits / hijacks / poisons UDP 53, the node domain fails to resolve
and the whole tunnel drops.

- Point dns-domestic, dns-remote, the proxy outbound, and
  default_domain_resolver at `dns-bootstrap` (DoH over the literal IP
  223.5.5.5:443), immune to UDP-53 interference and already egressing
  direct via the existing 223.5.5.5:443 route rule.
- Drop the redundant `domain_resolver` on `dns-bootstrap` itself (its
  server is already an IP, so no resolution is needed).
- Keep `dns-bootstrap-udp` for the non-critical app-query path.
- Fix two stale comments (the bootstrap bypasses TUN via the route rule,
  not a DNS `detour`; default_domain_resolver now names dns-bootstrap).

Validated with `sing-box check` (1.13.x): no cycle (dns-bootstrap is a
terminal IP node).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sway-Chan added a commit to Sway-Chan/FlowZ that referenced this pull request Jun 8, 2026
@dododook
dododook merged commit 4d31cd9 into dododook:main Jun 8, 2026
@dododook

dododook commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Merged into main branch via local git merge, included in v3.5.0 release. Thank you for your contribution!

@Sway-Chan
Sway-Chan deleted the fix/tun-dns-bootstrap branch June 15, 2026 09:14
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.

2 participants