-
Notifications
You must be signed in to change notification settings - Fork 18k
net.Resolver Ignores Custom Dialer #33086
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
You might have missed these comments in the net documentation:
and more importantly
|
Ah okay, it's strange because This seems to be a duplicate of 29621 |
Pebble accepts a `--dnsserver` flag, that allows to select a custom DNS resolver to use when validating the ACME challenges. This option is critical to make the certbot integration tests work in particular. Current implementation is to set the `net.DefaultResolver` on a new `net.Resolver` instance with a custom `Dial` property to consume the value from `--dnsserver`. This allows to transparently resolve any host using this custom DNS resolver from a pure-Go implementation of the DNS resolution API. Sadly this approach does not work on Windows, and the `--dnsserver` has no effect on how resolution is done, and it is always the OS mechanism that is used. One can reveal this behavior by running the following piece of code on Linux and on Windows: ```go // test.go package main import ( "context" "fmt" "net" ) func main() { resolver := &net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, _, _ string) (net.Conn, error) { d := net.Dialer{} return d.DialContext(ctx, "udp", "4.3.2.1:404") }, } net.DefaultResolver = resolver ctx, cancelfunc := context.WithTimeout(context.Background(), 30) defer cancelfunc() _, err := resolver.LookupTXT(ctx, "stupid.entry.net") fmt.Printf("Error is: %s\n", err) } ``` This piece of code tries to resolve a non-existent domain on a non-existent DNS server as IP `4.3.2.1:404`. On Linux, you will get the following error: ```bash Error is: lookup stupid.entry.net on 127.0.0.53:53: dial udp 4.3.2.1:404: i/o timeout ``` That indicates that the system tried to reach the non-existent DNS server, and get back a timeout exception on it. However on Windows you will get: ```bash Error is: lookup stupid.entry.net: dnsquery: DNS name does not exist. ``` This indicates that the system ignored the dummy DNS server address, contacted the OS DNS resolver, that responded that the DNS name does not exist. One can see also the reason for this behavior on Windows on the `net` godoc, https://godoc.org/net, in particular this line in the module introduction: ``` On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery. ``` In fact, the pure Go DNS resolver is not applicable on Windows, the OS DNS resolver will be used, ignoring any customization. Several relevant discussions, in particular a proposal (not developed yet) to make the pure Go DNS resolver available on Windows: * golang/go#29621 * golang/go#33097 * golang/go#33086 To fix this, this PR makes Pebble switch to a different logic: * if `-dnsserver` is not set, use the default API to resolve the names * if `-dnsserver` is set, use a dedicated DNS client, to avoid to use the OS one both on Linux and Windows The DNS client is https://github.com/miekg/dns, a highly used and supported DNS library. With these modifications, integrations tests on Certbot are running correctly both on Linux and Windows.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Attempting to cross-compile a Windows binary from MacOS that does DNS-over-TCP, to do this I implemented a custom dialer that uses TCP (code excerpt is below). The dialer is ignored and the program still performs DNS resolution over UDP (verified with Wireshark), and does not return any errors. Setting
preferGo
totrue
orfalse
does not appear to have any affect. Note that while I'm compiling on my Mac (version/env info above) the code is running on Windows.CUSTOM DIALER CALLED
is not log'd.What did you expect to see?
Go attempt to establish a connection using the provided TCP Dialer, log.Printf statement, or an error.
What did you see instead?
DNS resolution over UDP, no errors.
The text was updated successfully, but these errors were encountered: