diff --git a/plugin/auto/auto.go b/plugin/auto/auto.go index ec60bf23a..6330621be 100644 --- a/plugin/auto/auto.go +++ b/plugin/auto/auto.go @@ -62,6 +62,11 @@ func (a Auto) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i return dns.RcodeServerFailure, nil } + // If transfer is not loaded, we'll see these, answer with refused (no transfer allowed). + if state.QType() == dns.TypeAXFR || state.QType() == dns.TypeIXFR { + return dns.RcodeRefused, nil + } + answer, ns, extra, result := z.Lookup(ctx, state, qname) m := new(dns.Msg) diff --git a/plugin/file/file.go b/plugin/file/file.go index 1c586dd6d..0834ddc4d 100644 --- a/plugin/file/file.go +++ b/plugin/file/file.go @@ -47,6 +47,11 @@ func (f File) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i return dns.RcodeServerFailure, nil } + // If transfer is not loaded, we'll see these, answer with refused (no transfer allowed). + if state.QType() == dns.TypeAXFR || state.QType() == dns.TypeIXFR { + return dns.RcodeRefused, nil + } + // This is only for when we are a secondary zones. if r.Opcode == dns.OpcodeNotify { if z.isNotify(state) { diff --git a/plugin/file/xfr_test.go b/plugin/file/xfr_test.go index c02575556..f8d4cafcd 100644 --- a/plugin/file/xfr_test.go +++ b/plugin/file/xfr_test.go @@ -1,9 +1,15 @@ package file import ( + "context" "fmt" "strings" "testing" + + "github.com/coredns/coredns/plugin/pkg/dnstest" + "github.com/coredns/coredns/plugin/test" + + "github.com/miekg/dns" ) func ExampleZone_All() { @@ -41,3 +47,26 @@ func TestAllNewZone(t *testing.T) { t.Errorf("Expected %d records in empty zone, got %d", 0, len(records)) } } + +func TestAXFRWithOutTransferPlugin(t *testing.T) { + zone, err := Parse(strings.NewReader(dbMiekNL), testzone, "stdin", 0) + if err != nil { + t.Fatalf("Expected no error when reading zone, got %q", err) + } + + fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{testzone: zone}, Names: []string{testzone}}} + ctx := context.TODO() + + m := new(dns.Msg) + m.SetQuestion("miek.nl.", dns.TypeAXFR) + + rec := dnstest.NewRecorder(&test.ResponseWriter{}) + code, err := fm.ServeDNS(ctx, rec, m) + if err != nil { + t.Errorf("Expected no error, got %v", err) + return + } + if code != dns.RcodeRefused { + t.Errorf("Expecting REFUSED, got %d", code) + } +} diff --git a/plugin/kubernetes/handler.go b/plugin/kubernetes/handler.go index 57e9ac528..0bf4b12af 100644 --- a/plugin/kubernetes/handler.go +++ b/plugin/kubernetes/handler.go @@ -44,6 +44,8 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M records, extra, err = plugin.SRV(ctx, &k, zone, state, plugin.Options{}) case dns.TypeSOA: records, err = plugin.SOA(ctx, &k, zone, state, plugin.Options{}) + case dns.TypeAXFR, dns.TypeIXFR: + return dns.RcodeRefused, nil case dns.TypeNS: if state.Name() == zone { records, extra, err = plugin.NS(ctx, &k, zone, state, plugin.Options{})