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
