plugin/forward: Treat forward upstream hostnames as absolute FQDNs to avoid search-domain resolution. (#8563)

This commit is contained in:
Yong Tang
2026-09-19 21:37:34 -07:00
committed by GitHub
parent ce5ee05bee
commit 5cb7cdc914
3 changed files with 27 additions and 2 deletions

View File

@@ -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

View File

@@ -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
}

View File

@@ -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)
}
}