diff options
Diffstat (limited to 'middleware/dnssec/dnssec.go')
-rw-r--r-- | middleware/dnssec/dnssec.go | 135 |
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. -) |