diff --git a/bin/tests/system/kasp/README b/bin/tests/system/kasp/README index 23a7c8da34..48d5132dce 100644 --- a/bin/tests/system/kasp/README +++ b/bin/tests/system/kasp/README @@ -13,3 +13,6 @@ ns3 is an authoritative server for the various test domains. ns4 and ns5 are authoritative servers for various test domains related to views. ns6 is an authoritative server that tests changes in dnssec-policy. + +ns7 is an authoritative server that tests a specific case where zones +using views migrate to dnssec-policy. diff --git a/bin/tests/system/kasp/ns7/named.conf.in b/bin/tests/system/kasp/ns7/named.conf.in new file mode 100644 index 0000000000..7a371218e5 --- /dev/null +++ b/bin/tests/system/kasp/ns7/named.conf.in @@ -0,0 +1,70 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +// NS7 + +options { + query-source address 10.53.0.7; + notify-source 10.53.0.7; + transfer-source 10.53.0.7; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.7; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.7 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +key "external" { + algorithm "hmac-sha1"; + secret "YPfMoAk6h+3iN8MDRQC004iSNHY="; +}; + +key "internal" { + algorithm "hmac-sha1"; + secret "4xILSZQnuO1UKubXHkYUsvBRPu8="; +}; + +view "ext" { + match-clients { key "external"; }; + + zone "view-rsasha256.kasp" { + type master; + file "view-rsasha256.kasp.ext.db"; + auto-dnssec maintain; + inline-signing yes; + dnssec-dnskey-kskonly yes; + update-check-ksk yes; + }; +}; + +view "int" { + match-clients { key "internal"; }; + + zone "view-rsasha256.kasp" { + type master; + file "view-rsasha256.kasp.int.db"; + auto-dnssec maintain; + inline-signing yes; + dnssec-dnskey-kskonly yes; + update-check-ksk yes; + }; +}; diff --git a/bin/tests/system/kasp/ns7/named2.conf.in b/bin/tests/system/kasp/ns7/named2.conf.in new file mode 100644 index 0000000000..5215b7388d --- /dev/null +++ b/bin/tests/system/kasp/ns7/named2.conf.in @@ -0,0 +1,81 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +// NS7 + +options { + query-source address 10.53.0.7; + notify-source 10.53.0.7; + transfer-source 10.53.0.7; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.7; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.7 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +key "external" { + algorithm "hmac-sha1"; + secret "YPfMoAk6h+3iN8MDRQC004iSNHY="; +}; + +key "internal" { + algorithm "hmac-sha1"; + secret "4xILSZQnuO1UKubXHkYUsvBRPu8="; +}; + +dnssec-policy "rsasha256" { + keys { + zsk key-directory lifetime P3M algorithm 8 1024; + ksk key-directory lifetime P1Y algorithm 8 2048; + }; + + dnskey-ttl 6h; + publish-safety 1h; + retire-safety 1h; + + signatures-refresh 5d; + signatures-validity 14d; + signatures-validity-dnskey 14d; + + max-zone-ttl 1d; + zone-propagation-delay 300; + + parent-ds-ttl 86400; + parent-propagation-delay 3h; +}; + +view "external-view" { + zone "view-rsasha256.kasp" { + type master; + file "view-rsasha256.kasp.ext.db"; + dnssec-policy "rsasha256"; + }; +}; + +view "internal-view" { + zone "view-rsasha256.kasp" { + type master; + file "view-rsasha256.kasp.int.db"; + dnssec-policy "rsasha256"; + }; +}; diff --git a/bin/tests/system/kasp/ns7/setup.sh b/bin/tests/system/kasp/ns7/setup.sh new file mode 100644 index 0000000000..75f245b4d5 --- /dev/null +++ b/bin/tests/system/kasp/ns7/setup.sh @@ -0,0 +1,54 @@ +#!/bin/sh -e +# +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +# shellcheck source=conf.sh +. ../../conf.sh + +echo_i "ns7/setup.sh" + +private_type_record() { + _zone=$1 + _algorithm=$2 + _keyfile=$3 + + _id=$(keyfile_to_key_id "$_keyfile") + + printf "%s. 0 IN TYPE65534 %s 5 %02x%04x0000\n" "$_zone" "\\#" "$_algorithm" "$_id" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +zone="view-rsasha256.kasp" +algo="RSASHA256" +num="8" +echo "$zone" >> zones + +# Set up zones in views with auto-dnssec maintain to migrate to dnssec-policy. +# The keys for these zones are in use long enough that they should start a +# rollover for the ZSK (P3M), but not long enough to initiate a KSK rollover (P1Y). +ksktimes="-P -186d -A -186d -P sync -186d" +zsktimes="-P -186d -A -186d" +KSK=$($KEYGEN -a $algo -L 21600 -b 2048 -f KSK $ksktimes $zone 2> keygen.out.$zone.1) +ZSK=$($KEYGEN -a $algo -L 21600 -b 1024 $zsktimes $zone 2> keygen.out.$zone.2) + +echo_i "setting up zone $zone (external)" +view="ext" +zonefile="${zone}.${view}.db" +cat template.$view.db.in "${KSK}.key" "${ZSK}.key" > "$zonefile" + +echo_i "setting up zone $zone (internal)" +view="int" +zonefile="${zone}.${view}.db" +cat template.$view.db.in "${KSK}.key" "${ZSK}.key" > "$zonefile" diff --git a/bin/tests/system/kasp/ns7/template.ext.db.in b/bin/tests/system/kasp/ns7/template.ext.db.in new file mode 100644 index 0000000000..a4c962c663 --- /dev/null +++ b/bin/tests/system/kasp/ns7/template.ext.db.in @@ -0,0 +1,22 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 +@ IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + + NS ns7 +ns7 A 10.53.0.7 + +view TXT "external" diff --git a/bin/tests/system/kasp/ns7/template.int.db.in b/bin/tests/system/kasp/ns7/template.int.db.in new file mode 100644 index 0000000000..7f859c280d --- /dev/null +++ b/bin/tests/system/kasp/ns7/template.int.db.in @@ -0,0 +1,22 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 +@ IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + + NS ns7 +ns7 A 10.53.0.7 + +view TXT "internal" diff --git a/bin/tests/system/kasp/setup.sh b/bin/tests/system/kasp/setup.sh index 5a1f853d3c..4e789096ab 100644 --- a/bin/tests/system/kasp/setup.sh +++ b/bin/tests/system/kasp/setup.sh @@ -23,6 +23,7 @@ copy_setports ns3/named.conf.in ns3/named.conf copy_setports ns4/named.conf.in ns4/named.conf copy_setports ns5/named.conf.in ns5/named.conf copy_setports ns6/named.conf.in ns6/named.conf +copy_setports ns7/named.conf.in ns7/named.conf if $SHELL ../testcrypto.sh ed25519; then echo "yes" > ed25519-supported.file @@ -53,3 +54,7 @@ fi cd ns6 $SHELL setup.sh ) +( + cd ns7 + $SHELL setup.sh +) diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index e8ff6506d3..1851e341c0 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -127,6 +127,7 @@ key_clear "KEY4" # Call dig with default options. dig_with_opts() { + if [ -n "$TSIG" ]; then "$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" -y "$TSIG" "$@" else @@ -5271,5 +5272,230 @@ dnssec_verify # an unlimited lifetime. Fallback to the default loadkeys interval. check_next_key_event 3600 +# +# Testing good migration with views. +# +init_view_migration() { + key_clear "KEY1" + key_set "KEY1" "LEGACY" "yes" + set_keyrole "KEY1" "ksk" + set_keylifetime "KEY1" "0" + set_keysigning "KEY1" "yes" + set_zonesigning "KEY1" "no" + + key_clear "KEY2" + key_set "KEY2" "LEGACY" "yes" + set_keyrole "KEY2" "zsk" + set_keylifetime "KEY2" "0" + set_keysigning "KEY2" "no" + set_zonesigning "KEY2" "yes" + + key_clear "KEY3" + key_clear "KEY4" + + set_keystate "KEY1" "GOAL" "omnipresent" + set_keystate "KEY1" "STATE_DNSKEY" "rumoured" + set_keystate "KEY1" "STATE_KRRSIG" "rumoured" + set_keystate "KEY1" "STATE_DS" "rumoured" + + set_keystate "KEY2" "GOAL" "omnipresent" + set_keystate "KEY2" "STATE_DNSKEY" "rumoured" + set_keystate "KEY2" "STATE_ZRRSIG" "rumoured" +} + +set_keytimes_view_migration() { + # Key is six months in use. + created=$(key_get KEY1 CREATED) + set_addkeytime "KEY1" "PUBLISHED" "${created}" -16070400 + set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" -16070400 + set_addkeytime "KEY1" "ACTIVE" "${created}" -16070400 + created=$(key_get KEY2 CREATED) + set_addkeytime "KEY2" "PUBLISHED" "${created}" -16070400 + set_addkeytime "KEY2" "ACTIVE" "${created}" -16070400 +} + +# Zone view.rsasha256.kasp (external) +set_zone "view-rsasha256.kasp" +set_policy "rsasha256" "2" "21600" +set_server "ns7" "10.53.0.7" +init_view_migration +set_keyalgorithm "KEY1" "8" "RSASHA256" "2048" +set_keyalgorithm "KEY2" "8" "RSASHA256" "1024" +TSIG="hmac-sha1:external:$VIEW1" +wait_for_nsec +# Make sure the zone is signed with legacy keys. +check_keys +set_keytimes_view_migration +check_keytimes +dnssec_verify + +n=$((n+1)) +# check subdomain +echo_i "check TXT $ZONE (view ext) rrset is signed correctly ($n)" +ret=0 +dig_with_opts "view.${ZONE}" "@${SERVER}" TXT > "dig.out.$DIR.test$n.txt" || log_error "dig view.${ZONE} TXT failed" +grep "status: NOERROR" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "mismatch status in DNS response" +grep "view.${ZONE}\..*${DEFAULT_TTL}.*IN.*TXT.*external" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "missing view.${ZONE} TXT record in response" +check_signatures TXT "dig.out.$DIR.test$n.txt" "ZSK" +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# Remember legacy key tags. +_migrate_ext8_ksk=$(key_get KEY1 ID) +_migrate_ext8_zsk=$(key_get KEY2 ID) + +# Zone view.rsasha256.kasp (internal) +set_zone "view-rsasha256.kasp" +set_policy "rsasha256" "2" "21600" +set_server "ns7" "10.53.0.7" +init_view_migration +set_keyalgorithm "KEY1" "8" "RSASHA256" "2048" +set_keyalgorithm "KEY2" "8" "RSASHA256" "1024" +TSIG="hmac-sha1:internal:$VIEW2" +wait_for_nsec +# Make sure the zone is signed with legacy keys. +check_keys +set_keytimes_view_migration +check_keytimes +dnssec_verify + +n=$((n+1)) +# check subdomain +echo_i "check TXT $ZONE (view int) rrset is signed correctly ($n)" +ret=0 +dig_with_opts "view.${ZONE}" "@${SERVER}" TXT > "dig.out.$DIR.test$n.txt" || log_error "dig view.${ZONE} TXT failed" +grep "status: NOERROR" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "mismatch status in DNS response" +grep "view.${ZONE}\..*${DEFAULT_TTL}.*IN.*TXT.*internal" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "missing view.${ZONE} TXT record in response" +check_signatures TXT "dig.out.$DIR.test$n.txt" "ZSK" +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# Remember legacy key tags. +_migrate_int8_ksk=$(key_get KEY1 ID) +_migrate_int8_zsk=$(key_get KEY2 ID) + +# Reconfig dnssec-policy. +echo_i "reconfig to switch to dnssec-policy" +copy_setports ns7/named2.conf.in ns7/named.conf +rndc_reconfig ns7 10.53.0.7 + +# Calculate time passed to correctly check for next key events. +now="$(TZ=UTC date +%s)" +time_passed=$((now-start_time)) +echo_i "${time_passed} seconds passed between start of tests and reconfig" + +# +# Testing migration (RSASHA256, views). +# +set_zone "view-rsasha256.kasp" +set_policy "rsasha256" "3" "21600" +set_server "ns7" "10.53.0.7" +init_migration_match +set_keyalgorithm "KEY1" "8" "RSASHA256" "2048" +set_keyalgorithm "KEY2" "8" "RSASHA256" "1024" +# Key properties, timings and metadata should be the same as legacy keys above. +# However, because the keys have a lifetime, kasp will set the retired time. +key_set "KEY1" "LEGACY" "no" +set_keylifetime "KEY1" "31536000" +set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" +set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" +set_keystate "KEY1" "STATE_DS" "omnipresent" + +key_set "KEY2" "LEGACY" "no" +set_keylifetime "KEY2" "8035200" +set_keystate "KEY2" "STATE_DNSKEY" "omnipresent" +set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent" +# The ZSK needs to be replaced. +set_keystate "KEY2" "GOAL" "hidden" +set_keystate "KEY3" "GOAL" "omnipresent" +set_keyrole "KEY3" "zsk" +set_keylifetime "KEY3" "8035200" +set_keyalgorithm "KEY3" "8" "RSASHA256" "1024" +set_keysigning "KEY3" "no" +set_zonesigning "KEY3" "no" # not yet +set_keystate "KEY3" "STATE_DNSKEY" "rumoured" +set_keystate "KEY3" "STATE_ZRRSIG" "hidden" + +# Various signing policy checks (external). +TSIG="hmac-sha1:external:$VIEW1" +check_keys +wait_for_done_signing +check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" "external-view" +set_keytimes_view_migration + +# Set expected key times: +published=$(key_get KEY1 PUBLISHED) +set_keytime "KEY1" "ACTIVE" "${published}" +set_keytime "KEY1" "SYNCPUBLISH" "${published}" +# Lifetime: 1 year (8035200 seconds) +active=$(key_get KEY1 ACTIVE) +set_addkeytime "KEY1" "RETIRED" "${active}" "31536000" +# Retire interval: +# DS TTL: 1d +# Parent zone propagation: 3h +# Retire safety: 1h +# Total: 100800 seconds +retired=$(key_get KEY1 RETIRED) +set_addkeytime "KEY1" "REMOVED" "${retired}" "100800" + +published=$(key_get KEY2 PUBLISHED) +set_keytime "KEY2" "ACTIVE" "${published}" +# Lifetime: 3 months (8035200 seconds) +active=$(key_get KEY2 ACTIVE) +set_addkeytime "KEY2" "RETIRED" "${active}" "8035200" +# Retire interval: +# Sign delay: 9d (14-5) +# Max zone TTL: 1d +# Retire safety: 1h +# Zone propagation delay: 300s +# Total: 867900 seconds +retired=$(key_get KEY2 RETIRED) +set_addkeytime "KEY2" "REMOVED" "${retired}" "867900" + +created=$(key_get KEY3 CREATED) +set_keytime "KEY3" "PUBLISHED" "${created}" +# Publication interval: +# DNSKEY TTL: 6h +# Publish safety: 1h +# Zone propagation delay: 300s +# Total: 25500 seconds +set_addkeytime "KEY3" "ACTIVE" "${created}" "25500" +# Lifetime: 3 months (8035200 seconds) +active=$(key_get KEY3 ACTIVE) +set_addkeytime "KEY3" "RETIRED" "${active}" "8035200" +# Retire interval: +# Sign delay: 9d (14-5) +# Max zone TTL: 1d +# Retire safety: 1h +# Zone propagation delay: 300s +# Total: 867900 seconds +retired=$(key_get KEY3 RETIRED) +set_addkeytime "KEY3" "REMOVED" "${retired}" "867900" + +# Continue signing policy checks. +check_keytimes +check_apex +dnssec_verify + +# Various signing policy checks (external). +TSIG="hmac-sha1:internal:$VIEW2" +check_keys +wait_for_done_signing +check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" "internal-view" +set_keytimes_view_migration +check_keytimes +check_apex +dnssec_verify + +# Check key tags, should be the same. +n=$((n+1)) +echo_i "check that of zone ${ZONE} migration to dnssec-policy uses the same keys ($n)" +ret=0 +[ $_migrate_ext8_ksk == $_migrate_int8_ksk ] || log_error "mismatch ksk tag" +[ $_migrate_ext8_zsk == $_migrate_int8_zsk ] || log_error "mismatch zsk tag" +[ $_migrate_ext8_ksk == $(key_get KEY1 ID) ] || log_error "mismatch ksk tag" +[ $_migrate_ext8_zsk == $(key_get KEY2 ID) ] || log_error "mismatch zsk tag" +status=$((status+ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/util/copyrights b/util/copyrights index 8f6d7c22a2..c33c9c60da 100644 --- a/util/copyrights +++ b/util/copyrights @@ -507,6 +507,7 @@ ./bin/tests/system/kasp/ns4/setup.sh SH 2019,2020 ./bin/tests/system/kasp/ns5/setup.sh SH 2019,2020 ./bin/tests/system/kasp/ns6/setup.sh SH 2020 +./bin/tests/system/kasp/ns7/setup.sh SH 2020 ./bin/tests/system/kasp/setup.sh SH 2019,2020 ./bin/tests/system/kasp/tests.sh SH 2019,2020 ./bin/tests/system/keepalive/clean.sh SH 2017,2018,2019,2020