Hi,

Some thoughts below, strictly on the NSEC/NSEC3 algorithm.  They're quite
rough, but hopefully they're useful.

Cheers,
Casey

On Tue, Jul 7, 2015 at 5:20 AM, <[email protected]> wrote:

> Please check this algorithm.


Several times, the phrase "query as usual" is used.  However, something
might need to be said about the resolver modifying "query as usual" to save
NSEC/NSEC3 records associated with wildcard and negative responses in a way
that they can be used by the algorithm.

For example, the following indexes could be maintained:

Indexes:
NSEC_TABLE = a canonically ordered mapping of NSEC owner names to NSEC
records, grouped by corresponding SOA name
NSEC3_TABLE = a canonically ordered mapping of NSEC3 owner names to NSEC3
records, grouped by corresponding SOA name and NSEC3 parameters
NSEC3_NAMES = a canonically ordered mapping of names to their corresponding
NSEC3-hashed names (or records)

QNAME = the query name;
> if (QNAME name entry exists in the cache) {
>     resolve the query as usual;
>     // if RRSet (query name and query type) exists in the cache,
>     //     the resolver responds the RRSet from the cache
>     // Otherwise, the resolver needs to iterate the query.
> }
>
> // Find closest enclosing NS RRset in the cache.
> // The owner of this NS RRset will be a suffix of the QNAME
> //    - the longest suffix of any NS RRset in the cache.
> SIGNER = closest enclosing NS RRSet of QNAME in the cache;
>

You should now find the SOA record corresponding to SIGNER.  If there is no
SOA record in cache, then there are no previously cached negative
responses, so you can resolve the query as usual.

if (SIGNER zone does not have a special NSEC/NSEC3 data structure) {
>     Resolve the query as usual;
> }
>

I'm not sure what this means.


> if (SIGNER zone is not signed or not validated) {
>    Resolve the query as usual;
> }
>

You mean here: if the SOA record is not validated (signed is implied by
validated).

While colloquially we talk about zones being signed, in this case, you want
an actual RRset--one that matters at that.  The SOA record fits the bill
here because of its role with negative responses.


> if (SIGNER zone is signed with NSEC) {
>

While in theory a zone is signed with either NSEC or NSEC3, in practice all
that matters is the NSEC or NSEC3 proofs provided in individual responses.
While not necessarily desirable, it is entirely possible that subsequent
responses could different NSEC/NSEC3 results.  Therefore, for algorithm
robustness, checking whether a zone is signed with NSEC or NSEC3 is less
useful than simply looking at both NSEC and NSEC3 records in the cache.

I would eliminate "if SIGNER zone is signed with NSEC" and its
corresponding "else"/"else if" altogether.  You should really check both
NSEC and NSEC3.

BEGIN NSEC SECTION

     if (covering NSEC RR of QNAME at SIGNER zone
>        doesn't exist in the cache) {
>         Resolve the query as usual.
>     }
>

s/Resolve the query as usual/Go to NSEC3 SECTION/


>
>     TEST = Find the longest existing domain name of QNAME
>            from the covering NSEC RR;
>

You could use the term "closest encloser"/CLOSEST_ENCLOSER instead of
"longest existing domain name"/TEST.

    if (*.TEST name entry exists in the cache) {
>         the resolver can generate positive response
>         or resolve the query as usual;
>     }
>

s/resolve the query as usual/Go to the NSEC3 SECTION

It could be a NODATA response (which is a negative response), if the type
doesn't exist.  Although, I think that's what you mean by "positive
response or resolve the query as usual".


>     if covering NSEC RR of "*.TEST" at SIGNER zone exists
>          in the cache {
>         the resolver can generate negative response;
>     }
>

s/resolver can generate negative response/Return synthesized negative
response/


>     // Lack of information, need to resolve the query as usual
>

No. move on to NSEC3 now.


> } else
>
if (SIGNER zone is signed with NSEC3 and does not use Opt-Out) {
>

Eliminate this "else if SIGNER zone is signed with NSEC3 and does not use
Opt-out" check too.

BEGIN NSEC3 SECTION

    TEST = SIGNER;
>

Again, I would look for closest encloser (CLOSEST_ENCLOSER) here (e.g.,
using the NSEC3_NAMES table).  There might be multiple NSEC3 records for a
single closest encloser if multiple sets of NSEC3 parameters are used
across different responses, but really all you need is one.  In this case,
you would need to iterate through the different sets of NSEC3 parameters.

Once you have the closest encloser, the algorithm looks more (but not
entirely) like the NSEC portion above, but with NSEC3 instead.  I'm not
sure I follow the logic in the previously written NSEC3 section.  I've made
some modifications below.

   if (no CLOSEST_ENCLOSER is found) {
        Go to FALLBACK SECTION
    }

NEXT_CLOSEST_ENCLOSER_PROOF_FOUND = False
 for each set of parameters corresponding to NSEC3 names in the appropriate
zone {
    if (there is a NSEC3 RR covering the next closest encloser (i.e.,
CLOSEST_ENCLOSER + one label)) {
      NEXT_CLOSEST_ENCLOSER_PROOF_FOUND = True
    }
  }
  if ! NEXT_CLOSEST_ENCLOSER_PROOF_FOUND {
    Go to FALLBACK SECTION
  }

 WILDCARD_PROOF_FOUND = False
 for each set of parameters corresponding to NSEC3 names in the appropriate
zone {
    if (*.CLOSEST _ENCLOSER name entry exists in the cache) {
        the resolver can generate positive response
        or Go to FALLBACK SECTION;
    }

    if covering NSEC3 RR of "*.NEXT_CLOSEST_ENCLOSER" exists
         in the cache {
        WILDCARD_PROOF_FOUND = True
    }
   }

  If WILDCARD_PROOF_FOUND {
    Return synthesized negative response
  }

BEGIN FALLBACK SECTION
    // Lack of information, need to resolve the query as usual
_______________________________________________
DNSOP mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/dnsop

Reply via email to