+31 July 2026: Wouter
+ - For #1483: The failure reason when an NSEC NXDOMAIN is
+ encountered when looking for an insecure delegation, is
+ fixed to mention the NSEC records, instead of nonexistent
+ NSEC3 records, that it attempted.
+
30 July 2026: Wouter
- Fix #1482: DNS-over-QUIC doesn't work with simple config.
That fixes interface-automatic for use with doq service.
--- /dev/null
+; config options
+server:
+ ; This is the test key 29332 in the testdata.
+ trust-anchor: ". 3600 IN DS 29332 8 2 b75e26316631b6e37cbc977323a08769f86e36a10fee888676d35f61e2ff4181"
+ val-override-date: "20201020135527"
+ target-fetch-policy: "0 0 0 0 0"
+ qname-minimisation: no
+ fake-sha1: yes
+ trust-anchor-signaling: no
+ minimal-responses: no
+ log-servfail: yes
+
+forward-zone:
+ name: "."
+ forward-addr: 10.5.5.5
+CONFIG_END
+
+SCENARIO_BEGIN Test nxdomain that gets unsigned response
+; and the DS lookup that it makes gets an NSEC NXDOMAIN response.
+
+; 10.5.5.5 forwarder
+RANGE_BEGIN 0 100
+ ADDRESS 10.5.5.5
+
+; unsigned NXDOMAIN response, from the first forwarder, here it is served
+; from the upstream.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+example.veryinvalid. IN TXT
+SECTION AUTHORITY
+. 3600 IN SOA ns.root. host.root. 1 3600 3600 3600 3600
+ENTRY_END
+
+; DNSKEY answer, using CSK for test simplicity.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
+. 3600 IN RRSIG DNSKEY 8 0 3600 20201116135527 20201019135527 29332 . ToK8hJrGa+kNu6y8FpRwZq2FjDPBAk5Ctchia3Vu9yTth2dR7BhK2ALTWVBwAQGwiwxXKoVK9QCxdQM0ti7CVb9x75bejkd2E6UGWVmqyTRPpn3D43qYARm87y3ZVKG7LlWHp8UOf21XLp1H7R+wuipIvBJ1XA+QGXThPdbV9EEz1kKGdprBfdpFkQdcAiuYYrOTa5cJ11z32mGiQ12fWjpb4UUbfcoDD9YOoa/S5a6h7jYBOfm75ZB8UCW3Z/SlsN8KIfYZsg5CZphpf38XH5uNLMmzpaWYhfamJZJve9Isx4eILNmdMLK4E8ESwDFCVNzMIqdf20VRg6Lh7nwQeA==
+ENTRY_END
+
+; answer for DS, from another forwarder, here returned from the test upstream.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+veryinvalid. IN DS
+SECTION AUTHORITY
+versicherung. 3600 IN NSEC vet. NS DS RRSIG NSEC
+versicherung. 3600 IN RRSIG NSEC 8 1 3600 20201116135527 20201019135527 29332 . AVAON9Y7AVwX9YWQK8JPcB6Wk/tEfQT7JrLiCRlBBQA0+mpVYYYtMyrm4aMjkhusqYcnpIZoLGOI/dxJjIwDgnMkd4EqY2oICea3I260f8z2v9e7zNobyUTjkoWsmLPc7VRLtEGKu1XyVpt7DX6ElGoSUhU4JsTx7wkkXU0SGAakL0bhK8K68B92NEVwgKX4D7+kVfpjc0aHaB3rAkhQCM/G0jEFp0RuhTX1aru6IuYrZmjW0dvQ2niec6NaYzvuGnbhMLlFLuXqSmI2B7uIFx894usd1cVWnSRg49bAkuiEv5q04ltRel1huJBGGiZlLEwanS5g53C5DHfq10OUrw==
+. 3600 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY ZONEMD
+. 3600 IN RRSIG NSEC 8 0 3600 20201116135527 20201019135527 29332 . E8r6rpFgFBUda2GnFSMzHZLtjy1dT+ZS0wPRE12RNwVK547bo2vByv9EFhOHS6sEIFqX+AmIJotuiEPKnCFUTr6FKscaxtw38dJRZ3wldqV6dmqUiRmz91crDCV5nSL45FIbkWKk1Q+tnXie3sZ4zwBc12kGg2BttMAQ0i4sbMbf6EUNYZGwYzSB0/VhXVJcl8gl+5lfpiVqfWNZI7vTEaHqrC2gBC3UK1cQE9lQOqhJ6H5ThA1FR9j/mZFM9sG5vQ2Mqlzl2iiN2Y6mCptDY1vwfff6AnT0YeDwJ/XwGisMZrSvTCYaiRndb8CUUmCr23AFy5OER1rmeFGkHX5+WQ==
+. 3600 IN SOA ns.root. host.root. 1 3600 3600 3600 3600
+. 3600 IN RRSIG SOA 8 0 3600 20201116135527 20201019135527 29332 . tVeReLMXPnl6rk4QX94xy9lCodQ+xc39lokbNkvbXnTURNCOAwtNiMMPlAAJ3/HTpIxo175gPfupACIveBtgajdp85jUIvLMOM5B6lX80+dUPBGZ4gHVjf+8EGnr7q2wnW2+KcJu0OhN2g+YqCV6aPi8pzuAp+AMsBYcMfXqEQq9Lxqv6TL50MUCJN3GPCyBIdjbs/A+ZB7D1EOO1YgdbsMHK/pWKYt4UfBFfekoA6joIGf4vBKKRTWnoo0BcrFob3AW1SyJkoxoqEsN3YAVL9jNkJCkU0/adLypHgDNayLgsWI5/o4Ng8LxN6tNxAilkMhcGY80T5g0uo+ukY7McA==
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+example.veryinvalid. IN TXT
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+example.veryinvalid. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
return 0;
}
+void val_has_auth_nsecs(struct reply_info* rep, int* has_nsec, int* has_nsec3)
+{
+ size_t i, num_nsec = 0, num_nsec3 = 0;
+ for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) {
+ if(rep->rrsets[i]->rk.type == htons(LDNS_RR_TYPE_NSEC))
+ num_nsec++;
+ else if(rep->rrsets[i]->rk.type == htons(LDNS_RR_TYPE_NSEC3))
+ num_nsec3++;
+ else continue;
+ }
+ *has_nsec = (num_nsec != 0);
+ *has_nsec3 = (num_nsec3 != 0);
+}
+
struct dns_msg*
val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c,
struct regional* region, uint8_t* topname)
*/
int val_has_signed_nsecs(struct reply_info* rep, char** reason);
+/**
+ * See if there are NSECs, or NSEC3s in the authority section.
+ * @param rep: reply to check
+ * @param has_nsec: returned true if it has nsecs.
+ * @param has_nsec3: returned true if it has nsec3s.
+ */
+void val_has_auth_nsecs(struct reply_info* rep, int* has_nsec, int* has_nsec3);
+
/**
* Return algo number for favorite (best) algorithm that we support in DS.
* @param ds_rrset: the DSes in this rrset are inspected and best algo chosen.
case sec_status_unchecked:
default:
/* NSEC proof did not work, try next */
+ verbose(VERB_ALGO, "NSEC proof did not prove insecure delegation, try NSEC3");
break;
}
*ke = NULL;
return 0;
case sec_status_bogus:
+ /* It could be that the NSEC proof failed,
+ * and, then tried NSEC3. */
+ {
+ int has_nsec=0, has_nsec3=0;
+ val_has_auth_nsecs(msg->rep, &has_nsec,
+ &has_nsec3);
+ if(!has_nsec3 && has_nsec) {
+ /* The NSECs are the cause, mention that in the error message. */
+ verbose(VERB_DETAIL, "NSECs for the "
+ "referral did not prove no DS.");
+ errinf_ede(qstate, "NSECs for the referral did not prove no DS", LDNS_EDE_DNSSEC_BOGUS);
+ goto return_bogus;
+ }
+ if(!has_nsec3 && !has_nsec) {
+ verbose(VERB_DETAIL, "absence of NSECs and NSEC3s when attempting to prove no DS.");
+ errinf_ede(qstate, "no NSECs or NSEC3s when attempting to prove no DS", LDNS_EDE_DNSSEC_BOGUS);
+ goto return_bogus;
+ }
+ }
verbose(VERB_DETAIL, "NSEC3s for the "
"referral did not prove no DS.");
errinf_ede(qstate, reason, reason_bogus);