From 7aaed71b92cbdddfbc13ddc6ce618bb083502c42 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Mon, 11 May 2020 16:51:02 +0200 Subject: [PATCH] Fix query for SOA record for delegated zone (#3875) Addresses a bug in the file plugin where SOA queries to zone delegations are inappropriately returned the SOA for the delegating zone, and not a downward referral to the delegated zone. Here is an example of what I believe the expected downward referral in response to a SOA query for a delegated zone should be (note that no SOA record is returned): ~~~ ; <<>> DiG 9.11.3-1ubuntu1.5-Ubuntu <<>> @k.root-servers.net. miek.nl. SOA ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58381 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 3, ADDITIONAL: 7 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;miek.nl. IN SOA ;; AUTHORITY SECTION: nl. 172800 IN NS ns1.dns.nl. nl. 172800 IN NS ns2.dns.nl. nl. 172800 IN NS ns3.dns.nl. ;; ADDITIONAL SECTION: ns1.dns.nl. 172800 IN A 194.0.28.53 ns2.dns.nl. 172800 IN A 194.146.106.42 ns3.dns.nl. 172800 IN A 194.0.25.24 ns1.dns.nl. 172800 IN AAAA 2001:678:2c:0:194:0:28:53 ns2.dns.nl. 172800 IN AAAA 2001:67c:1010:10::53 ns3.dns.nl. 172800 IN AAAA 2001:678:20::24 ~~~ See #3852 for the original fix. Modified clouddns/route53 and removed the faulty tests there. Signed-off-by: Miek Gieben --- plugin/clouddns/clouddns_test.go | 24 +++++++++--------------- plugin/file/delegation_test.go | 11 +++++++++++ plugin/file/lookup.go | 16 +++++++++------- plugin/route53/route53_test.go | 20 +++++++------------- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/plugin/clouddns/clouddns_test.go b/plugin/clouddns/clouddns_test.go index dafd65bba..7d9db85f3 100644 --- a/plugin/clouddns/clouddns_test.go +++ b/plugin/clouddns/clouddns_test.go @@ -10,7 +10,7 @@ import ( "github.com/coredns/coredns/plugin/pkg/fall" "github.com/coredns/coredns/plugin/pkg/upstream" "github.com/coredns/coredns/plugin/test" - crequest "github.com/coredns/coredns/request" + "github.com/coredns/coredns/request" "github.com/miekg/dns" gcp "google.golang.org/api/dns/v1" @@ -138,7 +138,7 @@ func TestCloudDNS(t *testing.T) { r.Fall = fall.Zero r.Fall.SetZonesFromArgs([]string{"gov."}) r.Next = test.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - state := crequest.Request{W: w, Req: r} + state := request.Request{W: w, Req: r} qname := state.Name() m := new(dns.Msg) rcode := dns.RcodeServerFailure @@ -209,32 +209,26 @@ func TestCloudDNS(t *testing.T) { wantAnswer: []string{"sample.example.org. 300 IN CNAME example.org."}, }, // 5. Explicit SOA query for example.org. - { - qname: "example.org", - qtype: dns.TypeSOA, - wantAnswer: []string{"org. 300 IN SOA ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 300 259200 300"}, - }, - // 6. Explicit SOA query for example.org. { qname: "example.org", qtype: dns.TypeNS, wantNS: []string{"org. 300 IN SOA ns-cloud-c1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 300 259200 300"}, }, - // 7. AAAA query for split-example.org must return NODATA. + // 6. AAAA query for split-example.org must return NODATA. { qname: "split-example.gov", qtype: dns.TypeAAAA, wantRetCode: dns.RcodeSuccess, wantNS: []string{"org. 300 IN SOA ns-cloud-c1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 300 259200 300"}, }, - // 8. Zone not configured. + // 7. Zone not configured. { qname: "badexample.com", qtype: dns.TypeA, wantRetCode: dns.RcodeServerFailure, wantMsgRCode: dns.RcodeServerFailure, }, - // 9. No record found. Return SOA record. + // 8. No record found. Return SOA record. { qname: "bad.org", qtype: dns.TypeA, @@ -242,25 +236,25 @@ func TestCloudDNS(t *testing.T) { wantMsgRCode: dns.RcodeNameError, wantNS: []string{"org. 300 IN SOA ns-cloud-c1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 300 259200 300"}, }, - // 10. No record found. Fallthrough. + // 9. No record found. Fallthrough. { qname: "example.gov", qtype: dns.TypeA, wantAnswer: []string{"example.gov. 300 IN A 2.4.6.8"}, }, - // 11. other-zone.example.org is stored in a different hosted zone. success + // 10. other-zone.example.org is stored in a different hosted zone. success { qname: "other-example.org", qtype: dns.TypeA, wantAnswer: []string{"other-example.org. 300 IN A 3.5.7.9"}, }, - // 12. split-example.org only has A record. Expect NODATA. + // 11. split-example.org only has A record. Expect NODATA. { qname: "split-example.org", qtype: dns.TypeAAAA, wantNS: []string{"org. 300 IN SOA ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 300 259200 300"}, }, - // 13. *.www.example.org is a wildcard CNAME to www.example.org. + // 12. *.www.example.org is a wildcard CNAME to www.example.org. { qname: "a.www.example.org", qtype: dns.TypeA, diff --git a/plugin/file/delegation_test.go b/plugin/file/delegation_test.go index a317b827b..a6da6215c 100644 --- a/plugin/file/delegation_test.go +++ b/plugin/file/delegation_test.go @@ -56,6 +56,17 @@ var delegationTestCases = []test.Case{ test.AAAA("a.delegated.miek.nl. 1800 IN AAAA 2a01:7e00::f03c:91ff:fef1:6735"), }, }, + { + Qname: "foo.delegated.miek.nl.", Qtype: dns.TypeSOA, + Ns: []dns.RR{ + test.NS("delegated.miek.nl. 1800 IN NS a.delegated.miek.nl."), + test.NS("delegated.miek.nl. 1800 IN NS ns-ext.nlnetlabs.nl."), + }, + Extra: []dns.RR{ + test.A("a.delegated.miek.nl. 1800 IN A 139.162.196.78"), + test.AAAA("a.delegated.miek.nl. 1800 IN AAAA 2a01:7e00::f03c:91ff:fef1:6735"), + }, + }, { Qname: "miek.nl.", Qtype: dns.TypeSOA, Answer: []dns.RR{ diff --git a/plugin/file/lookup.go b/plugin/file/lookup.go index 3d8d899df..28da3d4d0 100644 --- a/plugin/file/lookup.go +++ b/plugin/file/lookup.go @@ -44,13 +44,15 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string) return nil, nil, nil, ServerFailure } - if qtype == dns.TypeSOA { - return ap.soa(do), ap.ns(do), nil, Success - } - if qtype == dns.TypeNS && qname == z.origin { - nsrrs := ap.ns(do) - glue := tr.Glue(nsrrs, do) // technically this isn't glue - return nsrrs, nil, glue, Success + if qname == z.origin { + switch qtype { + case dns.TypeSOA: + return ap.soa(do), ap.ns(do), nil, Success + case dns.TypeNS: + nsrrs := ap.ns(do) + glue := tr.Glue(nsrrs, do) // technically this isn't glue + return nsrrs, nil, glue, Success + } } var ( diff --git a/plugin/route53/route53_test.go b/plugin/route53/route53_test.go index aa5c82b9c..4b3fe1ebe 100644 --- a/plugin/route53/route53_test.go +++ b/plugin/route53/route53_test.go @@ -165,32 +165,26 @@ func TestRoute53(t *testing.T) { wantAnswer: []string{"sample.example.org. 300 IN CNAME example.org."}, }, // 5. Explicit SOA query for example.org. - { - qname: "example.org", - qtype: dns.TypeSOA, - wantAnswer: []string{"org. 300 IN SOA ns-15.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, - }, - // 6. Explicit SOA query for example.org. { qname: "example.org", qtype: dns.TypeNS, wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, }, - // 7. AAAA query for split-example.org must return NODATA. + // 6. AAAA query for split-example.org must return NODATA. { qname: "split-example.gov", qtype: dns.TypeAAAA, wantRetCode: dns.RcodeSuccess, wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, }, - // 8. Zone not configured. + // 7. Zone not configured. { qname: "badexample.com", qtype: dns.TypeA, wantRetCode: dns.RcodeServerFailure, wantMsgRCode: dns.RcodeServerFailure, }, - // 9. No record found. Return SOA record. + // 8. No record found. Return SOA record. { qname: "bad.org", qtype: dns.TypeA, @@ -198,25 +192,25 @@ func TestRoute53(t *testing.T) { wantMsgRCode: dns.RcodeNameError, wantNS: []string{"org. 300 IN SOA ns-1536.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, }, - // 10. No record found. Fallthrough. + // 9. No record found. Fallthrough. { qname: "example.gov", qtype: dns.TypeA, wantAnswer: []string{"example.gov. 300 IN A 2.4.6.8"}, }, - // 11. other-zone.example.org is stored in a different hosted zone. success + // 10. other-zone.example.org is stored in a different hosted zone. success { qname: "other-example.org", qtype: dns.TypeA, wantAnswer: []string{"other-example.org. 300 IN A 3.5.7.9"}, }, - // 12. split-example.org only has A record. Expect NODATA. + // 11. split-example.org only has A record. Expect NODATA. { qname: "split-example.org", qtype: dns.TypeAAAA, wantNS: []string{"org. 300 IN SOA ns-15.awsdns-00.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"}, }, - // 13. *.www.example.org is a wildcard CNAME to www.example.org. + // 12. *.www.example.org is a wildcard CNAME to www.example.org. { qname: "a.www.example.org", qtype: dns.TypeA,