]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add tests for going from secure to insecure
authorMatthijs Mekking <matthijs@isc.org>
Thu, 3 Dec 2020 07:53:34 +0000 (08:53 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 23 Dec 2020 08:02:11 +0000 (09:02 +0100)
Add two test zones that will be reconfigured to go insecure, by
setting the 'dnssec-policy' option to 'none'.

One zone was using inline-signing (implicitly through dnssec-policy),
the other is a dynamic zone.

Two tweaks to the kasp system test are required: we need to set
when to except the CDS/CDS Delete Records, and we need to know
when we are dealing with a dynamic zone (because the logs to look for
are slightly different, inline-signing prints "(signed)" after the
zone name, dynamic zones do not).

bin/tests/system/kasp/ns6/named.conf.in
bin/tests/system/kasp/ns6/named2.conf.in
bin/tests/system/kasp/ns6/setup.sh
bin/tests/system/kasp/tests.sh

index 5053329e4e49e5a157f0536569d863a8a774c29d..6b08497b0a36f057e7cf97b38570378064fcb903 100644 (file)
@@ -64,6 +64,20 @@ zone "migrate-nomatch-alglen.kasp" {
        update-check-ksk yes;
 };
 
+/* These zones are going insecure. */
+zone "step1.going-insecure.kasp" {
+       type master;
+       file "step1.going-insecure.kasp.db";
+       dnssec-policy "migrate";
+};
+
+zone "step1.going-insecure-dynamic.kasp" {
+       type master;
+       file "step1.going-insecure-dynamic.kasp.db";
+       dnssec-policy "migrate";
+       allow-update { any; };
+};
+
 /* These are alorithm rollover test zones. */
 zone "step1.algorithm-roll.kasp" {
        type primary;
index d07ee9eb6ed359aa15bb221b556a860e9199ee75..f0edd67b2a139af5adb9df2c7f754ba1875a4401 100644 (file)
@@ -57,6 +57,33 @@ zone "migrate-nomatch-alglen.kasp" {
        dnssec-policy "migrate-nomatch-alglen";
 };
 
+/* Zones for testing going insecure. */
+zone "step1.going-insecure.kasp" {
+        type master;
+        file "step1.going-insecure.kasp.db";
+        dnssec-policy "none";
+};
+
+zone "step2.going-insecure.kasp" {
+        type master;
+        file "step2.going-insecure.kasp.db";
+        dnssec-policy "none";
+};
+
+zone "step1.going-insecure-dynamic.kasp" {
+        type master;
+        file "step1.going-insecure-dynamic.kasp.db";
+        dnssec-policy "none";
+       allow-update { any; };
+};
+
+zone "step2.going-insecure-dynamic.kasp" {
+        type master;
+        file "step2.going-insecure-dynamic.kasp.db";
+        dnssec-policy "none";
+       allow-update { any; };
+};
+
 /*
  * Zones for testing KSK/ZSK algorithm roll.
  */
index 7ae089f8d918a0e3b24549103df8165d1a43bde3..99d842eaa543cfa16a94b2a2999b8ab28c2ef5b2 100644 (file)
@@ -86,6 +86,46 @@ private_type_record $zone 5 "$KSK" >> "$infile"
 private_type_record $zone 5 "$ZSK" >> "$infile"
 $SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
 
+# The child zones (step1, step2) beneath these zones represent the various
+# steps of unsigning a zone.
+for zn in going-insecure.kasp going-insecure-dynamic.kasp
+do
+       # Step 1:
+       # Set up a zone with dnssec-policy that is going insecure.
+       setup step1.$zn
+       echo "$zone" >> zones
+       T="now-10d"
+       ksktimes="-P $T -A $T -P sync $T"
+       zsktimes="-P $T -A $T"
+       KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2> keygen.out.$zone.1)
+       ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200        $zsktimes $zone 2> keygen.out.$zone.2)
+       cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
+       private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >> "$infile"
+       private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >> "$infile"
+       $SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
+
+       # Step 2:
+       # Set up a zone with dnssec-policy that is going insecure. Don't add
+       # this zone to the zones file, because this zone is no longer expected
+       # to be fully signed.
+       setup step2.$zn
+       # The DS was withdrawn from the parent zone 26 hours ago.
+       Trem="now-26h"
+       ksktimes="-P $T -A $T -P sync $T"
+       zsktimes="-P $T -A $T"
+       KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2> keygen.out.$zone.1)
+       ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200        $zsktimes $zone 2> keygen.out.$zone.2)
+       $SETTIME -s -g $H -k $O $T -r $O $T -d $U $Trem -D ds $Trem "$KSK" > settime.out.$zone.1 2>&1
+       $SETTIME -s -g $H -k $O $T -z $O $T                         "$ZSK" > settime.out.$zone.2 2>&1
+       # Fake lifetime of old algorithm keys.
+       echo "Lifetime: 0" >> "${KSK}.state"
+       echo "Lifetime: 5184000" >> "${ZSK}.state"
+       cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
+       private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >> "$infile"
+       private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >> "$infile"
+       $SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
+done
+
 #
 # The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK
 # algorithm rollover.
