diff --git a/CHANGES b/CHANGES index 6e7aaa78bf..304b238c6a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +3092. [bug] Signatures for records at the zone apex could go + stale due to an incorrect timer setting. [RT #23769] + +3091. [bug] Fixed a bug in which zone keys that were published + and then subsequently activated could fail to trigger + automatic signing. [RT #22991] + 3090. [func] Make --with-gssapi default [RT #23738] 3089. [func] dnssec-dsfromkey now supports reading keys from diff --git a/bin/named/update.c b/bin/named/update.c index 3d6ac73b38..89eb4fc992 100644 --- a/bin/named/update.c +++ b/bin/named/update.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: update.c,v 1.191 2011/03/11 12:51:40 marka Exp $ */ +/* $Id: update.c,v 1.192 2011/03/25 23:53:02 each Exp $ */ #include @@ -2395,7 +2395,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, name, diff)); } CHECK(add_exposed_sigs(client, zone, db, newver, name, - cut, diff, zone_keys, nkeys, + cut, &sig_diff, zone_keys, nkeys, inception, expire, check_ksk, keyset_kskonly)); } @@ -2554,7 +2554,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, privatetype, &nsec_diff)); } else { CHECK(add_exposed_sigs(client, zone, db, newver, name, - cut, diff, zone_keys, nkeys, + cut, &sig_diff, zone_keys, nkeys, inception, expire, check_ksk, keyset_kskonly)); CHECK(dns_nsec3_addnsec3sx(db, newver, name, nsecttl, diff --git a/bin/tests/system/autosign/clean.sh b/bin/tests/system/autosign/clean.sh index 91c094fd21..2e9cf7b15a 100644 --- a/bin/tests/system/autosign/clean.sh +++ b/bin/tests/system/autosign/clean.sh @@ -14,11 +14,12 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.9 2011/03/17 23:47:30 tbox Exp $ +# $Id: clean.sh,v 1.10 2011/03/25 23:53:02 each Exp $ rm -f */K* */dsset-* */*.signed */trusted.conf */tmp* */*.jnl */*.bk rm -f active.key inact.key del.key unpub.key standby.key rev.key rm -f nopriv.key vanishing.key del1.key del2.key +rm -f delayksk.key delayzsk.key rm -f nsupdate.out rm -f */core rm -f */example.bk diff --git a/bin/tests/system/autosign/ns3/keygen.sh b/bin/tests/system/autosign/ns3/keygen.sh index f28df31dbd..33b23c1212 100644 --- a/bin/tests/system/autosign/ns3/keygen.sh +++ b/bin/tests/system/autosign/ns3/keygen.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: keygen.sh,v 1.10 2011/03/17 23:47:30 tbox Exp $ +# $Id: keygen.sh,v 1.11 2011/03/25 23:53:02 each Exp $ SYSTEMTESTTOP=../.. . $SYSTEMTESTTOP/conf.sh @@ -238,3 +238,13 @@ zonefile="${zone}.db" $KEYGEN -3 -q -r $RANDFILE -L 30 -fk $zone > /dev/null cat ${infile} K${zone}.+*.key > $zonefile $KEYGEN -3 -q -r $RANDFILE -L 180 $zone > /dev/null + +# +# A zone with a DNSKEY RRset that is published before it's activated +# +zone=delay.example +zonefile="${zone}.db" +ksk=`$KEYGEN -G -q -3 -r $RANDFILE -fk $zone` +echo $ksk > ../delayksk.key +zsk=`$KEYGEN -G -q -3 -r $RANDFILE $zone` +echo $zsk > ../delayzsk.key diff --git a/bin/tests/system/autosign/ns3/named.conf b/bin/tests/system/autosign/ns3/named.conf index 0036b4932c..4d6598ee3d 100644 --- a/bin/tests/system/autosign/ns3/named.conf +++ b/bin/tests/system/autosign/ns3/named.conf @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.9 2011/03/17 23:47:30 tbox Exp $ */ +/* $Id: named.conf,v 1.10 2011/03/25 23:53:02 each Exp $ */ // NS3 @@ -213,4 +213,10 @@ zone "ttl4.example" { auto-dnssec maintain; }; +zone "delay.example" { + type master; + file "delay.example.db"; + allow-update { any; }; + auto-dnssec maintain; +}; include "trusted.conf"; diff --git a/bin/tests/system/autosign/tests.sh b/bin/tests/system/autosign/tests.sh index 00abad89be..a03bdac832 100644 --- a/bin/tests/system/autosign/tests.sh +++ b/bin/tests/system/autosign/tests.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.19 2011/03/21 16:53:44 each Exp $ +# $Id: tests.sh,v 1.20 2011/03/25 23:53:02 each Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -797,10 +797,62 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:waiting for former active key to be removed" -sleep 10 +echo "I:checking delayed key publication/activation ($n)" +ret=0 +zsk=`cat delayzsk.key` +ksk=`cat delayksk.key` +# publication and activation times should be unset +$SETTIME -K ns3 -pA -pP $zsk | grep -v UNSET > /dev/null 2>&1 && ret=1 +$SETTIME -K ns3 -pA -pP $ksk | grep -v UNSET > /dev/null 2>&1 && ret=1 +$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 +# DNSKEY not expected: +awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` -echo "I:checking key was removed ($n)" +echo "I:checking scheduled key publication, not activation ($n)" +ret=0 +$SETTIME -K ns3 -P now+3s -A none $zsk > /dev/null 2>&1 +$SETTIME -K ns3 -P now+3s -A none $ksk > /dev/null 2>&1 +$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /' + +echo "I:waiting for changes to take effect" +sleep 5 + +$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 +# DNSKEY expected: +awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n || ret=1 +# RRSIG not expected: +awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking scheduled key activation ($n)" +ret=0 +$SETTIME -K ns3 -A now+3s $zsk > /dev/null 2>&1 +$SETTIME -K ns3 -A now+3s $ksk > /dev/null 2>&1 +$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /' + +echo "I:waiting for changes to take effect" +sleep 5 + +$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.1.test$n || ret=1 +# DNSKEY expected: +awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1 +# RRSIG expected: +awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1 +$DIG $DIGOPTS +noall +answer a a.delay.example. @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 +# A expected: +awk 'BEGIN {r=1} $4=="A" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1 +# RRSIG expected: +awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking former active key was removed ($n)" ret=0 $DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 grep '; key id =.*'"$oldid"'$' dig.out.ns1.test$n > /dev/null && ret=1 diff --git a/lib/dns/diff.c b/lib/dns/diff.c index 840fa4932d..db665d95cc 100644 --- a/lib/dns/diff.c +++ b/lib/dns/diff.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: diff.c,v 1.25 2011/03/12 04:59:47 tbox Exp $ */ +/* $Id: diff.c,v 1.26 2011/03/25 23:53:02 each Exp $ */ /*! \file */ @@ -373,6 +373,15 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, diff->resign); dns_db_setsigningtime(db, modified, resign); + if (diff->resign == 0 && + (op == DNS_DIFFOP_ADDRESIGN || + op == DNS_DIFFOP_DELRESIGN)) + isc_log_write( + DIFF_COMMON_LOGARGS, + ISC_LOG_WARNING, + "resign requested " + "with 0 resign " + "interval"); } } else if (result == DNS_R_UNCHANGED) { /* diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 2b114c2984..8d8b2f429b 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.600 2011/03/21 18:38:40 each Exp $ */ +/* $Id: zone.c,v 1.601 2011/03/25 23:53:02 each Exp $ */ /*! \file */ @@ -4511,6 +4511,7 @@ static void set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) { unsigned int delta; + char timebuf[80]; zone->key_expiry = when; if (when <= now) { @@ -4518,19 +4519,22 @@ set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) "DNSKEY RRSIG(s) have expired"); isc_time_settoepoch(&zone->keywarntime); } else if (when < now + 7 * 24 * 3600) { + isc_time_t t; + isc_time_set(&t, when, 0); + isc_time_formattimestamp(&t, timebuf, 80); dns_zone_log(zone, ISC_LOG_WARNING, - "DNSKEY RRSIG(s) will expire at %u", - when); /* XXXMPA convert to date. */ + "DNSKEY RRSIG(s) will expire within 7 days: %s", + timebuf); delta = when - now; delta--; /* loop prevention */ delta /= 24 * 3600; /* to whole days */ delta *= 24 * 3600; /* to seconds */ isc_time_set(&zone->keywarntime, when - delta, 0); } else { - dns_zone_log(zone, ISC_LOG_NOTICE, /* XXMPA ISC_LOG_DEBUG(1) */ - "setting keywarntime to %u - 7 days", - when); /* XXXMPA convert to date. */ isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); + isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); + dns_zone_log(zone, ISC_LOG_NOTICE, + "setting keywarntime to %s", timebuf); } } @@ -7255,6 +7259,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { INSIST(result == ISC_R_SUCCESS); dns_diff_init(mctx, &diff); + diff.resign = zone->sigresigninginterval; CHECK(dns_db_newversion(kfetch->db, &ver)); @@ -13932,6 +13937,7 @@ zone_rekey(dns_zone_t *zone) { mctx = zone->mctx; dns_diff_init(mctx, &diff); dns_diff_init(mctx, &sig_diff); + sig_diff.resign = zone->sigresigninginterval; CHECK(dns_zone_getdb(zone, &db)); CHECK(dns_db_newversion(db, &ver)); @@ -14028,14 +14034,15 @@ zone_rekey(dns_zone_t *zone) { /* * Has a new key become active? If so, is it for - * a new algorithm? + * a new algorithm? In that event, we need to sign the + * zone fully. If there's a new key, but it's for an + * already-existing algorithm, then the zone signing + * can be handled incrementally. */ - for (tuple = ISC_LIST_HEAD(sig_diff.tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - dns_rdata_dnskey_t dnskey; - - if (tuple->rdata.type != dns_rdatatype_dnskey) + for (key = ISC_LIST_HEAD(dnskeys); + key != NULL; + key = ISC_LIST_NEXT(key, link)) { + if (!key->first_sign) continue; newkey = ISC_TRUE; @@ -14044,25 +14051,19 @@ zone_rekey(dns_zone_t *zone) { break; } - result = dns_rdata_tostruct(&tuple->rdata, - &dnskey, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (!signed_with_alg(&keysigs, - dnskey.algorithm)) { + if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { + /* + * This isn't a new algorithm; clear + * first_sign so we won't sign the + * whole zone with this key later + */ + key->first_sign = ISC_FALSE; + } else { newalg = ISC_TRUE; break; } } - /* - * If we found a new algorithm, we need to sign the - * zone fully. If there's a new key, but it's for an - * already-existing algorithm, then the zone signing - * can be handled incrementally. - */ - if (newkey && !newalg) - set_resigntime(zone); - /* Remove any signatures from removed keys. */ if (!ISC_LIST_EMPTY(rmkeys)) { for (key = ISC_LIST_HEAD(rmkeys); @@ -14106,30 +14107,19 @@ zone_rekey(dns_zone_t *zone) { /* * We haven't been told to sign fully, but a new * algorithm was added to the DNSKEY. We sign - * the full zone, but only with the newly-added + * the full zone, but only with newly active * keys. */ - for (tuple = ISC_LIST_HEAD(sig_diff.tuples); - tuple != NULL; - tuple = ISC_LIST_NEXT(tuple, link)) { - dns_rdata_dnskey_t dnskey; - dns_secalg_t algorithm; - isc_region_t r; - isc_uint16_t keyid; - - if (tuple->rdata.type != dns_rdatatype_dnskey || - tuple->op == DNS_DIFFOP_DEL) + for (key = ISC_LIST_HEAD(dnskeys); + key != NULL; + key = ISC_LIST_NEXT(key, link)) { + if (!key->first_sign) continue; - result = dns_rdata_tostruct(&tuple->rdata, - &dnskey, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_toregion(&tuple->rdata, &r); - algorithm = dnskey.algorithm; - keyid = dst_region_computeid(&r, algorithm); - - result = zone_signwithkey(zone, algorithm, - keyid, ISC_FALSE); + result = zone_signwithkey(zone, + dst_key_alg(key->key), + dst_key_id(key->key), + ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", @@ -14174,6 +14164,11 @@ zone_rekey(dns_zone_t *zone) { dns_result_totext(result)); } } + + /* + * Schedule the next resigning event + */ + set_resigntime(zone); UNLOCK_ZONE(zone); }