Merge branch '2445-nsec3-iterations-resolver' into 'main'
Resolve "NSEC3 iterations" Closes #2445 See merge request isc-projects/bind9!4957
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
||||
5630. [func] Treat DNSSEC responses with NSEC3 iterations greater
|
||||
than 150 as insecure. [GL #2445]
|
||||
|
||||
5629. [func] Reduce the supported maximum number of iterations
|
||||
that can be configured in an NSEC3 zone to 150.
|
||||
[GL #2642]
|
||||
|
||||
@@ -4331,5 +4331,56 @@ n=$((n+1))
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
# Check that the validating resolver will fallback to insecure if the answer
|
||||
# contains NSEC3 records with high iteration count.
|
||||
echo_i "checking fallback to insecure when NSEC3 iterations is too high (nxdomain) ($n)"
|
||||
ret=0
|
||||
dig_with_opts @10.53.0.2 does-not-exist.too-many-iterations > dig.out.ns2.test$n || ret=1
|
||||
dig_with_opts @10.53.0.4 does-not-exist.too-many-iterations > dig.out.ns4.test$n || ret=1
|
||||
digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "status: NXDOMAIN" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "ANSWER: 0, AUTHORITY: 6" dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=$((n+1))
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "checking fallback to insecure when NSEC3 iterations is too high (nodata) ($n)"
|
||||
ret=0
|
||||
dig_with_opts @10.53.0.2 a.too-many-iterations txt > dig.out.ns2.test$n || ret=1
|
||||
dig_with_opts @10.53.0.4 a.too-many-iterations txt > dig.out.ns4.test$n || ret=1
|
||||
digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "ANSWER: 0, AUTHORITY: 4" dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=$((n+1))
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "checking fallback to insecure when NSEC3 iterations is too high (wildcard) ($n)"
|
||||
ret=0
|
||||
dig_with_opts @10.53.0.2 wild.a.too-many-iterations > dig.out.ns2.test$n || ret=1
|
||||
dig_with_opts @10.53.0.4 wild.a.too-many-iterations > dig.out.ns4.test$n || ret=1
|
||||
digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep 'wild\.a\.too-many-iterations\..*A.10\.0\.0\.3' dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "ANSWER: 2, AUTHORITY: 4" dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=$((n+1))
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "checking fallback to insecure when NSEC3 iterations is too high (wildcard nodata) ($n)"
|
||||
ret=0
|
||||
dig_with_opts @10.53.0.2 type100 wild.a.too-many-iterations > dig.out.ns2.test$n || ret=1
|
||||
dig_with_opts @10.53.0.4 type100 wild.a.too-many-iterations > dig.out.ns4.test$n || ret=1
|
||||
digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
||||
grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep "ANSWER: 0, AUTHORITY: 8" dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=$((n+1))
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
||||
@@ -40,6 +40,9 @@ Feature Changes
|
||||
- Reduce the supported maximum number of iterations that can be
|
||||
configured in an NSEC3 zones to 150. :gl:`#2642`
|
||||
|
||||
- Treat DNSSEC responses with NSEC3 iterations greater than 150 as insecure.
|
||||
[GL #2445]
|
||||
|
||||
Bug Fixes
|
||||
~~~~~~~~~
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#define DNS_NSEC3_SALTSIZE 255
|
||||
#define DNS_NSEC3_SALTSIZE 255
|
||||
#define DNS_NSEC3_MAXITERATIONS 150U
|
||||
|
||||
/*
|
||||
* hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max)
|
||||
|
||||
@@ -1880,7 +1880,7 @@ try_private:
|
||||
|
||||
unsigned int
|
||||
dns_nsec3_maxiterations(void) {
|
||||
return (150);
|
||||
return (DNS_NSEC3_MAXITERATIONS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -2022,6 +2022,13 @@ dns_nsec3_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
|
||||
first = true;
|
||||
|
||||
while (qlabels >= zlabels) {
|
||||
/*
|
||||
* If there are too many iterations reject the NSEC3 record.
|
||||
*/
|
||||
if (nsec3.iterations > DNS_NSEC3_MAXITERATIONS) {
|
||||
return (DNS_R_NSEC3ITERRANGE);
|
||||
}
|
||||
|
||||
length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
|
||||
nsec3.salt, nsec3.salt_length,
|
||||
qname->ndata, qname->length);
|
||||
|
||||
@@ -2245,6 +2245,26 @@ findnsec3proofs(dns_validator_t *val) {
|
||||
if (unknown) {
|
||||
val->attributes |= VALATTR_FOUNDUNKNOWN;
|
||||
}
|
||||
if (result == DNS_R_NSEC3ITERRANGE) {
|
||||
/*
|
||||
* We don't really know which NSEC3 record provides
|
||||
* which proof. Just populate them.
|
||||
*/
|
||||
if (NEEDNOQNAME(val) &&
|
||||
proofs[DNS_VALIDATOR_NOQNAMEPROOF] == NULL) {
|
||||
proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name;
|
||||
} else if (setclosest) {
|
||||
proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
|
||||
} else if (NEEDNODATA(val) &&
|
||||
proofs[DNS_VALIDATOR_NODATAPROOF] == NULL) {
|
||||
proofs[DNS_VALIDATOR_NODATAPROOF] = name;
|
||||
} else if (NEEDNOWILDCARD(val) &&
|
||||
proofs[DNS_VALIDATOR_NOWILDCARDPROOF] ==
|
||||
NULL) {
|
||||
proofs[DNS_VALIDATOR_NOWILDCARDPROOF] = name;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
@@ -2501,7 +2521,13 @@ validate_nx(dns_validator_t *val, bool resume) {
|
||||
*/
|
||||
if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) {
|
||||
if (!FOUNDNOQNAME(val)) {
|
||||
findnsec3proofs(val);
|
||||
result = findnsec3proofs(val);
|
||||
if (result == DNS_R_NSEC3ITERRANGE) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"too many iterations");
|
||||
markanswer(val, "validate_nx (3)", NULL);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) && !FOUNDOPTOUT(val))
|
||||
@@ -2531,7 +2557,13 @@ validate_nx(dns_validator_t *val, bool resume) {
|
||||
}
|
||||
|
||||
if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val)) {
|
||||
findnsec3proofs(val);
|
||||
result = findnsec3proofs(val);
|
||||
if (result == DNS_R_NSEC3ITERRANGE) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"too many iterations");
|
||||
markanswer(val, "validate_nx (4)", NULL);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user