diff --git a/CHANGES b/CHANGES index 06772c24e6..83590f8445 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +6292. [func] Lower the maximum number of allowed NSEC3 iterations, + from 150 to 50. DNSSEC responses with a higher + iteration count are treated as insecure. For signing + with dnssec-policy, iterations must be set to zero. + [GL #4363] + 6291. [bug] SIGTERM failed to properly stop multiple outstanding lookup in dig. [GL #4457] diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 2cf0a9bd83..83e3b9ee6a 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -3494,7 +3494,7 @@ main(int argc, char *argv[]) { set_iter = true; /* too-many is NOT DOCUMENTED */ if (strcmp(isc_commandline_argument, "too-many") == 0) { - nsec3iter = 151; + nsec3iter = 51; no_max_check = true; break; } diff --git a/bin/tests/system/autosign/ns2/named.conf.in b/bin/tests/system/autosign/ns2/named.conf.in index 83da464595..fc5740c84f 100644 --- a/bin/tests/system/autosign/ns2/named.conf.in +++ b/bin/tests/system/autosign/ns2/named.conf.in @@ -67,7 +67,7 @@ dnssec-policy "optout" { zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; }; - nsec3param iterations 1 optout yes salt-length 0; + nsec3param iterations 0 optout yes salt-length 0; }; zone "." { diff --git a/bin/tests/system/autosign/tests.sh b/bin/tests/system/autosign/tests.sh index 41cbb0b613..61afacf1e4 100755 --- a/bin/tests/system/autosign/tests.sh +++ b/bin/tests/system/autosign/tests.sh @@ -1269,9 +1269,9 @@ n=$((n + 1)) if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) -echo_i "check removal of ENT NSEC3 records when opt out delegations are removed" +echo_i "check removal of ENT NSEC3 records when opt out delegations are removed ($n)" zone=optout-with-ent -hash=JTR8R6AVFULU0DQH9I6HNN2KUK5956EL +hash=JE76PJ65FUO86UIR594L8P0SNJJ6RMNI # check that NSEC3 for ENT is present echo_i "check ENT NSEC3 is initially present" diff --git a/bin/tests/system/checkconf/good-kasp.conf b/bin/tests/system/checkconf/good-kasp.conf index fb3fceab0a..d5da98fc6d 100644 --- a/bin/tests/system/checkconf/good-kasp.conf +++ b/bin/tests/system/checkconf/good-kasp.conf @@ -29,7 +29,7 @@ dnssec-policy "test" { csk key-directory lifetime unlimited algorithm rsasha256 2048; }; max-zone-ttl 86400; - nsec3param iterations 5 optout no salt-length 8; + nsec3param iterations 0 optout no salt-length 8; parent-ds-ttl 7200; parent-propagation-delay PT1H; publish-safety PT3600S; diff --git a/bin/tests/system/checkconf/good-key-directory.conf b/bin/tests/system/checkconf/good-key-directory.conf index 07deb28993..063c4a9928 100644 --- a/bin/tests/system/checkconf/good-key-directory.conf +++ b/bin/tests/system/checkconf/good-key-directory.conf @@ -17,7 +17,7 @@ dnssec-policy "internet" { zsk key-directory lifetime P90D algorithm ecdsa256; }; - nsec3param iterations 15 optout no salt-length 8; + nsec3param iterations 0 optout no salt-length 8; }; dnssec-policy "intranet" { @@ -25,7 +25,7 @@ dnssec-policy "intranet" { ksk key-directory lifetime unlimited algorithm ecdsa256; zsk key-directory lifetime P30D algorithm ecdsa256; }; - nsec3param iterations 15 optout no salt-length 8; + nsec3param iterations 0 optout no salt-length 8; }; dnssec-policy "localhost" { @@ -33,7 +33,7 @@ dnssec-policy "localhost" { ksk key-directory lifetime unlimited algorithm ecdsa256; zsk key-directory lifetime P30D algorithm ecdsa256; }; - nsec3param iterations 15 optout no salt-length 8; + nsec3param iterations 0 optout no salt-length 8; }; options { diff --git a/bin/tests/system/checkconf/kasp-bad-nsec3-iter-fips.conf b/bin/tests/system/checkconf/kasp-bad-nsec3-iter-fips.conf index e54df3b360..da896a2447 100644 --- a/bin/tests/system/checkconf/kasp-bad-nsec3-iter-fips.conf +++ b/bin/tests/system/checkconf/kasp-bad-nsec3-iter-fips.conf @@ -15,28 +15,28 @@ dnssec-policy "rsasha256" { keys { csk lifetime P10Y algorithm rsasha256 2048; }; - nsec3param iterations 150; + nsec3param iterations 0; }; dnssec-policy "rsasha256-bad" { keys { csk lifetime P10Y algorithm rsasha256 2048; }; - nsec3param iterations 151; + nsec3param iterations 1; }; dnssec-policy "rsasha512" { keys { csk lifetime P10Y algorithm rsasha512 4096; }; - nsec3param iterations 150; + nsec3param iterations 0; }; dnssec-policy "rsasha512-bad" { keys { csk lifetime P10Y algorithm rsasha512 4096; }; - nsec3param iterations 151; + nsec3param iterations 1; }; zone "example.net" { diff --git a/bin/tests/system/checkconf/kasp-bad-nsec3-iter.conf b/bin/tests/system/checkconf/kasp-bad-nsec3-iter.conf index 8dc710f29c..967c29fc0f 100644 --- a/bin/tests/system/checkconf/kasp-bad-nsec3-iter.conf +++ b/bin/tests/system/checkconf/kasp-bad-nsec3-iter.conf @@ -15,42 +15,42 @@ dnssec-policy "rsasha1" { keys { csk lifetime P10Y algorithm nsec3rsasha1 1024; }; - nsec3param iterations 150; + nsec3param iterations 0; }; dnssec-policy "rsasha1-bad" { keys { csk lifetime P10Y algorithm nsec3rsasha1 1024; }; - nsec3param iterations 151; + nsec3param iterations 1; }; dnssec-policy "rsasha256" { keys { csk lifetime P10Y algorithm rsasha256 2048; }; - nsec3param iterations 150; + nsec3param iterations 0; }; dnssec-policy "rsasha256-bad" { keys { csk lifetime P10Y algorithm rsasha256 2048; }; - nsec3param iterations 151; + nsec3param iterations 1; }; dnssec-policy "rsasha512" { keys { csk lifetime P10Y algorithm rsasha512 4096; }; - nsec3param iterations 150; + nsec3param iterations 0; }; dnssec-policy "rsasha512-bad" { keys { csk lifetime P10Y algorithm rsasha512 4096; }; - nsec3param iterations 151; + nsec3param iterations 1; }; zone "example.net" { diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index 458b1a41ec..606c8487a3 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -620,7 +620,7 @@ else expect=3 fi $CHECKCONF $conf >checkconf.out$n 2>&1 && ret=1 -grep "dnssec-policy: nsec3 iterations value 151 out of range" /dev/null || ret=1 +grep "dnssec-policy: nsec3 iterations value 1 not allowed, must be zero" /dev/null || ret=1 lines=$(wc -l <"checkconf.out$n") if [ $lines -ne $expect ]; then ret=1; fi if [ $ret -ne 0 ]; then echo_i "failed"; fi diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 0c73dcb69c..e98579b5b3 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -1467,7 +1467,7 @@ ret=0 ( cd signer/general || exit 0 rm -f signed.zone - $SIGNER -f signed.zone -3 - -H 151 -o example.com. test9.zone >signer.out.$n + $SIGNER -f signed.zone -3 - -H 51 -o example.com. test9.zone >signer.out.$n test -f signed.zone ) && ret=1 n=$((n + 1)) @@ -1492,7 +1492,7 @@ ret=0 ( cd signer/general || exit 1 rm -f signed.zone - $SIGNER -f signed.zone -3 - -H 150 -o example.com. test9.zone >signer.out.$n + $SIGNER -f signed.zone -3 - -H 50 -o example.com. test9.zone >signer.out.$n test -f signed.zone ) || ret=1 n=$((n + 1)) @@ -4317,8 +4317,8 @@ status=$((status + ret)) echo_i "checking excessive NSEC3 iteration warnings in named.run ($n)" ret=0 -grep "zone too-many-iterations/IN: excessive NSEC3PARAM iterations [0-9]* > 150" ns2/named.run >/dev/null 2>&1 || ret=1 -grep "zone too-many-iterations/IN: excessive NSEC3PARAM iterations [0-9]* > 150" ns3/named.run >/dev/null 2>&1 || ret=1 +grep "zone too-many-iterations/IN: excessive NSEC3PARAM iterations [0-9]* > 50" ns2/named.run >/dev/null 2>&1 || ret=1 +grep "zone too-many-iterations/IN: excessive NSEC3PARAM iterations [0-9]* > 50" ns3/named.run >/dev/null 2>&1 || ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" status=$((status + ret)) diff --git a/bin/tests/system/nsec3/ns3/named-fips.conf.in b/bin/tests/system/nsec3/ns3/named-fips.conf.in index 7890d4aa6d..4ed7cc0427 100644 --- a/bin/tests/system/nsec3/ns3/named-fips.conf.in +++ b/bin/tests/system/nsec3/ns3/named-fips.conf.in @@ -27,7 +27,7 @@ dnssec-policy "optout" { }; dnssec-policy "nsec3-other" { - nsec3param iterations 11 optout yes salt-length 8; + nsec3param iterations 0 optout yes salt-length 8; }; options { diff --git a/bin/tests/system/nsec3/ns3/named2-fips.conf.in b/bin/tests/system/nsec3/ns3/named2-fips.conf.in index 87e87f2e17..8b42abbcce 100644 --- a/bin/tests/system/nsec3/ns3/named2-fips.conf.in +++ b/bin/tests/system/nsec3/ns3/named2-fips.conf.in @@ -27,7 +27,7 @@ dnssec-policy "optout" { }; dnssec-policy "nsec3-other" { - nsec3param iterations 11 optout yes salt-length 0; + nsec3param iterations 0 optout yes salt-length 8; }; options { diff --git a/bin/tests/system/nsec3/tests.sh b/bin/tests/system/nsec3/tests.sh index 5be7fe33d4..ee49d63f47 100644 --- a/bin/tests/system/nsec3/tests.sh +++ b/bin/tests/system/nsec3/tests.sh @@ -46,12 +46,10 @@ set_zone_policy() { CDS_SHA256="yes" CDS_SHA384="no" } -# Set expected NSEC3 parameters: flags ($1), iterations ($2), and -# salt length ($3). +# Set expected NSEC3 parameters: flags ($1) and salt length ($2). set_nsec3param() { FLAGS=$1 - ITERATIONS=$2 - SALTLEN=$3 + SALTLEN=$2 # Reset salt. SALT="" } @@ -102,7 +100,7 @@ set_key_states() { # The apex NSEC3PARAM record indicates that it is signed. _wait_for_nsec3param() { dig_with_opts +noquestion "@${SERVER}" "$ZONE" NSEC3PARAM >"dig.out.test$n.wait" || return 1 - grep "${ZONE}\..*IN.*NSEC3PARAM.*1.*0.*${ITERATIONS}.*${SALT}" "dig.out.test$n.wait" >/dev/null || return 1 + grep "${ZONE}\..*IN.*NSEC3PARAM 1 0 0.*${SALT}" "dig.out.test$n.wait" >/dev/null || return 1 grep "${ZONE}\..*IN.*RRSIG" "dig.out.test$n.wait" >/dev/null || return 1 return 0 } @@ -188,7 +186,7 @@ check_nsec() { # Test: check NSEC3 parameters in answers _check_nsec3_nsec3param() { dig_with_opts +noquestion @$SERVER "${ZONE}" NSEC3PARAM >"dig.out.test$n.nsec3param.$ZONE" || return 1 - grep "${ZONE}.*0.*IN.*NSEC3PARAM.*1.*0.*${ITERATIONS}.*${SALT}" "dig.out.test$n.nsec3param.$ZONE" >/dev/null || return 1 + grep "${ZONE}.*0.*IN.*NSEC3PARAM.*1.*0.*0.*${SALT}" "dig.out.test$n.nsec3param.$ZONE" >/dev/null || return 1 if [ -z "$SALT" ]; then SALT=$(awk '$4 == "NSEC3PARAM" { print $8 }' dig.out.test$n.nsec3param.$ZONE) @@ -198,7 +196,7 @@ _check_nsec3_nsec3param() { _check_nsec3_nxdomain() { dig_with_opts @$SERVER "nosuchname.${ZONE}" >"dig.out.test$n.nxdomain.$ZONE" || return 1 - grep ".*\.${ZONE}.*IN.*NSEC3.*1.${FLAGS}.*${ITERATIONS}.*${SALT}" "dig.out.test$n.nxdomain.$ZONE" >/dev/null || return 1 + grep ".*\.${ZONE}.*IN.*NSEC3.*1.${FLAGS}.*0.*${SALT}" "dig.out.test$n.nxdomain.$ZONE" >/dev/null || return 1 return 0 } @@ -206,14 +204,14 @@ check_nsec3() { wait_for_zone_is_signed "nsec3" n=$((n + 1)) - echo_i "check that NSEC3PARAM 1 0 ${ITERATIONS} is published zone ${ZONE} ($n)" + echo_i "check that NSEC3PARAM 1 0 0 ${SALT} is published zone ${ZONE} ($n)" ret=0 retry_quiet 10 _check_nsec3_nsec3param || log_error "bad NSEC3PARAM response for ${ZONE}" test "$ret" -eq 0 || echo_i "failed" status=$((status + ret)) n=$((n + 1)) - echo_i "check NXDOMAIN response has correct NSEC3 1 ${FLAGS} ${ITERATIONS} ${SALT} for zone ${ZONE} ($n)" + echo_i "check NXDOMAIN response has correct NSEC3 1 ${FLAGS} 0 ${SALT} for zone ${ZONE} ($n)" ret=0 retry_quiet 10 _check_nsec3_nxdomain || log_error "bad NXDOMAIN response for zone ${ZONE}" test "$ret" -eq 0 || echo_i "failed" @@ -277,21 +275,21 @@ fi # Zone: nsec3.kasp. set_zone_policy "nsec3.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-dynamic.kasp. set_zone_policy "nsec3-dynamic.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-change.kasp. set_zone_policy "nsec3-change.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 @@ -316,49 +314,49 @@ retry_quiet 10 _wait_for_new_soa || log_error "failed to update SOA record in zo # Zone: nsec3-dynamic-change.kasp. set_zone_policy "nsec3-dynamic-change.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-dynamic-to-inline.kasp. set_zone_policy "nsec3-dynamic-to-inline.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-inline-to-dynamic.kasp. set_zone_policy "nsec3-inline-to-dynamic.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-to-nsec.kasp. set_zone_policy "nsec3-to-nsec.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-to-optout.kasp. set_zone_policy "nsec3-to-optout.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-from-optout.kasp. set_zone_policy "nsec3-from-optout.kasp" "optout" 1 3600 -set_nsec3param "1" "0" "0" +set_nsec3param "1" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-other.kasp. set_zone_policy "nsec3-other.kasp" "nsec3-other" 1 3600 -set_nsec3param "1" "11" "8" +set_nsec3param "1" "8" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 @@ -403,7 +401,7 @@ rndc_reconfig ns3 10.53.0.3 # Zone: nsec-to-nsec3.kasp. (reconfigured) set_zone_policy "nsec-to-nsec3.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 @@ -431,7 +429,7 @@ if ($SHELL ../testcrypto.sh -q RSASHA1); then # Zone: nsec3-to-rsasha1.kasp. set_zone_policy "nsec3-to-rsasha1.kasp" "rsasha1" 2 3600 - set_nsec3param "1" "0" "0" + set_nsec3param "1" "0" set_server "ns3" "10.53.0.3" set_key_default_values "KEY1" set_key_states "KEY1" "hidden" "unretentive" "unretentive" "unretentive" "hidden" @@ -443,7 +441,7 @@ if ($SHELL ../testcrypto.sh -q RSASHA1); then # Zone: nsec3-to-rsasha1-ds.kasp. set_zone_policy "nsec3-to-rsasha1-ds.kasp" "rsasha1" 2 3600 - set_nsec3param "1" "0" "0" + set_nsec3param "1" "0" set_server "ns3" "10.53.0.3" set_key_default_values "KEY1" set_key_states "KEY1" "hidden" "omnipresent" "omnipresent" "omnipresent" "omnipresent" @@ -457,21 +455,21 @@ fi # Zone: nsec3.kasp. (same) set_zone_policy "nsec3.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 # Zone: nsec3-dyamic.kasp. (same) set_zone_policy "nsec3-dynamic.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 # Zone: nsec3-change.kasp. (reconfigured) set_zone_policy "nsec3-change.kasp" "nsec3-other" 1 3600 -set_nsec3param "1" "11" "8" +set_nsec3param "1" "8" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 @@ -486,30 +484,36 @@ grep "${ZONE}\..*900.*IN.*NSEC3PARAM" "dig.out.nsec3param.test$n" >/dev/null || test "$ret" -eq 0 || echo_i "failed" status=$((status + ret)) +# Using rndc signing -nsec3param (should fail) +echo_i "use rndc signing -nsec3param ${ZONE} to change NSEC3 settings" +rndccmd $SERVER signing -nsec3param 1 1 12 ffff $ZONE >rndc.signing.test$n.$ZONE || log_error "failed to call rndc signing -nsec3param $ZONE" +grep "zone uses dnssec-policy, use rndc dnssec command instead" rndc.signing.test$n.$ZONE >/dev/null || log_error "rndc signing -nsec3param should fail" +check_nsec3 + # Zone: nsec3-dynamic-change.kasp. (reconfigured) set_zone_policy "nsec3-dynamic-change.kasp" "nsec3-other" 1 3600 -set_nsec3param "1" "11" "8" +set_nsec3param "1" "8" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 # Zone: nsec3-dynamic-to-inline.kasp. (same) set_zone_policy "nsec3-dynamic-to-inline.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 # Zone: nsec3-inline-to-dynamic.kasp. (same) set_zone_policy "nsec3-inline-to-dynamic.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec3 # Zone: nsec3-to-nsec.kasp. (reconfigured) set_zone_policy "nsec3-to-nsec.kasp" "nsec" 1 3600 -set_nsec3param "1" "11" "8" +set_nsec3param "1" "8" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec @@ -519,7 +523,7 @@ check_nsec # There is a bug in the nsec3param building code that thinks when the # optout bit is changed, the chain already exists. [GL #2216] #set_zone_policy "nsec3-to-optout.kasp" "optout" 1 3600 -#set_nsec3param "1" "0" "0" +#set_nsec3param "1" "0" #set_key_default_values "KEY1" #echo_i "check zone ${ZONE} after reconfig" #check_nsec3 @@ -529,28 +533,21 @@ check_nsec # There is a bug in the nsec3param building code that thinks when the # optout bit is changed, the chain already exists. [GL #2216] #set_zone_policy "nsec3-from-optout.kasp" "nsec3" 1 3600 -#set_nsec3param "0" "0" "0" +#set_nsec3param "0" "0" #set_key_default_values "KEY1" #echo_i "check zone ${ZONE} after reconfig" #check_nsec3 # Zone: nsec3-other.kasp. (same) set_zone_policy "nsec3-other.kasp" "nsec3-other" 1 3600 -set_nsec3param "1" "11" "8" +set_nsec3param "1" "8" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 -# Using rndc signing -nsec3param (should fail) -set_zone_policy "nsec3-change.kasp" "nsec3-other" 1 3600 -echo_i "use rndc signing -nsec3param ${ZONE} to change NSEC3 settings" -rndccmd $SERVER signing -nsec3param 1 1 12 ffff $ZONE >rndc.signing.test$n.$ZONE || log_error "failed to call rndc signing -nsec3param $ZONE" -grep "zone uses dnssec-policy, use rndc dnssec command instead" rndc.signing.test$n.$ZONE >/dev/null || log_error "rndc signing -nsec3param should fail" -check_nsec3 - # Test NSEC3 and NSEC3PARAM is the same after restart set_zone_policy "nsec3.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "check zone ${ZONE} before restart" check_nsec3 @@ -570,7 +567,7 @@ status=$((status + ret)) prevsalt="${SALT}" set_zone_policy "nsec3.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" SALT="${prevsalt}" echo_i "check zone ${ZONE} after restart has salt ${SALT}" @@ -581,7 +578,7 @@ cp ns3/template.db.in ns3/nsec3-fails-to-load.kasp.db rndc_reload ns3 10.53.0.3 set_zone_policy "nsec3-fails-to-load.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" "0" +set_nsec3param "0" "0" set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reload" check_nsec3 diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index 775df666d1..9977552ef3 100755 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -433,7 +433,7 @@ if $PERL -e 'use Net::DNS;' 2>/dev/null; then n=$((n + 1)) ret=0 echo_i "check for too many NSEC3 iterations log ($n)" - grep "updating zone 'update.nil/IN': too many NSEC3 iterations (151)" ns1/named.run >/dev/null || ret=1 + grep "updating zone 'update.nil/IN': too many NSEC3 iterations (51)" ns1/named.run >/dev/null || ret=1 [ $ret -eq 1 ] && { echo_i "failed" status=1 @@ -1899,9 +1899,9 @@ echo_i "check that excessive NSEC3PARAM iterations are rejected by nsupdate ($n) $NSUPDATE -d <nsupdate.out.test$n 2>&1 && ret=1 server 10.53.0.3 ${PORT} zone example -update add example 0 in NSEC3PARAM 1 0 151 - +update add example 0 in NSEC3PARAM 1 0 51 - END -grep "NSEC3PARAM has excessive iterations (> 150)" nsupdate.out.test$n >/dev/null || ret=1 +grep "NSEC3PARAM has excessive iterations (> 50)" nsupdate.out.test$n >/dev/null || ret=1 [ $ret = 0 ] || { echo_i "failed" status=1 diff --git a/bin/tests/system/nsupdate/update_test.pl b/bin/tests/system/nsupdate/update_test.pl index 835f1f88c7..066fa2ca15 100644 --- a/bin/tests/system/nsupdate/update_test.pl +++ b/bin/tests/system/nsupdate/update_test.pl @@ -417,8 +417,8 @@ if ($Net::DNS::VERSION < 1.01) { print "skipped Excessive NSEC3PARAM iterations; Net::DNS too old.\n"; } else { section("Excessive NSEC3PARAM iterations"); - test("REFUSED", ["update", rr_add("$zone 300 NSEC3PARAM 1 0 151 -")]); - test("NOERROR", ["update", rr_add("$zone 300 NSEC3PARAM 1 0 150 -")]); + test("REFUSED", ["update", rr_add("$zone 300 NSEC3PARAM 1 0 51 -")]); + test("NOERROR", ["update", rr_add("$zone 300 NSEC3PARAM 1 0 50 -")]); } if ($failures) { diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 7c0b9b30dc..9bb024fe9b 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -33,7 +33,12 @@ Removed Features Feature Changes ~~~~~~~~~~~~~~~ -- None. +- The maximum number of allowed NSEC3 iterations for validation has been + lowered from 150 to 50. DNSSEC responses containing NSEC3 records with + iteration counts greater than 50 are now treated as insecure. :gl:`#4363` + +- The number of NSEC3 iterations that can be configured for a zone must be 0. + :gl:`#4363` Bug Fixes ~~~~~~~~~ diff --git a/lib/dns/include/dns/nsec3.h b/lib/dns/include/dns/nsec3.h index e4da790b06..3cd81cc616 100644 --- a/lib/dns/include/dns/nsec3.h +++ b/lib/dns/include/dns/nsec3.h @@ -26,7 +26,7 @@ #include #define DNS_NSEC3_SALTSIZE 255 -#define DNS_NSEC3_MAXITERATIONS 150U +#define DNS_NSEC3_MAXITERATIONS 50U /* * hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max) diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index 19365fdc06..861cf514b3 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -291,15 +291,12 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, return (DNS_R_NSEC3BADALG); } - if (iter > dns_nsec3_maxiterations()) { - ret = DNS_R_NSEC3ITERRANGE; - } - - if (ret == DNS_R_NSEC3ITERRANGE) { + if (iter != DEFAULT_NSEC3PARAM_ITER) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dnssec-policy: nsec3 iterations value %u " - "out of range", + "not allowed, must be zero", iter); + return (DNS_R_NSEC3ITERRANGE); return (ret); } diff --git a/tests/dns/nsec3_test.c b/tests/dns/nsec3_test.c index c2fcacd994..dd772d1cff 100644 --- a/tests/dns/nsec3_test.c +++ b/tests/dns/nsec3_test.c @@ -115,11 +115,11 @@ nsec3param_salttotext_test(const nsec3param_salttotext_test_params_t *params) { ISC_RUN_TEST_IMPL(max_iterations) { UNUSED(state); - iteration_test(TESTS_DIR "/testdata/nsec3/1024.db", 150); - iteration_test(TESTS_DIR "/testdata/nsec3/2048.db", 150); - iteration_test(TESTS_DIR "/testdata/nsec3/4096.db", 150); - iteration_test(TESTS_DIR "/testdata/nsec3/min-1024.db", 150); - iteration_test(TESTS_DIR "/testdata/nsec3/min-2048.db", 150); + iteration_test(TESTS_DIR "/testdata/nsec3/1024.db", 50); + iteration_test(TESTS_DIR "/testdata/nsec3/2048.db", 50); + iteration_test(TESTS_DIR "/testdata/nsec3/4096.db", 50); + iteration_test(TESTS_DIR "/testdata/nsec3/min-1024.db", 50); + iteration_test(TESTS_DIR "/testdata/nsec3/min-2048.db", 50); } /* check dns_nsec3param_salttotext() */