From 619f1ddd05f95e2992fe7d64084fbfbb20f12744 Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Thu, 17 Apr 2025 10:51:06 +0100 Subject: [PATCH] Warn when no external DNS nameservers are found Since commit 925b484 ("No fallback nameservers for internal resolver"), if the host's resolv.conf has no nameservers and no servers are supplied via config, the internal resolver will not use Google's DNS - so the container will not be able to resolve external DNS requests. That can happen when container's are "restart-always" and the docker daemon starts before the host's DNS is configured. So, to highlight the issue (which may not be an error, but probably is), include a warning in the container's resolv.conf file. Also, log a warning - logs currently say "No non-localhost DNS nameservers are left in resolv.conf. Using default external servers". But, that's misleading because it's from an initial resolv.conf setup, before the internal resolver configured without those fallbacks - we'll drop the fallbacks completely once the default bridge has an internal resolver). Signed-off-by: Rob Murray --- libnetwork/internal/resolvconf/resolvconf.go | 11 +++++++---- libnetwork/internal/resolvconf/resolvconf_test.go | 4 ++++ .../testdata/TestRCTransformForIntNS/No_config.golden | 5 +++++ libnetwork/sandbox_dns_unix.go | 5 +++++ 4 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 libnetwork/internal/resolvconf/testdata/TestRCTransformForIntNS/No_config.golden diff --git a/libnetwork/internal/resolvconf/resolvconf.go b/libnetwork/internal/resolvconf/resolvconf.go index 5f82c339c7..4857aa161c 100644 --- a/libnetwork/internal/resolvconf/resolvconf.go +++ b/libnetwork/internal/resolvconf/resolvconf.go @@ -85,10 +85,10 @@ type metadata struct { SearchOverride bool OptionsOverride bool NDotsFrom string - UsedDefaultNS bool Transform string InvalidNSs []string ExtNameServers []ExtDNSEntry + Warnings []string } // Load opens a file at path and parses it as a resolv.conf file. @@ -229,7 +229,7 @@ func (rc *ResolvConf) TransformForLegacyNw(ipv6 bool) { if len(rc.nameServers) == 0 { log.G(context.TODO()).Info("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers") rc.nameServers = defaultNSAddrs(ipv6) - rc.md.UsedDefaultNS = true + rc.md.Warnings = append(rc.md.Warnings, "Used default nameservers.") } } @@ -280,6 +280,9 @@ func (rc *ResolvConf) TransformForIntNS( } rc.md.Transform = "internal resolver" + if len(rc.md.ExtNameServers) == 0 { + rc.md.Warnings = append(rc.md.Warnings, "NO EXTERNAL NAMESERVERS DEFINED") + } return append([]ExtDNSEntry(nil), rc.md.ExtNameServers...), nil } @@ -325,8 +328,8 @@ options {{join . " "}} {{join . "\n"}} {{end}}{{if .Comments}} # Based on host file: '{{.Md.SourcePath}}'{{with .Md.Transform}} ({{.}}){{end}} -{{if .Md.UsedDefaultNS -}} -# Used default nameservers. +{{range .Md.Warnings -}} +# {{.}} {{end -}} {{with .Md.ExtNameServers -}} # ExtServers: {{.}} diff --git a/libnetwork/internal/resolvconf/resolvconf_test.go b/libnetwork/internal/resolvconf/resolvconf_test.go index e3d43dcae4..35544f0a8a 100644 --- a/libnetwork/internal/resolvconf/resolvconf_test.go +++ b/libnetwork/internal/resolvconf/resolvconf_test.go @@ -410,6 +410,10 @@ func TestRCTransformForIntNS(t *testing.T) { reqdOptions: []string{"ndots:0", "attempts:3", "edns0", "trust-ad"}, expExtServers: []ExtDNSEntry{mke("127.0.0.53", true)}, }, + { + name: "No config", + input: "", + }, } for _, tc := range testcases { diff --git a/libnetwork/internal/resolvconf/testdata/TestRCTransformForIntNS/No_config.golden b/libnetwork/internal/resolvconf/testdata/TestRCTransformForIntNS/No_config.golden new file mode 100644 index 0000000000..253fecad24 --- /dev/null +++ b/libnetwork/internal/resolvconf/testdata/TestRCTransformForIntNS/No_config.golden @@ -0,0 +1,5 @@ +nameserver 127.0.0.11 + +# Based on host file: '/etc/resolv.conf' (internal resolver) +# NO EXTERNAL NAMESERVERS DEFINED +# Overrides: [] diff --git a/libnetwork/sandbox_dns_unix.go b/libnetwork/sandbox_dns_unix.go index 0257d1087b..6b4005e25a 100644 --- a/libnetwork/sandbox_dns_unix.go +++ b/libnetwork/sandbox_dns_unix.go @@ -219,6 +219,11 @@ func (sb *Sandbox) restoreHostsPath() { } func (sb *Sandbox) setExternalResolvers(entries []resolvconf.ExtDNSEntry) { + if len(entries) == 0 { + log.G(context.TODO()).WithField("cid", sb.ContainerID()).Warn("DNS resolver has no external nameservers") + sb.extDNS = nil + return + } sb.extDNS = make([]extDNSEntry, 0, len(entries)) for _, entry := range entries { sb.extDNS = append(sb.extDNS, extDNSEntry{