fix(wg-client): route unqualified names to Docker DNS, dotted names upstream - #117
Open
shejnowicz wants to merge 1 commit into
Open
shejnowicz wants to merge 1 commit into
shejnowicz wants to merge 1 commit into
Conversation
…pstream Fixes #113. Implements the dnsmasq configuration proposed by @jiramares. The old config routed each search domain to Docker's embedded resolver and dropped dotless queries (domain-needed). That assumed search domains are the compose network domain — but Docker copies the HOST's search domains into containers, so in corporate setups they are intranet zones. Consequences: sibling-container lookups failed (libc's search expansion produced name.<intranet> → NXDOMAIN, and the final bare-name attempt was dropped by domain-needed), and intranet FQDNs were black-holed (routed to Docker's resolver, which forwards unknown names to the compose `dns:` exfiltration sink). New config: `server=//127.0.0.11` sends ONLY unqualified single-label names (sibling containers) to Docker's resolver; every dotted name — including hosts under the search domains — goes to the upstream from dns.conf through wg0 → mitmproxy, so intranet zones resolve via `dns_servers` and stay subject to the DNS policy. Search domains in resolv.conf now serve their real purpose: short intranet names. The exfiltration posture is unchanged: unknown single-label names are forwarded by Docker's resolver to the unroutable `dns:` sink and fail without leaving the host; dotted names were already policy-gated. Tests updated with #113 regression guards (no per-search-domain routes, no domain-needed); docs (Container-to-container DNS) rewritten to match. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #113. Implements the dnsmasq configuration proposed by @jiramares — thank you for the precise diagnosis and the ready-to-use config.
Problem
The old config assumed the container's search domains are the compose network domain and routed them to Docker's embedded resolver, while
domain-neededdropped dotless queries. But Docker copies the host's search domains into containers, so in corporate setups they are intranet zones. Result: sibling-container lookups failed (search expansion producedname.<intranet>→ NXDOMAIN, and the final bare-name attempt was dropped), and intranet FQDNs were black-holed via the composedns:sink.Fix
(
domain-neededremoved.) Search domains in resolv.conf now do their real job — short intranet names — and the exfiltration posture is unchanged: unknown single-label names are forwarded by Docker's resolver to the unroutabledns:sink and never leave the host; dotted names stay subject to mitmproxy's DNS policy.Test plan
domain-needed); full suite 16/16 green.dns_serverspointed at it):server=//127.0.0.11+ the intranet upstream, nodomain-needed;mitmproxy,wg-client) — the exact failure from the issue;nexus.corp.testresolves to203.0.113.42— an address only the intranet server knows, and its network is not agent-local, so the query provably went agent → wg0 → mitmproxy → intranet DNS;domain-neededused to drop it at dnsmasq) — the cost of making sibling resolution work at all.🤖 Generated with Claude Code