diff options
author | 2017-03-13 20:24:37 +0000 | |
---|---|---|
committer | 2017-03-13 20:24:37 +0000 | |
commit | bfaf9e0aecc74d4e6897cdb9c6ef51b4b21ffd4e (patch) | |
tree | 1eb571726beee206742fa69d6d97ef80d6dcd48f /middleware | |
parent | 4985d698e2d1e7c8335bff3b39c1d593cf1f02e6 (diff) | |
download | coredns-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.go | 2 | ||||
-rw-r--r-- | middleware/normalize.go | 27 | ||||
-rw-r--r-- | middleware/proxy/grpc.go | 7 | ||||
-rw-r--r-- | middleware/proxy/pb/dns.pb.go | 140 | ||||
-rw-r--r-- | middleware/proxy/pb/dns.proto | 12 | ||||
-rw-r--r-- | middleware/reverse/setup.go | 3 | ||||
-rw-r--r-- | middleware/root/root.go | 5 | ||||
-rw-r--r-- | middleware/root/root_test.go | 2 | ||||
-rw-r--r-- | middleware/tls/README.md | 13 | ||||
-rw-r--r-- | middleware/tls/tls.go | 37 | ||||
-rw-r--r-- | middleware/tls/tls_test.go | 44 |
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) + } + } + } +} |