aboutsummaryrefslogtreecommitdiff
path: root/middleware
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2017-03-13 20:24:37 +0000
committerGravatar GitHub <noreply@github.com> 2017-03-13 20:24:37 +0000
commitbfaf9e0aecc74d4e6897cdb9c6ef51b4b21ffd4e (patch)
tree1eb571726beee206742fa69d6d97ef80d6dcd48f /middleware
parent4985d698e2d1e7c8335bff3b39c1d593cf1f02e6 (diff)
downloadcoredns-bfaf9e0aecc74d4e6897cdb9c6ef51b4b21ffd4e.tar.gz
coredns-bfaf9e0aecc74d4e6897cdb9c6ef51b4b21ffd4e.tar.zst
coredns-bfaf9e0aecc74d4e6897cdb9c6ef51b4b21ffd4e.zip
core: add more transports (#574)
* core: add listening for other protocols Allow CoreDNS to listen for TLS request coming over port 853. This can be enabled with `tls://` in the config file. Implement listening for grps:// as well. a Corefile like: ~~~ . tls://.:1853 { whoami tls } ~~~ Means we listen on 1853 for tls requests, the `tls` config item allows configuration for TLS parameters. We *might* be tempted to use Caddy's Let's Encrypt implementation here. * Refactor coredns/grpc into CoreDNS This makes gRPC a first class citizen in CoreDNS. Add defines as being just another server. * some cleanups * unexport the servers * Move protobuf dir * Hook up TLS properly * Fix test * listen for TLS as well. README updates * disable test, fix package * fix test * Fix tests * Fix remaining test * Some tests * Make the test work * Add grpc test from #580 * fix crash * Fix tests * Close conn * README cleanups * README * link RFC
Diffstat (limited to 'middleware')
-rw-r--r--middleware/erratic/erratic.go2
-rw-r--r--middleware/normalize.go27
-rw-r--r--middleware/proxy/grpc.go7
-rw-r--r--middleware/proxy/pb/dns.pb.go140
-rw-r--r--middleware/proxy/pb/dns.proto12
-rw-r--r--middleware/reverse/setup.go3
-rw-r--r--middleware/root/root.go5
-rw-r--r--middleware/root/root_test.go2
-rw-r--r--middleware/tls/README.md13
-rw-r--r--middleware/tls/tls.go37
-rw-r--r--middleware/tls/tls_test.go44
11 files changed, 126 insertions, 166 deletions
diff --git a/middleware/erratic/erratic.go b/middleware/erratic/erratic.go
index 3aec36798..a3fbb2e8e 100644
--- a/middleware/erratic/erratic.go
+++ b/middleware/erratic/erratic.go
@@ -38,7 +38,7 @@ func (e *Erratic) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
m.Authoritative = true
// small dance to copy rrA or rrAAAA into a non-pointer var that allows us to overwrite the ownername
- // in a non-racy manor.
+ // in a non-racy way.
switch state.QType() {
case dns.TypeA:
rr := *(rrA.(*dns.A))
diff --git a/middleware/normalize.go b/middleware/normalize.go
index 87f3ce703..77ef97993 100644
--- a/middleware/normalize.go
+++ b/middleware/normalize.go
@@ -7,6 +7,8 @@ import (
"github.com/miekg/dns"
)
+// See core/dnsserver/address.go - we should unify these two impls.
+
// Zones respresents a lists of zone names.
type Zones []string
@@ -56,12 +58,24 @@ type (
)
// Normalize will return the host portion of host, stripping
-// of any port. The host will also be fully qualified and lowercased.
+// of any port or transport. The host will also be fully qualified and lowercased.
func (h Host) Normalize() string {
+
+ s := string(h)
+
+ switch {
+ case strings.HasPrefix(s, TransportTLS+"://"):
+ s = s[len(TransportTLS+"://"):]
+ case strings.HasPrefix(s, TransportDNS+"://"):
+ s = s[len(TransportDNS+"://"):]
+ case strings.HasPrefix(s, TransportGRPC+"://"):
+ s = s[len(TransportGRPC+"://"):]
+ }
+
// separate host and port
- host, _, err := net.SplitHostPort(string(h))
+ host, _, err := net.SplitHostPort(s)
if err != nil {
- host, _, _ = net.SplitHostPort(string(h) + ":")
+ host, _, _ = net.SplitHostPort(s + ":")
}
return Name(host).Normalize()
}
@@ -77,3 +91,10 @@ func (a Addr) Normalize() string {
// TODO(miek): lowercase it?
return net.JoinHostPort(addr, port)
}
+
+// Duplicated from core/dnsserver/address.go !
+const (
+ TransportDNS = "dns"
+ TransportTLS = "tls"
+ TransportGRPC = "grpc"
+)
diff --git a/middleware/proxy/grpc.go b/middleware/proxy/grpc.go
index c480d3cf2..d3ed14ccd 100644
--- a/middleware/proxy/grpc.go
+++ b/middleware/proxy/grpc.go
@@ -5,16 +5,13 @@ import (
"crypto/tls"
"log"
- "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
-
- "github.com/coredns/coredns/middleware/proxy/pb"
"github.com/coredns/coredns/middleware/trace"
+ "github.com/coredns/coredns/pb"
"github.com/coredns/coredns/request"
+ "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
"github.com/miekg/dns"
-
opentracing "github.com/opentracing/opentracing-go"
-
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
diff --git a/middleware/proxy/pb/dns.pb.go b/middleware/proxy/pb/dns.pb.go
deleted file mode 100644
index 3117102ab..000000000
--- a/middleware/proxy/pb/dns.pb.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Code generated by protoc-gen-go.
-// source: dns.proto
-// DO NOT EDIT!
-
-/*
-Package pb is a generated protocol buffer package.
-
-It is generated from these files:
- dns.proto
-
-It has these top-level messages:
- DnsPacket
-*/
-package pb
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import (
- context "golang.org/x/net/context"
- grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type DnsPacket struct {
- Msg []byte `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
-}
-
-func (m *DnsPacket) Reset() { *m = DnsPacket{} }
-func (m *DnsPacket) String() string { return proto.CompactTextString(m) }
-func (*DnsPacket) ProtoMessage() {}
-func (*DnsPacket) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-func (m *DnsPacket) GetMsg() []byte {
- if m != nil {
- return m.Msg
- }
- return nil
-}
-
-func init() {
- proto.RegisterType((*DnsPacket)(nil), "coredns.dns.DnsPacket")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// Client API for DnsService service
-
-type DnsServiceClient interface {
- Query(ctx context.Context, in *DnsPacket, opts ...grpc.CallOption) (*DnsPacket, error)
-}
-
-type dnsServiceClient struct {
- cc *grpc.ClientConn
-}
-
-func NewDnsServiceClient(cc *grpc.ClientConn) DnsServiceClient {
- return &dnsServiceClient{cc}
-}
-
-func (c *dnsServiceClient) Query(ctx context.Context, in *DnsPacket, opts ...grpc.CallOption) (*DnsPacket, error) {
- out := new(DnsPacket)
- err := grpc.Invoke(ctx, "/coredns.dns.DnsService/Query", in, out, c.cc, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-// Server API for DnsService service
-
-type DnsServiceServer interface {
- Query(context.Context, *DnsPacket) (*DnsPacket, error)
-}
-
-func RegisterDnsServiceServer(s *grpc.Server, srv DnsServiceServer) {
- s.RegisterService(&_DnsService_serviceDesc, srv)
-}
-
-func _DnsService_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(DnsPacket)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(DnsServiceServer).Query(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: "/coredns.dns.DnsService/Query",
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(DnsServiceServer).Query(ctx, req.(*DnsPacket))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-var _DnsService_serviceDesc = grpc.ServiceDesc{
- ServiceName: "coredns.dns.DnsService",
- HandlerType: (*DnsServiceServer)(nil),
- Methods: []grpc.MethodDesc{
- {
- MethodName: "Query",
- Handler: _DnsService_Query_Handler,
- },
- },
- Streams: []grpc.StreamDesc{},
- Metadata: "dns.proto",
-}
-
-func init() { proto.RegisterFile("dns.proto", fileDescriptor0) }
-
-var fileDescriptor0 = []byte{
- // 120 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0xc9, 0x2b, 0xd6,
- 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4e, 0xce, 0x2f, 0x4a, 0x05, 0x71, 0x53, 0xf2, 0x8a,
- 0x95, 0x64, 0xb9, 0x38, 0x5d, 0xf2, 0x8a, 0x03, 0x12, 0x93, 0xb3, 0x53, 0x4b, 0x84, 0x04, 0xb8,
- 0x98, 0x73, 0x8b, 0xd3, 0x25, 0x18, 0x15, 0x18, 0x35, 0x78, 0x82, 0x40, 0x4c, 0x23, 0x57, 0x2e,
- 0x2e, 0x97, 0xbc, 0xe2, 0xe0, 0xd4, 0xa2, 0xb2, 0xcc, 0xe4, 0x54, 0x21, 0x73, 0x2e, 0xd6, 0xc0,
- 0xd2, 0xd4, 0xa2, 0x4a, 0x21, 0x31, 0x3d, 0x24, 0x33, 0xf4, 0xe0, 0x06, 0x48, 0xe1, 0x10, 0x77,
- 0x62, 0x89, 0x62, 0x2a, 0x48, 0x4a, 0x62, 0x03, 0xdb, 0x6f, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff,
- 0xf5, 0xd1, 0x3f, 0x26, 0x8c, 0x00, 0x00, 0x00,
-}
diff --git a/middleware/proxy/pb/dns.proto b/middleware/proxy/pb/dns.proto
deleted file mode 100644
index 8461f01e6..000000000
--- a/middleware/proxy/pb/dns.proto
+++ /dev/null
@@ -1,12 +0,0 @@
-syntax = "proto3";
-
-package coredns.dns;
-option go_package = "pb";
-
-message DnsPacket {
- bytes msg = 1;
-}
-
-service DnsService {
- rpc Query (DnsPacket) returns (DnsPacket);
-}
diff --git a/middleware/reverse/setup.go b/middleware/reverse/setup.go
index ea94aea7d..56ab620fa 100644
--- a/middleware/reverse/setup.go
+++ b/middleware/reverse/setup.go
@@ -40,8 +40,7 @@ func reverseParse(c *caddy.Controller) (nets networks, fall bool, err error) {
zones := make([]string, len(c.ServerBlockKeys))
for i, str := range c.ServerBlockKeys {
- host, _, _ := net.SplitHostPort(str)
- zones[i] = strings.ToLower(host)
+ zones[i] = middleware.Host(str).Normalize()
}
for c.Next() {
diff --git a/middleware/root/root.go b/middleware/root/root.go
index 6a26fbd1a..d03ecb8a4 100644
--- a/middleware/root/root.go
+++ b/middleware/root/root.go
@@ -5,6 +5,7 @@ import (
"os"
"github.com/coredns/coredns/core/dnsserver"
+ "github.com/coredns/coredns/middleware"
"github.com/mholt/caddy"
)
@@ -21,7 +22,7 @@ func setup(c *caddy.Controller) error {
for c.Next() {
if !c.NextArg() {
- return c.ArgErr()
+ return middleware.Error("root", c.ArgErr())
}
config.Root = c.Val()
}
@@ -34,7 +35,7 @@ func setup(c *caddy.Controller) error {
// But make sure the user knows!
log.Printf("[WARNING] Root path does not exist: %s", config.Root)
} else {
- return c.Errf("Unable to access root path '%s': %v", config.Root, err)
+ return middleware.Error("root", c.Errf("unable to access root path '%s': %v", config.Root, err))
}
}
diff --git a/middleware/root/root_test.go b/middleware/root/root_test.go
index 0a58c69bf..6823301f8 100644
--- a/middleware/root/root_test.go
+++ b/middleware/root/root_test.go
@@ -19,7 +19,7 @@ func TestRoot(t *testing.T) {
// Predefined error substrings
parseErrContent := "Parse error:"
- unableToAccessErrContent := "Unable to access root path"
+ unableToAccessErrContent := "unable to access root path"
existingDirPath, err := getTempDirPath()
if err != nil {
diff --git a/middleware/tls/README.md b/middleware/tls/README.md
new file mode 100644
index 000000000..6070257d3
--- /dev/null
+++ b/middleware/tls/README.md
@@ -0,0 +1,13 @@
+# tls
+
+*tls* extra TLS configuration.
+
+## Syntax
+
+~~~ txt
+tls [STUFF]
+~~~
+
+**STUFF** is things you'll need to configure TLS.
+
+## Examples
diff --git a/middleware/tls/tls.go b/middleware/tls/tls.go
new file mode 100644
index 000000000..2e2586ce5
--- /dev/null
+++ b/middleware/tls/tls.go
@@ -0,0 +1,37 @@
+package tls
+
+import (
+ "github.com/coredns/coredns/core/dnsserver"
+ "github.com/coredns/coredns/middleware"
+ "github.com/coredns/coredns/middleware/pkg/tls"
+
+ "github.com/mholt/caddy"
+)
+
+func init() {
+ caddy.RegisterPlugin("tls", caddy.Plugin{
+ ServerType: "dns",
+ Action: setup,
+ })
+}
+
+func setup(c *caddy.Controller) error {
+ config := dnsserver.GetConfig(c)
+
+ if config.TLSConfig != nil {
+ return middleware.Error("tls", c.Errf("TLS already configured for this server instance"))
+ }
+
+ for c.Next() {
+ args := c.RemainingArgs()
+ if len(args) != 3 {
+ return middleware.Error("tls", c.ArgErr())
+ }
+ tls, err := tls.NewTLSConfig(args[0], args[1], args[2])
+ if err != nil {
+ return middleware.Error("tls", c.ArgErr())
+ }
+ config.TLSConfig = tls
+ }
+ return nil
+}
diff --git a/middleware/tls/tls_test.go b/middleware/tls/tls_test.go
new file mode 100644
index 000000000..2374d772c
--- /dev/null
+++ b/middleware/tls/tls_test.go
@@ -0,0 +1,44 @@
+package tls
+
+import (
+ "io/ioutil"
+ "log"
+ "strings"
+ "testing"
+
+ "github.com/mholt/caddy"
+)
+
+func TestTLS(t *testing.T) {
+ log.SetOutput(ioutil.Discard)
+
+ tests := []struct {
+ input string
+ shouldErr bool
+ expectedRoot string // expected root, set to the controller. Empty for negative cases.
+ expectedErrContent string // substring from the expected error. Empty for positive cases.
+ }{
+ // positive
+ // negative
+ }
+
+ for i, test := range tests {
+ c := caddy.NewTestController("dns", test.input)
+ err := setup(c)
+ //cfg := dnsserver.GetConfig(c)
+
+ if test.shouldErr && err == nil {
+ t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input)
+ }
+
+ if err != nil {
+ if !test.shouldErr {
+ t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err)
+ }
+
+ if !strings.Contains(err.Error(), test.expectedErrContent) {
+ t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input)
+ }
+ }
+ }
+}