index b8f623b2cf9a16d75cef583ef6b995d3694430f4..d22ec2660bcc2731b3c35e7bb66d174366ef19a4 100644 (file)
@@ -172,12 +172,26 @@ set_server() {
 # Set zone name for testing keys.
 set_zone() {
        ZONE=$1
+       DYNAMIC="no"
 }
+# By default zones are considered static.
+# When testing dynamic zones, call 'set_dynamic' after 'set_zone'.
+set_dynamic() {
+       DYNAMIC="yes"
+}
+
 # Set policy settings (name $1, number of keys $2, dnskey ttl $3) for testing keys.
 set_policy() {
        POLICY=$1
        NUM_KEYS=$2
        DNSKEY_TTL=$3
+       CDS_DELETE="no"
+}
+# By default policies are considered to be secure.
+# If a zone sets its policy to "none", call 'set_cdsdelete' to tell the system
+# test to expect a CDS and CDNSKEY Delete record.
+set_cdsdelete() {
+       CDS_DELETE="yes"
 }
 
 # Set key properties for testing keys.
@@ -1044,6 +1058,14 @@ check_cds() {
        dig_with_opts "$ZONE" "@${SERVER}" "CDNSKEY" > "dig.out.$DIR.test$n.cdnskey" || log_error "dig ${ZONE} CDNSKEY failed"
        grep "status: NOERROR" "dig.out.$DIR.test$n.cdnskey" > /dev/null || log_error "mismatch status in DNS response"
 
+       if [ "$CDS_DELETE" = "no" ]; then
+               grep "CDS.*0 0 0 00" "dig.out.$DIR.test$n.cds" > /dev/null && log_error "unexpected CDS DELETE record in DNS response"
+               grep "CDNSKEY.*0 3 0 AA==" "dig.out.$DIR.test$n.cdnskey" > /dev/null && log_error "unexpected CDNSKEY DELETE record in DNS response"
+       else
+               grep "CDS.*0 0 0 00" "dig.out.$DIR.test$n.cds" > /dev/null || log_error "missing CDS DELETE record in DNS response"
+               grep "CDNSKEY.*0 3 0 AA==" "dig.out.$DIR.test$n.cdnskey" > /dev/null || log_error "missing CDNSKEY DELETE record in DNS response"
+       fi
+
        if [ "$(key_get KEY1 STATE_DS)" = "rumoured" ] || [ "$(key_get KEY1 STATE_DS)" = "omnipresent" ]; then
                response_has_cds_for_key KEY1 "dig.out.$DIR.test$n.cds" || log_error "missing CDS record in response for key $(key_get KEY1 ID)"
                check_signatures "CDS" "dig.out.$DIR.test$n.cds" "KSK"
@@ -1210,7 +1232,13 @@ _loadkeys_on() {
 
        nextpart $_dir/named.run > /dev/null
        rndccmd $_server loadkeys $_zone in $_view > rndc.dnssec.loadkeys.out.$_zone.$n
-       wait_for_log 20 "zone ${_zone}/IN (signed): next key event" $_dir/named.run || return 1
+
+       if [ "${DYNAMIC}" = "yes" ]; then
+               wait_for_log 20 "zone ${_zone}/IN: next key event" $_dir/named.run || return 1
+       else
+               # inline-signing zone adds "(signed)"
+               wait_for_log 20 "zone ${_zone}/IN (signed): next key event" $_dir/named.run || return 1
+       fi
 }
 
 # Tell named that the DS for the key in given zone has been seen in the
@@ -1346,6 +1374,7 @@ status=$((status+ret))
 # Zone: dynamic.kasp
 #
 set_zone "dynamic.kasp"
+set_dynamic
 set_policy "default" "1" "3600"
 set_server "ns3" "10.53.0.3"
 # Key properties, timings and states same as above.
@@ -1378,6 +1407,7 @@ status=$((status+ret))
 # Zone: dynamic-inline-signing.kasp
 #
 set_zone "dynamic-inline-signing.kasp"
+set_dynamic
 set_policy "default" "1" "3600"
 set_server "ns3" "10.53.0.3"
 # Key properties, timings and states same as above.
@@ -2937,7 +2967,12 @@ check_next_key_event() {
        grep "zone ${ZONE}.*: next key event in .* seconds" "${DIR}/named.run" > "keyevent.out.$ZONE.test$n" || log_error "no next key event for zone ${ZONE}"
 
        # Get the latest next key event.
-       _time=$(awk '{print $10}' < "keyevent.out.$ZONE.test$n" | tail -1)
+       if [ "${DYNAMIC}" = "yes" ]; then
+               _time=$(awk '{print $9}' < "keyevent.out.$ZONE.test$n" | tail -1)
+       else
+               # inline-signing zone adds "(signed)"
+               _time=$(awk '{print $10}' < "keyevent.out.$ZONE.test$n" | tail -1)
+       fi
 
        # The next key event time must within threshold of the
        # expected time.
@@ -4452,6 +4487,90 @@ dnssec_verify
 _migratenomatch_alglen_ksk=$(key_get KEY1 ID)
 _migratenomatch_alglen_zsk=$(key_get KEY2 ID)
 
+#
+# Testing going insecure.
+#
+
+#
+# Zone step1.going-insecure.kasp
+#
+set_zone "step1.going-insecure.kasp"
+set_policy "migrate" "2" "7200"
+set_server "ns6" "10.53.0.6"
+
+# Policy parameters.
+# Lksk:      0
+# Lzsk:      60 days (5184000 seconds)
+# Iret(KSK): DS TTL (1d) + DprpP (1h) + retire-safety (1h)
+# Iret(KSK): 1d2h (93600 seconds)
+# Iret(ZSK): RRSIG TTL (1d) + Dprp (5m) + Dsgn (9d) + retire-safety (1h)
+# Iret(ZSK): 10d1h5m (867900 seconds)
+Lksk=0
+Lzsk=5184000
+IretKSK=93600
+IretZSK=867900
+
+init_migration_insecure() {
+       key_clear        "KEY1"
+       set_keyrole      "KEY1" "ksk"
+       set_keylifetime  "KEY1" "${Lksk}"
+       set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
+       set_keysigning   "KEY1" "yes"
+       set_zonesigning  "KEY1" "no"
+
+       set_keystate "KEY1" "GOAL"         "omnipresent"
+       set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
+       set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
+       set_keystate "KEY1" "STATE_DS"     "omnipresent"
+
+       key_clear        "KEY2"
+       set_keyrole      "KEY2" "zsk"
+       set_keylifetime  "KEY2" "${Lzsk}"
+       set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
+       set_keysigning   "KEY2" "no"
+       set_zonesigning  "KEY2" "yes"
+
+       set_keystate "KEY2" "GOAL"         "omnipresent"
+       set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
+       set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
+
+       key_clear "KEY3"
+       key_clear "KEY4"
+}
+init_migration_insecure
+
+# Various signing policy checks.
+check_keys
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+
+# We have set the timing metadata to now - 10 days (864000 seconds).
+rollover_predecessor_keytimes -864000
+check_keytimes
+check_apex
+check_subdomain
+dnssec_verify
+
+#
+# Zone step1.going-insecure-dynamic.kasp
+#
+
+set_zone "step1.going-insecure-dynamic.kasp"
+set_dynamic
+set_policy "migrate" "2" "7200"
+set_server "ns6" "10.53.0.6"
+init_migration_insecure
+
+# Various signing policy checks.
+check_keys
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+
+# We have set the timing metadata to now - 10 days (864000 seconds).
+rollover_predecessor_keytimes -864000
+check_keytimes
+check_apex
+check_subdomain
+dnssec_verify
+
 # Reconfig dnssec-policy (triggering algorithm roll and other dnssec-policy
 # changes).
 echo_i "reconfig dnssec-policy to trigger algorithm rollover"
@@ -4501,6 +4620,148 @@ wait_for_done_signing() {
        status=$((status+ret))
 }
 
+#
+# Testing going insecure.
+#
+
+#
+# Zone: step1.going-insecure.kasp
+#
+set_zone "step1.going-insecure.kasp"
+set_policy "none" "2" "7200"
+set_server "ns6" "10.53.0.6"
+# Expect a CDS/CDNSKEY Delete Record.
+set_cdsdelete
+
+# Key goal states should be HIDDEN.
+init_migration_insecure
+set_keystate "KEY1" "GOAL" "hidden"
+set_keystate "KEY2" "GOAL" "hidden"
+# The DS may be removed if we are going insecure.
+set_keystate "KEY1" "STATE_DS" "unretentive"
+
+# Various signing policy checks.
+check_keys
+wait_for_done_signing
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+check_apex
+check_subdomain
+dnssec_verify
+
+# Tell named that the DS has been removed.
+rndc_checkds "$SERVER" "$DIR" "KEY1" "now" "withdrawn" "$ZONE"
+wait_for_done_signing
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+check_apex
+check_subdomain
+dnssec_verify
+
+# Next key event is when the DS becomes HIDDEN. This happens after the
+# parent propagation delay, retire safety delay, and DS TTL:
+# 1h + 1h + 1d = 26h = 93600 seconds.
+check_next_key_event 93600
+
+#
+# Zone: step2.going-insecure.kasp
+#
+set_zone "step2.going-insecure.kasp"
+set_policy "none" "2" "7200"
+set_server "ns6" "10.53.0.6"
+# Expect a CDS/CDNSKEY Delete Record.
+set_cdsdelete
+
+# The DS is long enough removed from the zone to be considered HIDDEN.
+# This means the DNSKEY and the KSK signatures can be removed.
+set_keystate     "KEY1" "STATE_DS"     "hidden"
+set_keystate     "KEY1" "STATE_DNSKEY" "unretentive"
+set_keystate     "KEY1" "STATE_KRRSIG" "unretentive"
+set_keysigning   "KEY1" "no"
+
+set_keystate     "KEY2" "STATE_DNSKEY" "unretentive"
+set_keystate     "KEY2" "STATE_ZRRSIG" "unretentive"
+set_zonesigning  "KEY2" "no"
+
+# Various signing policy checks.
+check_keys
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+check_apex
+check_subdomain
+
+# Next key event is when the DNSKEY becomes HIDDEN. This happens after the
+# propagation delay, plus DNSKEY TTL:
+# 5m + 2h = 125m =  7500 seconds.
+check_next_key_event 7500
+
+#
+# Zone: step1.going-insecure-dynamic.kasp
+#
+set_zone "step1.going-insecure-dynamic.kasp"
+set_dynamic
+set_policy "none" "2" "7200"
+set_server "ns6" "10.53.0.6"
+# Expect a CDS/CDNSKEY Delete Record.
+set_cdsdelete
+
+# Key goal states should be HIDDEN.
+init_migration_insecure
+set_keystate "KEY1" "GOAL" "hidden"
+set_keystate "KEY2" "GOAL" "hidden"
+# The DS may be removed if we are going insecure.
+set_keystate "KEY1" "STATE_DS" "unretentive"
+
+# Various signing policy checks.
+check_keys
+wait_for_done_signing
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+check_apex
+check_subdomain
+dnssec_verify
+
+# Tell named that the DS has been removed.
+rndc_checkds "$SERVER" "$DIR" "KEY1" "now" "withdrawn" "$ZONE"
+wait_for_done_signing
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+check_apex
+check_subdomain
+dnssec_verify
+
+# Next key event is when the DS becomes HIDDEN. This happens after the
+# parent propagation delay, retire safety delay, and DS TTL:
+# 1h + 1h + 1d = 26h = 93600 seconds.
+check_next_key_event 93600
+
+#
+# Zone: step2.going-insecure-dynamic.kasp
+#
+set_zone "step2.going-insecure-dynamic.kasp"
+set_dynamic
+set_policy "none" "2" "7200"
+set_server "ns6" "10.53.0.6"
+# Expect a CDS/CDNSKEY Delete Record.
+set_cdsdelete
+
+# The DS is long enough removed from the zone to be considered HIDDEN.
+# This means the DNSKEY and the KSK signatures can be removed.
+set_keystate     "KEY1" "STATE_DS"     "hidden"
+set_keystate     "KEY1" "STATE_DNSKEY" "unretentive"
+set_keystate     "KEY1" "STATE_KRRSIG" "unretentive"
+set_keysigning   "KEY1" "no"
+
+set_keystate     "KEY2" "STATE_DNSKEY" "unretentive"
+set_keystate     "KEY2" "STATE_ZRRSIG" "unretentive"
+set_zonesigning  "KEY2" "no"
+
+# Various signing policy checks.
+check_keys
+check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
+check_apex
+check_subdomain
+
+# Next key event is when the DNSKEY becomes HIDDEN. This happens after the
+# propagation delay, plus DNSKEY TTL:
+# 5m + 2h = 125m =  7500 seconds.
+check_next_key_event 7500
+
 #
 # Testing migration.
 #