forked from coredns/coredns
/
setup.go
128 lines (110 loc) · 2.67 KB
/
setup.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package dnssec
import (
"fmt"
"strconv"
"strings"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/middleware"
"github.com/coredns/coredns/middleware/pkg/cache"
"github.com/mholt/caddy"
)
func init() {
caddy.RegisterPlugin("dnssec", caddy.Plugin{
ServerType: "dns",
Action: setup,
})
}
func setup(c *caddy.Controller) error {
zones, keys, capacity, err := dnssecParse(c)
if err != nil {
return middleware.Error("dnssec", err)
}
ca := cache.New(capacity)
dnsserver.GetConfig(c).AddMiddleware(func(next middleware.Handler) middleware.Handler {
return New(zones, keys, next, ca)
})
// Export the capacity for the metrics. This only happens once, because this is a re-load change only.
cacheCapacity.WithLabelValues("signature").Set(float64(capacity))
return nil
}
func dnssecParse(c *caddy.Controller) ([]string, []*DNSKEY, int, error) {
zones := []string{}
keys := []*DNSKEY{}
capacity := defaultCap
for c.Next() {
// dnssec [zones...]
zones = make([]string, len(c.ServerBlockKeys))
copy(zones, c.ServerBlockKeys)
args := c.RemainingArgs()
if len(args) > 0 {
zones = args
}
for c.NextBlock() {
switch c.Val() {
case "key":
k, e := keyParse(c)
if e != nil {
return nil, nil, 0, e
}
keys = append(keys, k...)
case "cache_capacity":
if !c.NextArg() {
return nil, nil, 0, c.ArgErr()
}
value := c.Val()
cacheCap, err := strconv.Atoi(value)
if err != nil {
return nil, nil, 0, err
}
capacity = cacheCap
}
}
}
for i := range zones {
zones[i] = middleware.Host(zones[i]).Normalize()
}
// Check if each keys owner name can actually sign the zones we want them to sign
for _, k := range keys {
kname := middleware.Name(k.K.Header().Name)
ok := false
for i := range zones {
if kname.Matches(zones[i]) {
ok = true
break
}
}
if !ok {
return zones, keys, capacity, fmt.Errorf("key %s (keyid: %d) can not sign any of the zones", string(kname), k.keytag)
}
}
return zones, keys, capacity, nil
}
func keyParse(c *caddy.Controller) ([]*DNSKEY, error) {
keys := []*DNSKEY{}
if !c.NextArg() {
return nil, c.ArgErr()
}
value := c.Val()
if value == "file" {
ks := c.RemainingArgs()
if len(ks) == 0 {
return nil, c.ArgErr()
}
for _, k := range ks {
base := k
// Kmiek.nl.+013+26205.key, handle .private or without extension: Kmiek.nl.+013+26205
if strings.HasSuffix(k, ".key") {
base = k[:len(k)-4]
}
if strings.HasSuffix(k, ".private") {
base = k[:len(k)-8]
}
k, err := ParseKeyFile(base+".key", base+".private")
if err != nil {
return nil, err
}
keys = append(keys, k)
}
}
return keys, nil
}