yiguodev:Xray Linux TUN DNS 接管仍有混合解析路径反例
yiguodev 在 Xray-core #6773 中说明,已用四组真实 Linux 场景复测确认无 DNS、空 DNS 和 gateway-source-IP 到 blackhole 等修复有效;但新增只对 example.com 使用 localhost 且 finalQuery/skipFallback 的上游后,接管会被接受而查询 4/4 超时。他认为应在可选解析路径可能依赖系统解析器时拒绝接管,并在 README 明确 source-port-independent DNS path 等限制。
作者原文@yiguodevThanks for the three commits and the explicit clarification of their scope. I retested
71b70211daf9ebe25500f64d8f8634be32fd2c3dwith four real Linux matrices, nine scenarios each. This follow-up focuses on functional behavior rather than style.Confirmed fixes
- No
dnssection, an empty DNS configuration, and the gateway-source-IP → blackhole case now correctly refuse takeover while system resolution remains usable.- The dirty-state fix works: real private-bus ACL denials cause another revert attempt at shutdown. After restoring the private policy, I captured successful Revert method-return replies, correlated by caller and serial—not merely the absence of an error log. With permission still denied, the retry receives an error and the per-link state disappears with the TUN on exit.
Please keep the small
app/dnsaccessor; covering the empty-server case is justified. The real-router tests are also useful, CI-friendly regression coverage. They test decisions rather than DNS responses, but that does not negate their value.New counterexample: mixed independent and system-resolver upstreams
Starting from the working independent-upstream configuration, add this DNS server:
{ "address": "localhost", "domains": ["full:example.com"], "finalQuery": true, "skipFallback": true }The takeover is accepted, but
example.comtimes out in 4/4 runs. Queries reach the DNS outbound, and logs show lookups returning to the private system stub and timing out. An unrelated domain resolves successfully before and after the failing query in the same instance.
UsesSystemResolver()returns false as soon as any upstream is non-local, whereas the domain-specific selection can still choose only localhost. This is an additional configuration case, not a claim that your no/empty-DNS fixes failed.A conservative fix would refuse takeover when a selectable resolution path may depend on the system resolver, rather than checking whether all clients do. A
MayUseSystemResolver-style check and a mixed-server regression case would make that distinction explicit; do not silently remove the user's local resolver.Source ports: the limitation you already disclosed
I acknowledge your statement that the representative source port cannot predict the real query's port. The live consequence is reproducible: with source port
49152→ DNS and remaining TUN/53 traffic → blackhole, preflight accepts takeover; real queries from49152answer, while49153and the system resolver's actual ephemeral ports fail, in all four runs.Could the README explicitly require a source-port-independent DNS path and clarify whether unsupported configurations should be refused? We should avoid presenting the synthetic check as a guarantee for arbitrary routing rules. I am not asking for a general Router redesign in this PR.
Scope and evidence limits
Deferring godbus is fine. Fixture duplication and missing full TUN E2E coverage are not additional observed functional failures. The remaining
.Base(err).Base(cause)overwrite is a diagnostic improvement, not evidence that cleanup is skipped.The real TUN/gVisor, DNS and resolvectl path ran inside private mount/PID namespaces with a private bus/resolved. This does not establish normal-host authorization or general leak coverage. Four seconds is the client's timeout limit.
One supplementary rollback-recovery run also had a DNS timeout before policy restoration; Revert succeeded and the next identical run answered normally. That failure is retained and unexplained—not attributed to rollback or dismissed as proven network noise.
All 36 Core instances exited 0, their TUNs disappeared automatically, and all four host-preservation audits passed.