aboutsummaryrefslogtreecommitdiff
path: root/middleware/dnssec/dnssec.go
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/dnssec/dnssec.go')
-rw-r--r--middleware/dnssec/dnssec.go135
1 files changed, 0 insertions, 135 deletions
diff --git a/middleware/dnssec/dnssec.go b/middleware/dnssec/dnssec.go
deleted file mode 100644
index 4e1e70217..000000000
--- a/middleware/dnssec/dnssec.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Package dnssec implements a middleware that signs responses on-the-fly using
-// NSEC black lies.
-package dnssec
-
-import (
- "time"
-
- "github.com/coredns/coredns/middleware"
- "github.com/coredns/coredns/middleware/pkg/cache"
- "github.com/coredns/coredns/middleware/pkg/response"
- "github.com/coredns/coredns/middleware/pkg/singleflight"
- "github.com/coredns/coredns/request"
-
- "github.com/miekg/dns"
-)
-
-// Dnssec signs the reply on-the-fly.
-type Dnssec struct {
- Next middleware.Handler
-
- zones []string
- keys []*DNSKEY
- inflight *singleflight.Group
- cache *cache.Cache
-}
-
-// New returns a new Dnssec.
-func New(zones []string, keys []*DNSKEY, next middleware.Handler, c *cache.Cache) Dnssec {
- return Dnssec{Next: next,
- zones: zones,
- keys: keys,
- cache: c,
- inflight: new(singleflight.Group),
- }
-}
-
-// Sign signs the message in state. it takes care of negative or nodata responses. It
-// uses NSEC black lies for authenticated denial of existence. Signatures
-// creates will be cached for a short while. By default we sign for 8 days,
-// starting 3 hours ago.
-func (d Dnssec) Sign(state request.Request, zone string, now time.Time) *dns.Msg {
- req := state.Req
-
- mt, _ := response.Typify(req, time.Now().UTC()) // TODO(miek): need opt record here?
- if mt == response.Delegation {
- // TODO(miek): uh, signing DS record?!?!
- return req
- }
-
- incep, expir := incepExpir(now)
-
- if mt == response.NameError {
- if req.Ns[0].Header().Rrtype != dns.TypeSOA || len(req.Ns) > 1 {
- return req
- }
-
- ttl := req.Ns[0].Header().Ttl
-
- if sigs, err := d.sign(req.Ns, zone, ttl, incep, expir); err == nil {
- req.Ns = append(req.Ns, sigs...)
- }
- if sigs, err := d.nsec(state.Name(), zone, ttl, incep, expir); err == nil {
- req.Ns = append(req.Ns, sigs...)
- }
- if len(req.Ns) > 1 { // actually added nsec and sigs, reset the rcode
- req.Rcode = dns.RcodeSuccess
- }
- return req
- }
-
- for _, r := range rrSets(req.Answer) {
- ttl := r[0].Header().Ttl
- if sigs, err := d.sign(r, zone, ttl, incep, expir); err == nil {
- req.Answer = append(req.Answer, sigs...)
- }
- }
- for _, r := range rrSets(req.Ns) {
- ttl := r[0].Header().Ttl
- if sigs, err := d.sign(r, zone, ttl, incep, expir); err == nil {
- req.Ns = append(req.Ns, sigs...)
- }
- }
- for _, r := range rrSets(req.Extra) {
- ttl := r[0].Header().Ttl
- if sigs, err := d.sign(r, zone, ttl, incep, expir); err == nil {
- req.Extra = append(sigs, req.Extra...) // prepend to leave OPT alone
- }
- }
- return req
-}
-
-func (d Dnssec) sign(rrs []dns.RR, signerName string, ttl, incep, expir uint32) ([]dns.RR, error) {
- k := hash(rrs)
- sgs, ok := d.get(k)
- if ok {
- return sgs, nil
- }
-
- sigs, err := d.inflight.Do(k, func() (interface{}, error) {
- sigs := make([]dns.RR, len(d.keys))
- var e error
- for i, k := range d.keys {
- sig := k.newRRSIG(signerName, ttl, incep, expir)
- e = sig.Sign(k.s, rrs)
- sigs[i] = sig
- }
- d.set(k, sigs)
- return sigs, e
- })
- return sigs.([]dns.RR), err
-}
-
-func (d Dnssec) set(key uint32, sigs []dns.RR) {
- d.cache.Add(key, sigs)
-}
-
-func (d Dnssec) get(key uint32) ([]dns.RR, bool) {
- if s, ok := d.cache.Get(key); ok {
- cacheHits.Inc()
- return s.([]dns.RR), true
- }
- cacheMisses.Inc()
- return nil, false
-}
-
-func incepExpir(now time.Time) (uint32, uint32) {
- incep := uint32(now.Add(-3 * time.Hour).Unix()) // -(2+1) hours, be sure to catch daylight saving time and such
- expir := uint32(now.Add(eightDays).Unix()) // sign for 8 days
- return incep, expir
-}
-
-const (
- eightDays = 8 * 24 * time.Hour
- defaultCap = 10000 // default capacity of the cache.
-)