mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
Add dns_nsec_requiredtypespresent
checks an NSEC rdataset to ensure that both NSEC and RRSIG are present in the type map. These types are required for the NSEC to be valid
This commit is contained in:
parent
571f3af6e8
commit
8ff2c133b5
@ -7,7 +7,11 @@ minimal. 3600 SOA ns1.minimal. hostmaster.minimal. (
|
|||||||
3600 ; minimum (1 hour)
|
3600 ; minimum (1 hour)
|
||||||
)
|
)
|
||||||
3600 NS ns1.minimal.
|
3600 NS ns1.minimal.
|
||||||
3600 NSEC black.minimal. NS SOA RRSIG NSEC DNSKEY
|
3600 NSEC badtypemap.minimal. NS SOA RRSIG NSEC DNSKEY
|
||||||
|
; bad NSEC type map without RRSIG or NSEC
|
||||||
|
badtypemap.minimal. 3600 NSEC black.minimal. A
|
||||||
|
badtypemap.minimal. 3600 A 1.2.3.4
|
||||||
|
badtypemap.minimal. 3600 AAAA 2002::1
|
||||||
; cloudflare black lie
|
; cloudflare black lie
|
||||||
black.minimal. 3600 NSEC \000.black.minimal. RRSIG NSEC
|
black.minimal. 3600 NSEC \000.black.minimal. RRSIG NSEC
|
||||||
;
|
;
|
||||||
|
@ -67,6 +67,19 @@ check_nosynth_a() (
|
|||||||
return 0
|
return 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
check_synth_aaaa() (
|
||||||
|
name=$(echo "$1" | sed 's/\./\\./g')
|
||||||
|
grep "^${name}.*[0-9]*.IN.AAAA" ${2} > /dev/null || return 1
|
||||||
|
grep "^${name}.*3600.IN.A" ${2} > /dev/null && return 1
|
||||||
|
return 0
|
||||||
|
)
|
||||||
|
|
||||||
|
check_nosynth_aaaa() (
|
||||||
|
name=$(echo "$1" | sed 's/\./\\./g')
|
||||||
|
grep "^${name}.*3600.IN.AAAA" ${2} > /dev/null || return 1
|
||||||
|
return 0
|
||||||
|
)
|
||||||
|
|
||||||
check_synth_cname() (
|
check_synth_cname() (
|
||||||
name=$(echo "$1" | sed 's/\./\\./g')
|
name=$(echo "$1" | sed 's/\./\\./g')
|
||||||
grep "^${name}.*[0-9]*.IN.CNAME" ${2} > /dev/null || return 1
|
grep "^${name}.*[0-9]*.IN.CNAME" ${2} > /dev/null || return 1
|
||||||
@ -200,6 +213,17 @@ do
|
|||||||
n=$((n+1))
|
n=$((n+1))
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=$((status+ret))
|
status=$((status+ret))
|
||||||
|
|
||||||
|
echo_i "prime bad type map NODATA response (synth-from-dnssec ${description};) ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts badtypemap.minimal. @10.53.0.${ns} TXT > dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_ad_flag $ad dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_status NOERROR dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_nosynth_soa minimal. dig.out.ns${ns}.test$n || ret=1
|
||||||
|
grep 'badtypemap.minimal.*3600.IN.NSEC.black.minimal. A$' dig.out.ns${ns}.test$n > /dev/null || ret=1
|
||||||
|
n=$((n+1))
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status+ret))
|
||||||
done
|
done
|
||||||
|
|
||||||
echo_i "prime redirect response (+nodnssec) (synth-from-dnssec <default>;) ($n)"
|
echo_i "prime redirect response (+nodnssec) (synth-from-dnssec <default>;) ($n)"
|
||||||
@ -388,6 +412,27 @@ do
|
|||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=$((status+ret))
|
status=$((status+ret))
|
||||||
|
|
||||||
|
echo_i "check bad type map NODATA response (synth-from-dnssec ${description};) ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts badtypemap.minimal. @10.53.0.${ns} HINFO > dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_ad_flag $ad dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_status NOERROR dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_nosynth_soa minimal. dig.out.ns${ns}.test$n || ret=1
|
||||||
|
grep 'badtypemap.minimal.*3600.IN.NSEC.black.minimal. A$' dig.out.ns${ns}.test$n > /dev/null || ret=1
|
||||||
|
n=$((n+1))
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status+ret))
|
||||||
|
|
||||||
|
echo_i "check bad type map NODATA response with existent data (synth-from-dnssec ${description};) ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts badtypemap.minimal. @10.53.0.${ns} AAAA > dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_ad_flag $ad dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_status NOERROR dig.out.ns${ns}.test$n || ret=1
|
||||||
|
check_nosynth_aaaa badtypemap.minimal. dig.out.ns${ns}.test$n || ret=1
|
||||||
|
n=$((n+1))
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status+ret))
|
||||||
|
|
||||||
echo_i "check 'rndc stats' output for 'covering nsec returned' (synth-from-dnssec ${description};) ($n)"
|
echo_i "check 'rndc stats' output for 'covering nsec returned' (synth-from-dnssec ${description};) ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
${RNDCCMD} 10.53.0.${ns} stats 2>&1 | sed 's/^/ns6 /' | cat_i
|
${RNDCCMD} 10.53.0.${ns} stats 2>&1 | sed 's/^/ns6 /' | cat_i
|
||||||
|
@ -106,4 +106,14 @@ dns_nsec_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
|
|||||||
* Return ISC_R_IGNORE when the NSEC is not the appropriate one.
|
* Return ISC_R_IGNORE when the NSEC is not the appropriate one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_nsec_requiredtypespresent(dns_rdataset_t *rdataset);
|
||||||
|
/*
|
||||||
|
* Return true if all the NSEC records in rdataset have both
|
||||||
|
* NSEC and RRSIG present.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li rdataset to be a NSEC rdataset.
|
||||||
|
*/
|
||||||
|
|
||||||
ISC_LANG_ENDDECLS
|
ISC_LANG_ENDDECLS
|
||||||
|
@ -460,3 +460,32 @@ dns_nsec_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
|
|||||||
*exists = false;
|
*exists = false;
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
dns_nsec_requiredtypespresent(dns_rdataset_t *nsecset) {
|
||||||
|
dns_rdataset_t rdataset;
|
||||||
|
isc_result_t result;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
REQUIRE(DNS_RDATASET_VALID(nsecset));
|
||||||
|
REQUIRE(nsecset->type == dns_rdatatype_nsec);
|
||||||
|
|
||||||
|
dns_rdataset_init(&rdataset);
|
||||||
|
dns_rdataset_clone(nsecset, &rdataset);
|
||||||
|
|
||||||
|
for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
|
||||||
|
result = dns_rdataset_next(&rdataset))
|
||||||
|
{
|
||||||
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
|
dns_rdataset_current(&rdataset, &rdata);
|
||||||
|
if (!dns_nsec_typepresent(&rdata, dns_rdatatype_nsec) ||
|
||||||
|
!dns_nsec_typepresent(&rdata, dns_rdatatype_rrsig))
|
||||||
|
{
|
||||||
|
dns_rdataset_disassociate(&rdataset);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
dns_rdataset_disassociate(&rdataset);
|
||||||
|
return (found);
|
||||||
|
}
|
||||||
|
@ -5572,6 +5572,15 @@ answer_response:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't cache NSEC if missing NSEC or RRSIG types.
|
||||||
|
*/
|
||||||
|
if (rdataset->type == dns_rdatatype_nsec &&
|
||||||
|
!dns_nsec_requiredtypespresent(rdataset))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't cache "white lies" but do cache
|
* Don't cache "white lies" but do cache
|
||||||
* "black lies".
|
* "black lies".
|
||||||
|
Loading…
x
Reference in New Issue
Block a user