diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/dnsserver/address.go | 8 | ||||
-rw-r--r-- | core/dnsserver/address_test.go | 5 | ||||
-rw-r--r-- | core/dnsserver/config.go | 6 | ||||
-rw-r--r-- | core/dnsserver/directives.go | 64 | ||||
-rw-r--r-- | core/dnsserver/register.go | 20 | ||||
-rw-r--r-- | core/dnsserver/server.go | 25 | ||||
-rw-r--r-- | core/dnsserver/server_test.go | 20 |
7 files changed, 61 insertions, 87 deletions
diff --git a/core/dnsserver/address.go b/core/dnsserver/address.go index e8ef13dbf..e17c9c706 100644 --- a/core/dnsserver/address.go +++ b/core/dnsserver/address.go @@ -1,6 +1,7 @@ package dnsserver import ( + "net" "strings" "github.com/coredns/coredns/plugin" @@ -11,7 +12,8 @@ import ( type zoneAddr struct { Zone string Port string - Transport string // dns, tls or grpc + Transport string // dns, tls or grpc + IPNet *net.IPNet // if reverse zone this hold the IPNet } // String return the string representation of z. @@ -50,7 +52,7 @@ func normalizeZone(str string) (zoneAddr, error) { str = str[len(TransportGRPC+"://"):] } - host, port, err := plugin.SplitHostPort(str) + host, port, ipnet, err := plugin.SplitHostPort(str) if err != nil { return zoneAddr{}, err } @@ -67,7 +69,7 @@ func normalizeZone(str string) (zoneAddr, error) { } } - return zoneAddr{Zone: dns.Fqdn(host), Port: port, Transport: trans}, nil + return zoneAddr{Zone: dns.Fqdn(host), Port: port, Transport: trans, IPNet: ipnet}, nil } // Supported transports. diff --git a/core/dnsserver/address_test.go b/core/dnsserver/address_test.go index 5bf0d4f3d..a2785f6aa 100644 --- a/core/dnsserver/address_test.go +++ b/core/dnsserver/address_test.go @@ -45,8 +45,9 @@ func TestNormalizeZoneReverse(t *testing.T) { {"10.0.0.0/24.:53", "dns://10.0.0.0/24.:53", false}, // non %8==0 netmasks - {"2003::53/67", "dns://2003::53/67.:53", false}, - {"10.0.0.0/25.", "dns://10.0.0.0/25.:53", false}, + {"2003::53/67", "dns://0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.2.ip6.arpa.:53", false}, + {"10.0.0.0/25.", "dns://10.0.0.0/25.:53", false}, // has dot + {"10.0.0.0/25", "dns://0.0.10.in-addr.arpa.:53", false}, } { addr, err := normalizeZone(test.input) actual := addr.String() diff --git a/core/dnsserver/config.go b/core/dnsserver/config.go index 0d25183c0..0f75a7f86 100644 --- a/core/dnsserver/config.go +++ b/core/dnsserver/config.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "github.com/coredns/coredns/plugin" + "github.com/mholt/caddy" ) @@ -29,6 +30,11 @@ type Config struct { // DNS-over-TLS or DNS-over-gRPC. Transport string + // If this function is not nil it will be used to further filter access + // to this handler. The primary use is to limit access to a reverse zone + // on a non-octet boundary, i.e. /17 + FilterFunc func(string) bool + // TLSConfig when listening for encrypted connections (gRPC, DNS-over-TLS). TLSConfig *tls.Config diff --git a/core/dnsserver/directives.go b/core/dnsserver/directives.go deleted file mode 100644 index bc37baf11..000000000 --- a/core/dnsserver/directives.go +++ /dev/null @@ -1,64 +0,0 @@ -package dnsserver - -import ( - "fmt" - "os" - "strings" -) - -// RegisterDevDirective splices name into the list of directives -// immediately before another directive. This function is ONLY -// for plugin development purposes! NEVER use it for a plugin -// that you are not currently building. If before is empty, -// the directive will be appended to the end of the list. -// -// It is imperative that directives execute in the proper -// order, and hard-coding the list of directives guarantees -// a correct, absolute order every time. This function is -// convenient when developing a plugin, but it does not -// guarantee absolute ordering. Multiple plugins registering -// directives with this function will lead to non- -// deterministic builds and buggy software. -// -// Directive names must be lower-cased and unique. Any errors -// here are fatal, and even successful calls print a message -// to stdout as a reminder to use it only in development. -func RegisterDevDirective(name, before string) { - if name == "" { - fmt.Println("[FATAL] Cannot register empty directive name") - os.Exit(1) - } - if strings.ToLower(name) != name { - fmt.Printf("[FATAL] %s: directive name must be lowercase\n", name) - os.Exit(1) - } - for _, dir := range directives { - if dir == name { - fmt.Printf("[FATAL] %s: directive name already exists\n", name) - os.Exit(1) - } - } - if before == "" { - directives = append(directives, name) - } else { - var found bool - for i, dir := range directives { - if dir == before { - directives = append(directives[:i], append([]string{name}, directives[i:]...)...) - found = true - break - } - } - if !found { - fmt.Printf("[FATAL] %s: directive not found\n", before) - os.Exit(1) - } - } - msg := fmt.Sprintf("Registered directive '%s' ", name) - if before == "" { - msg += "at end of list" - } else { - msg += fmt.Sprintf("before '%s'", before) - } - fmt.Printf("[INFO] %s\n", msg) -} diff --git a/core/dnsserver/register.go b/core/dnsserver/register.go index d10227a65..ebe4fc112 100644 --- a/core/dnsserver/register.go +++ b/core/dnsserver/register.go @@ -4,9 +4,11 @@ import ( "flag" "fmt" "net" + "strings" "time" "github.com/coredns/coredns/plugin" + "github.com/coredns/coredns/plugin/pkg/dnsutil" "github.com/mholt/caddy" "github.com/mholt/caddy/caddyfile" @@ -66,12 +68,28 @@ func (h *dnsContext) InspectServerBlocks(sourceFile string, serverBlocks []caddy } dups[za.String()] = za.String() - // Save the config to our master list, and key it for lookups + // Save the config to our master list, and key it for lookups. cfg := &Config{ Zone: za.Zone, Port: za.Port, Transport: za.Transport, } + if za.IPNet == nil { + h.saveConfig(za.String(), cfg) + continue + } + + ones, bits := za.IPNet.Mask.Size() + if (bits-ones)%8 != 0 { // only do this for non-octet bounderies + cfg.FilterFunc = func(s string) bool { + // TODO(miek): strings.ToLower! Slow and allocates new string. + addr := dnsutil.ExtractAddressFromReverse(strings.ToLower(s)) + if addr == "" { + return true + } + return za.IPNet.Contains(net.ParseIP(addr)) + } + } h.saveConfig(za.String(), cfg) } } diff --git a/core/dnsserver/server.go b/core/dnsserver/server.go index bb9a87a12..38d8600c7 100644 --- a/core/dnsserver/server.go +++ b/core/dnsserver/server.go @@ -40,7 +40,7 @@ type Server struct { classChaos bool // allow non-INET class queries } -// NewServer returns a new CoreDNS server and compiles all plugin in to it. By default CH class +// NewServer returns a new CoreDNS server and compiles all plugins in to it. By default CH class // queries are blocked unless the chaos or proxy is loaded. func NewServer(addr string, group []*Config) (*Server, error) { @@ -225,11 +225,22 @@ func (s *Server) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) if h, ok := s.zones[string(b[:l])]; ok { if r.Question[0].Qtype != dns.TypeDS { - rcode, _ := h.pluginChain.ServeDNS(ctx, w, r) - if !plugin.ClientWrite(rcode) { - DefaultErrorFunc(w, r, rcode) + if h.FilterFunc == nil { + rcode, _ := h.pluginChain.ServeDNS(ctx, w, r) + if !plugin.ClientWrite(rcode) { + DefaultErrorFunc(w, r, rcode) + } + return + } + // FilterFunc is set, call it to see if we should use this handler. + // This is given to full query name. + if h.FilterFunc(q) { + rcode, _ := h.pluginChain.ServeDNS(ctx, w, r) + if !plugin.ClientWrite(rcode) { + DefaultErrorFunc(w, r, rcode) + } + return } - return } // The type is DS, keep the handler, but keep on searching as maybe we are serving // the parent as well and the DS should be routed to it - this will probably *misroute* DS @@ -244,8 +255,8 @@ func (s *Server) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) } } - if dshandler != nil { - // DS request, and we found a zone, use the handler for the query + if r.Question[0].Qtype == dns.TypeDS && dshandler != nil { + // DS request, and we found a zone, use the handler for the query. rcode, _ := dshandler.pluginChain.ServeDNS(ctx, w, r) if !plugin.ClientWrite(rcode) { DefaultErrorFunc(w, r, rcode) diff --git a/core/dnsserver/server_test.go b/core/dnsserver/server_test.go index 16235fd7c..75f5b98f7 100644 --- a/core/dnsserver/server_test.go +++ b/core/dnsserver/server_test.go @@ -18,7 +18,7 @@ func (tp testPlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns. func (tp testPlugin) Name() string { return "testplugin" } -func testConfig(transport string) *Config { +func testConfig(transport string, p plugin.Handler) *Config { c := &Config{ Zone: "example.com.", Transport: transport, @@ -27,31 +27,31 @@ func testConfig(transport string) *Config { Debug: false, } - c.AddPlugin(func(next plugin.Handler) plugin.Handler { return testPlugin{} }) + c.AddPlugin(func(next plugin.Handler) plugin.Handler { return p }) return c } func TestNewServer(t *testing.T) { - _, err := NewServer("127.0.0.1:53", []*Config{testConfig("dns")}) + _, err := NewServer("127.0.0.1:53", []*Config{testConfig("dns", testPlugin{})}) if err != nil { - t.Errorf("Expected no error for NewServer, got %s.", err) + t.Errorf("Expected no error for NewServer, got %s", err) } - _, err = NewServergRPC("127.0.0.1:53", []*Config{testConfig("grpc")}) + _, err = NewServergRPC("127.0.0.1:53", []*Config{testConfig("grpc", testPlugin{})}) if err != nil { - t.Errorf("Expected no error for NewServergRPC, got %s.", err) + t.Errorf("Expected no error for NewServergRPC, got %s", err) } - _, err = NewServerTLS("127.0.0.1:53", []*Config{testConfig("tls")}) + _, err = NewServerTLS("127.0.0.1:53", []*Config{testConfig("tls", testPlugin{})}) if err != nil { - t.Errorf("Expected no error for NewServerTLS, got %s.", err) + t.Errorf("Expected no error for NewServerTLS, got %s", err) } } func BenchmarkCoreServeDNS(b *testing.B) { - s, err := NewServer("127.0.0.1:53", []*Config{testConfig("dns")}) + s, err := NewServer("127.0.0.1:53", []*Config{testConfig("dns", testPlugin{})}) if err != nil { - b.Errorf("Expected no error for NewServer, got %s.", err) + b.Errorf("Expected no error for NewServer, got %s", err) } ctx := context.TODO() |