plugin/dnssec: on delegation, sign DS or NSEC of no DS. (#5899)

* When returning NS for delegation point, we sign any DS Record or if not
  found we generate a NSEC proving absence of DS. This follow behaviour
  describe in rfc4035 (Section 3.1.4)
* DS request at apex behave as before.
* Fix edge case of requesting NSEC which prove that NSEC does not exist.

Signed-off-by: Jeremiejig <me@jeremiejig.fr>
This commit is contained in:
jeremiejig
2023-04-22 22:32:01 +02:00
committed by GitHub
parent 0862dd1cb5
commit 13e66918e3
5 changed files with 365 additions and 9 deletions

View File

@@ -48,6 +48,22 @@ func (d Dnssec) Sign(state request.Request, now time.Time, server string) *dns.M
mt, _ := response.Typify(req, time.Now().UTC()) // TODO(miek): need opt record here?
if mt == response.Delegation {
// We either sign DS or NSEC of DS.
ttl := req.Ns[0].Header().Ttl
ds := []dns.RR{}
for i := range req.Ns {
if req.Ns[i].Header().Rrtype == dns.TypeDS {
ds = append(ds, req.Ns[i])
}
}
if len(ds) == 0 {
if sigs, err := d.nsec(state, mt, ttl, incep, expir, server); err == nil {
req.Ns = append(req.Ns, sigs...)
}
} else if sigs, err := d.sign(ds, state.Zone, ttl, incep, expir, server); err == nil {
req.Ns = append(req.Ns, sigs...)
}
return req
}
@@ -66,6 +82,10 @@ func (d Dnssec) Sign(state request.Request, now time.Time, server string) *dns.M
}
if len(req.Ns) > 1 { // actually added nsec and sigs, reset the rcode
req.Rcode = dns.RcodeSuccess
if state.QType() == dns.TypeNSEC { // If original query was NSEC move Ns to Answer without SOA
req.Answer = req.Ns[len(req.Ns)-2 : len(req.Ns)]
req.Ns = nil
}
}
return req
}