diff --git a/plugin/forward/README.md b/plugin/forward/README.md index 911cfd697..00d8fead1 100644 --- a/plugin/forward/README.md +++ b/plugin/forward/README.md @@ -32,7 +32,8 @@ forward FROM TO... * **TO...** are the destination endpoints to forward to. The **TO** syntax allows you to specify a protocol, `tls://9.9.9.9`, `quic://94.140.14.14`, `https://9.9.9.9` (DoH defaults to `/dns-query` path) or `dns://` (or no protocol) for plain DNS. The number of upstreams is limited to 15. In addition to IP addresses and files (like `/etc/resolv.conf`), **TO** can also be - a hostname (e.g., `my-dns.svc.cluster.local`). Hostnames are resolved to IP addresses at startup. + a hostname (e.g., `my-dns.svc.cluster.local`). Hostnames are resolved to IP addresses at startup and are treated as + absolute DNS names even without a trailing dot; resolver search domains are not applied. See the `resolver` option below. Multiple upstreams are randomized (see `policy`) on first use. When a healthy proxy returns an error diff --git a/plugin/forward/resolve.go b/plugin/forward/resolve.go index b3b3b8cc9..70f19e497 100644 --- a/plugin/forward/resolve.go +++ b/plugin/forward/resolve.go @@ -195,9 +195,11 @@ func lookupHost(hostname string, resolvers []string) ([]string, error) { return dnsLookup(hostname, resolvers) } +var netLookupHost = net.LookupHost + // systemLookup resolves using the system resolver (/etc/resolv.conf). func systemLookup(hostname string) ([]string, error) { - ips, err := net.LookupHost(hostname) + ips, err := netLookupHost(dns.Fqdn(hostname)) if err != nil { return nil, err } diff --git a/plugin/forward/resolve_test.go b/plugin/forward/resolve_test.go index c03ca772f..bac065989 100644 --- a/plugin/forward/resolve_test.go +++ b/plugin/forward/resolve_test.go @@ -661,3 +661,25 @@ func TestResolverWithHCOptions(t *testing.T) { t.Errorf("expected opts %v, got %v", expectedOpts, f.opts) } } + +func TestSystemLookupUsesFQDN(t *testing.T) { + original := netLookupHost + t.Cleanup(func() { + netLookupHost = original + }) + + var gotHostname string + netLookupHost = func(hostname string) ([]string, error) { + gotHostname = hostname + return []string{"192.0.2.1"}, nil + } + + _, err := systemLookup("dns.google") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if gotHostname != "dns.google." { + t.Errorf("expected system resolver lookup for %q, got %q", "dns.google.", gotHostname) + } +}