mirror of
https://github.com/coredns/coredns.git
synced 2025-11-24 04:34:01 -05:00
Add middleware/dnssec (#133)
This adds an online dnssec middleware. The middleware will sign responses on the fly. Negative responses are signed with NSEC black lies.
This commit is contained in:
@@ -27,8 +27,7 @@ func cacheParse(c *Controller) (int, []string, error) {
|
||||
for c.Next() {
|
||||
if c.Val() == "cache" {
|
||||
// cache [ttl] [zones..]
|
||||
|
||||
origins := []string{c.ServerBlockHosts[c.ServerBlockHostIndex]}
|
||||
origins := c.ServerBlockHosts
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
origins = args
|
||||
@@ -39,7 +38,7 @@ func cacheParse(c *Controller) (int, []string, error) {
|
||||
origins = origins[1:]
|
||||
if len(origins) == 0 {
|
||||
// There was *only* the ttl, revert back to server block
|
||||
origins = []string{c.ServerBlockHosts[c.ServerBlockHostIndex]}
|
||||
origins = c.ServerBlockHosts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func TestChaos(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
shouldErr bool
|
||||
expectedVersion string // expected veresion.
|
||||
expectedVersion string // expected version.
|
||||
expectedAuthor string // expected author (string, although we get a map).
|
||||
expectedErrContent string // substring from the expected error. Empty for positive cases.
|
||||
}{
|
||||
|
||||
79
core/setup/dnssec.go
Normal file
79
core/setup/dnssec.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"path"
|
||||
|
||||
"github.com/miekg/coredns/middleware"
|
||||
"github.com/miekg/coredns/middleware/dnssec"
|
||||
)
|
||||
|
||||
// Dnssec sets up the dnssec middleware.
|
||||
func Dnssec(c *Controller) (middleware.Middleware, error) {
|
||||
zones, keys, err := dnssecParse(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return func(next middleware.Handler) middleware.Handler {
|
||||
return dnssec.NewDnssec(zones, keys, next)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func dnssecParse(c *Controller) ([]string, []*dnssec.DNSKEY, error) {
|
||||
zones := []string{}
|
||||
|
||||
keys := []*dnssec.DNSKEY{}
|
||||
for c.Next() {
|
||||
if c.Val() == "dnssec" {
|
||||
// dnssec [zones...]
|
||||
zones = c.ServerBlockHosts
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
zones = args
|
||||
}
|
||||
|
||||
for c.NextBlock() {
|
||||
k, e := keyParse(c)
|
||||
if e != nil {
|
||||
// TODO(miek): Log and drop or something? stop startup?
|
||||
continue
|
||||
}
|
||||
keys = append(keys, k...)
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, _ := range zones {
|
||||
zones[i] = middleware.Host(zones[i]).Normalize()
|
||||
}
|
||||
return zones, keys, nil
|
||||
}
|
||||
|
||||
func keyParse(c *Controller) ([]*dnssec.DNSKEY, error) {
|
||||
keys := []*dnssec.DNSKEY{}
|
||||
|
||||
what := c.Val()
|
||||
if !c.NextArg() {
|
||||
return nil, c.ArgErr()
|
||||
}
|
||||
value := c.Val()
|
||||
switch what {
|
||||
case "key":
|
||||
if value == "file" {
|
||||
ks := c.RemainingArgs()
|
||||
for _, k := range ks {
|
||||
// Kmiek.nl.+013+26205.key, handle .private or without extension: Kmiek.nl.+013+26205
|
||||
ext := path.Ext(k) // TODO(miek): test things like .key
|
||||
base := k
|
||||
if len(ext) > 0 {
|
||||
base = k[:len(k)-len(ext)]
|
||||
}
|
||||
k, err := dnssec.ParseKeyFile(base+".key", base+".private")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
54
core/setup/dnssec_test.go
Normal file
54
core/setup/dnssec_test.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDnssec(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
shouldErr bool
|
||||
expectedZones []string
|
||||
expectedKeys []string
|
||||
expectedErrContent string
|
||||
}{
|
||||
{
|
||||
`dnssec`, false, nil, nil, "",
|
||||
},
|
||||
{
|
||||
`dnssec miek.nl`, false, []string{"miek.nl."}, nil, "",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
c := NewTestController(test.input)
|
||||
zones, keys, err := dnssecParse(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)
|
||||
}
|
||||
}
|
||||
if !test.shouldErr {
|
||||
for i, z := range test.expectedZones {
|
||||
if zones[i] != z {
|
||||
t.Errorf("Dnssec not correctly set for input %s. Expected: %s, actual: %s", test.input, z, zones[i])
|
||||
}
|
||||
}
|
||||
for i, k := range test.expectedKeys {
|
||||
if k != keys[i].K.Header().Name {
|
||||
t.Errorf("Dnssec not correctly set for input %s. Expected: '%s', actual: '%s'", test.input, k, keys[i].K.Header().Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/miekg/coredns/middleware"
|
||||
"github.com/miekg/coredns/middleware/etcd"
|
||||
"github.com/miekg/coredns/middleware/etcd/singleflight"
|
||||
"github.com/miekg/coredns/middleware/proxy"
|
||||
"github.com/miekg/coredns/middleware/singleflight"
|
||||
|
||||
etcdc "github.com/coreos/etcd/client"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -46,7 +46,7 @@ func fileParse(c *Controller) (file.Zones, error) {
|
||||
}
|
||||
fileName := c.Val()
|
||||
|
||||
origins := []string{c.ServerBlockHosts[c.ServerBlockHostIndex]}
|
||||
origins := c.ServerBlockHosts
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
origins = args
|
||||
@@ -54,7 +54,7 @@ func fileParse(c *Controller) (file.Zones, error) {
|
||||
|
||||
reader, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
return file.Zones{}, err
|
||||
continue
|
||||
}
|
||||
|
||||
for i, _ := range origins {
|
||||
@@ -68,7 +68,7 @@ func fileParse(c *Controller) (file.Zones, error) {
|
||||
|
||||
noReload := false
|
||||
for c.NextBlock() {
|
||||
t, _, e := parseTransfer(c)
|
||||
t, _, e := transferParse(c)
|
||||
if e != nil {
|
||||
return file.Zones{}, e
|
||||
}
|
||||
@@ -89,8 +89,8 @@ func fileParse(c *Controller) (file.Zones, error) {
|
||||
return file.Zones{Z: z, Names: names}, nil
|
||||
}
|
||||
|
||||
// transfer to [address...]
|
||||
func parseTransfer(c *Controller) (tos, froms []string, err error) {
|
||||
// transferParse parses transfer statements: 'transfer to [address...]'.
|
||||
func transferParse(c *Controller) (tos, froms []string, err error) {
|
||||
what := c.Val()
|
||||
if !c.NextArg() {
|
||||
return nil, nil, c.ArgErr()
|
||||
|
||||
@@ -7,10 +7,7 @@ import (
|
||||
"github.com/miekg/coredns/middleware/metrics"
|
||||
)
|
||||
|
||||
const (
|
||||
path = "/metrics"
|
||||
addr = "localhost:9135" // 9153 is occupied by bind_exporter
|
||||
)
|
||||
const addr = "localhost:9135" // 9153 is occupied by bind_exporter
|
||||
|
||||
var once sync.Once
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ func secondaryParse(c *Controller) (file.Zones, error) {
|
||||
for c.Next() {
|
||||
if c.Val() == "secondary" {
|
||||
// secondary [origin]
|
||||
origins := []string{c.ServerBlockHosts[c.ServerBlockHostIndex]}
|
||||
origins := c.ServerBlockHosts
|
||||
args := c.RemainingArgs()
|
||||
if len(args) > 0 {
|
||||
origins = args
|
||||
@@ -52,7 +52,7 @@ func secondaryParse(c *Controller) (file.Zones, error) {
|
||||
}
|
||||
|
||||
for c.NextBlock() {
|
||||
t, f, e := parseTransfer(c)
|
||||
t, f, e := transferParse(c)
|
||||
if e != nil {
|
||||
return file.Zones{}, e
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user