From 24e0f0ab7e85995f497aa8799af52bbb12ffe042 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 10 Sep 2024 10:13:48 +0200 Subject: [PATCH] - Fix to limit NSEC and NSEC3 TTL when aggressive nsec is enabled (RFC9077). --- doc/Changelog | 4 ++++ iterator/iterator.c | 47 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/doc/Changelog b/doc/Changelog index 8a22e049d..136fd0b68 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +10 September 2024: Wouter + - Fix to limit NSEC and NSEC3 TTL when aggressive nsec is + enabled (RFC9077). + 6 September 2024: Yorgos - Fix alloc-size and calloc-transposed-args compiler warnings. - Fix comment to not trigger doxygen unknown command. diff --git a/iterator/iterator.c b/iterator/iterator.c index 659af34d9..d566a7998 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -367,6 +367,48 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) return error_response(qstate, id, rcode); } +/** limit NSEC and NSEC3 TTL in response, RFC9077 */ +static void +limit_nsec_ttl(struct dns_msg* msg) +{ + size_t i; + int found = 0; + time_t soa_ttl = 0; + /* Limit the NSEC and NSEC3 TTL values to the SOA TTL and SOA minimum + * TTL. That has already been applied to the SOA record ttl. */ + for(i=0; irep->rrset_count; i++) { + struct ub_packed_rrset_key* s = msg->rep->rrsets[i]; + if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA) { + struct packed_rrset_data* soadata = (struct packed_rrset_data*)s->entry.data; + found = 1; + soa_ttl = soadata->ttl; + break; + } + } + if(!found) + return; + for(i=0; irep->rrset_count; i++) { + struct ub_packed_rrset_key* s = msg->rep->rrsets[i]; + if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC || + ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { + struct packed_rrset_data* data = (struct packed_rrset_data*)s->entry.data; + /* Limit the negative TTL. */ + if(data->ttl > soa_ttl) { + if(verbosity >= VERB_ALGO) { + char buf[256]; + snprintf(buf, sizeof(buf), + "limiting TTL %d of %s record to the SOA TTL of %d for", + (int)data->ttl, ((ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC)?"NSEC":"NSEC3"), (int)soa_ttl); + log_nametypeclass(VERB_ALGO, buf, + s->rk.dname, ntohs(s->rk.type), + ntohs(s->rk.rrset_class)); + } + data->ttl = soa_ttl; + } + } + } +} + /** check if prepend item is duplicate item */ static int prepend_is_duplicate(struct ub_packed_rrset_key** sets, size_t to, @@ -4366,7 +4408,10 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, if(verbosity >= VERB_ALGO) log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo, iq->response->rep); - + + if(qstate->env->cfg->aggressive_nsec) { + limit_nsec_ttl(iq->response); + } if(event == module_event_capsfail || iq->caps_fallback) { if(qstate->env->cfg->qname_minimisation && iq->minimisation_state != DONOT_MINIMISE_STATE) {