From e6258e65906434569e9d4a54ca0a80fcf40a5bda Mon Sep 17 00:00:00 2001 From: Cory Snider Date: Fri, 16 Dec 2022 15:03:55 -0500 Subject: [PATCH] libnetwork: reply SERVFAIL if DNS forwarding fails Fixes moby/moby issue 44575 Signed-off-by: Cory Snider --- libnetwork/resolver.go | 11 +++++----- libnetwork/resolver_test.go | 42 ++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/libnetwork/resolver.go b/libnetwork/resolver.go index e5ba96ca7e..39861d9b94 100644 --- a/libnetwork/resolver.go +++ b/libnetwork/resolver.go @@ -408,15 +408,14 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { resp = createRespMsg(query) } else { resp = r.forwardExtDNS(proto, maxSize, query) - if resp == nil { - return - } } - } else { - // The backend doesn't support proxying DNS requests. - resp = new(dns.Msg).SetRcode(query, dns.RcodeServerFailure) } + if resp == nil { + // We were unable to get an answer from any of the upstream DNS + // servers or the backend doesn't support proxying DNS requests. + resp = new(dns.Msg).SetRcode(query, dns.RcodeServerFailure) + } if err = w.WriteMsg(resp); err != nil { logrus.WithError(err).Errorf("[resolver] failed to write response") } diff --git a/libnetwork/resolver_test.go b/libnetwork/resolver_test.go index 59471082e5..8cd28a0c8a 100644 --- a/libnetwork/resolver_test.go +++ b/libnetwork/resolver_test.go @@ -417,17 +417,39 @@ func (noopDNSBackend) NdotsSet() bool { return false } func (noopDNSBackend) HandleQueryResp(name string, ip net.IP) {} -func TestReplySERVFAILOnInternalError(t *testing.T) { - defer redirectLogrusTo(t) +func TestReplySERVFAIL(t *testing.T) { + cases := []struct { + name string + q *dns.Msg + proxyDNS bool + }{ + { + name: "InternalError", + q: new(dns.Msg).SetQuestion("_sip._tcp.example.com.", dns.TypeSRV), + }, + { + name: "ProxyDNS=false", + q: new(dns.Msg).SetQuestion("example.com.", dns.TypeA), + }, + { + name: "ProxyDNS=true", // No extDNS servers configured -> no answer from any upstream + q: new(dns.Msg).SetQuestion("example.com.", dns.TypeA), + proxyDNS: true, + }, + } + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + defer redirectLogrusTo(t) - rsv := NewResolver("", false, badSRVDNSBackend{}).(*resolver) - w := &tstwriter{} - q := new(dns.Msg).SetQuestion("_sip._tcp.example.com.", dns.TypeSRV) - rsv.ServeDNS(w, q) - resp := w.GetResponse() - checkNonNullResponse(t, resp) - t.Log("Response: ", resp.String()) - checkDNSResponseCode(t, resp, dns.RcodeServerFailure) + rsv := NewResolver("", tt.proxyDNS, badSRVDNSBackend{}).(*resolver) + w := &tstwriter{} + rsv.ServeDNS(w, tt.q) + resp := w.GetResponse() + checkNonNullResponse(t, resp) + t.Log("Response: ", resp.String()) + checkDNSResponseCode(t, resp, dns.RcodeServerFailure) + }) + } } type badSRVDNSBackend struct{ noopDNSBackend }