+4928. [func] The "dnskey-sig-validity" option allows
+ "sig-validity-interval" to be overriden for signatures
+ covering DNSKEY RRsets. [GL #145]
+
4927. [placeholder]
4926. [func] Add root key sentinel support. To disable, add
sig-signing-signatures 10;\n\
sig-signing-type 65534;\n\
sig-validity-interval 30; /* days */\n\
+ dnskey-sig-validity 0; /* default: sig-validity-interval */\n\
transfer-source *;\n\
transfer-source-v6 *;\n\
try-tcp-refresh yes; /* BIND 8 compat */\n\
if (ztype == dns_zone_master || raw != NULL) {
isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
+ obj = NULL;
+ result = named_config_get(maps, "dnskey-sig-validity", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ seconds = cfg_obj_asuint32(obj) * 86400;
+ dns_zone_setkeyvalidityinterval(zone, seconds);
+
obj = NULL;
result = named_config_get(maps, "sig-validity-interval", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
--- /dev/null
+/*
+ * 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.
+ */
+
+options {
+ dnskey-sig-validity 5000; /* maximum value 10 years, this is 14 */
+};
--- /dev/null
+/*
+ * 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.
+ */
+
+options {
+ sig-validity-interval 5000;
+};
rm -f signer/general/signer.out.*
rm -f signer/general/dsset*
rm -f signing.out*
+rm -f python.out.*
type master;
allow-update { any; };
sig-validity-interval 35 28;
+ dnskey-sig-validity 90;
auto-dnssec maintain;
file "siginterval.example.db";
};
if test "$before" = "$after" ; then echo_i "failed"; ret=1; fi
status=`expr $status + $ret`
+if [ -x "$PYTHON" ]; then
+ echo_i "check dnskey-sig-validity sets longer expiry for DNSKEY ($n)"
+ ret=0
+ $RNDCCMD 10.53.0.3 sign siginterval.example 2>&1 | sed 's/^/ns3 /' | cat_i
+ # convert expiry date to a comma-separated list of integers python can
+ # use as input to date(). strip leading 0s in months and days so
+ # python3 will recognize them as integers.
+ soaexpire=`$DIG +dnssec +short -p ${PORT} @10.53.0.3 soa siginterval.example | awk '$1 ~ /SOA/ { print $5 }' | sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' | sed 's/ 0/ /'`
+ dnskeyexpire=`$DIG +dnssec +short -p ${PORT} @10.53.0.3 dnskey siginterval.example | awk '$1 ~ /DNSKEY/ { print $5; exit 0 }' | sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' | sed 's/ 0/ /'`
+ $PYTHON > python.out.$n <<EOF
+from datetime import date;
+ke=date($dnskeyexpire)
+se=date($soaexpire)
+print((ke-se).days);
+EOF
+ diff=`cat python.out.$n`
+ [ "$diff" -ge 55 ] || ret=1
+ n=`expr $n + 1`
+ if [ $ret != 0 ]; then echo_i "failed"; fi
+ status=`expr $status + $ret`
+fi
+
copy_setports ns4/named4.conf.in ns4/named.conf
$RNDCCMD 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
sleep 3
set to one hour before the current time to allow
for a limited amount of clock skew.
</para>
+ <para>
+ The <command>sig-validity-interval</command> can be
+ overridden for DNSKEY records by setting
+ <command>dnskey-sig-validity</command>.
+ </para>
<para>
The <command>sig-validity-interval</command>
should be, at least, several multiples of the SOA
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>dnskey-sig-validity</command></term>
+ <listitem>
+ <para>
+ Specifies the number of days into the future when
+ DNSSEC signatures that are automatically generated
+ for DNSKEY RRsets as a result of dynamic updates
+ (<xref linkend="dynamic_update"/>) will expire.
+ If set to a non-zero value, this overrides the
+ value set by <command>sig-validity-interval</command>.
+ The default is zero, meaning
+ <command>sig-validity-interval</command> is used.
+ The maximum value is 3660 days (10 years), and
+ higher values will be rejected.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><command>sig-signing-nodes</command></term>
<listitem>
'root-key-sentinel no;' to named.conf.
</para>
</listitem>
+ <listitem>
+ <para>
+ The <command>dnskey-sig-validity</command> option allows the
+ <command>sig-validity-interval</command> to be overriden for
+ signatures covering DNSKEY RRsets. [GL #145]
+ </para>
+ </listitem>
</itemizedlist>
</section>
}
}
+ obj = NULL;
+ cfg_map_get(options, "dnskey-sig-validity", &obj);
+ if (obj != NULL) {
+ isc_uint32_t keyvalidity;
+
+ keyvalidity = cfg_obj_asuint32(obj);
+ if (keyvalidity > 3660 || keyvalidity == 0) { /* 10 years */
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "%s '%u' is out of range (1..3660)",
+ "dnskey-sig-validity",
+ keyvalidity);
+ result = ISC_R_RANGE;
+ }
+
+ }
+
obj = NULL;
(void)cfg_map_get(options, "preferred-glue", &obj);
if (obj != NULL) {
void
dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval);
/*%<
- * Set the zone's RRSIG validity interval. This is the length of time
- * for which DNSSEC signatures created as a result of dynamic updates
- * to secure zones will remain valid, in seconds.
+ * Set the zone's general signature validity interval. This is the length
+ * of time for which DNSSEC signatures created as a result of dynamic
+ * updates to secure zones will remain valid, in seconds.
*
* Requires:
* \li 'zone' to be a valid zone.
isc_uint32_t
dns_zone_getsigvalidityinterval(dns_zone_t *zone);
/*%<
- * Get the zone's RRSIG validity interval.
+ * Get the zone's general signature validity interval.
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone.
+ */
+
+void
+dns_zone_setkeyvalidityinterval(dns_zone_t *zone, isc_uint32_t interval);
+/*%<
+ * Set the zone's DNSKEY signature validity interval. This is the length
+ * of time for which DNSSEC signatures created for DNSKEY records
+ * will remain valid, in seconds.
+ *
+ * If this value is set to zero, then the regular signature validity
+ * interval (see dns_zone_setsigvalidityinterval(), above) is used
+ * for all RRSIGs. However, if this value is nonzero, then it is used
+ * as the validity interval for RRSIGs covering DNSKEY and CDNSKEY
+ * RRsets.
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone.
+ */
+
+isc_uint32_t
+dns_zone_getkeyvalidityinterval(dns_zone_t *zone);
+/*%<
+ * Get the zone's DNSKEY signature validity interval.
*
* Requires:
* \li 'zone' to be a valid zone.
dns_diff_t work;
dst_key_t *zone_keys[DNS_MAXZONEKEYS];
unsigned int nkeys;
- isc_stdtime_t inception, expire;
+ isc_stdtime_t inception, expire, keyexpire;
dns_ttl_t nsecttl;
isc_boolean_t check_ksk, keyset_kskonly, build_nsec3;
enum { sign_updates, remove_orphaned, build_chain, process_nsec,
isc_stdtime_get(&now);
state->inception = now - 3600; /* Allow for some clock skew. */
state->expire = now + sigvalidityinterval;
+ state->keyexpire = dns_zone_getkeyvalidityinterval(zone);
+ if (state->keyexpire == 0) {
+ state->keyexpire = state->expire;
+ } else {
+ state->keyexpire += now;
+ }
/*
* Do we look at the KSK flag on the DNSKEY to determining which
CHECK(rrset_visible(db, newver, name, type,
&flag));
if (flag) {
+ isc_stdtime_t exp;
+ if (type == dns_rdatatype_dnskey ||
+ type == dns_rdatatype_cdnskey ||
+ type == dns_rdatatype_cds)
+ {
+ exp = state->keyexpire;
+ } else {
+ exp = state->expire;
+ }
+
CHECK(add_sigs(log, zone, db, newver,
name, type,
&state->sig_diff,
state->zone_keys,
state->nkeys,
- state->inception,
- state->expire,
+ state->inception, exp,
state->check_ksk,
state->keyset_kskonly));
sigs++;
isc_event_t ctlevent;
dns_ssutable_t *ssutable;
isc_uint32_t sigvalidityinterval;
+ isc_uint32_t keyvalidityinterval;
isc_uint32_t sigresigninginterval;
dns_view_t *view;
dns_view_t *prev_view;
zone->maxxfrout = MAX_XFER_TIME;
zone->ssutable = NULL;
zone->sigvalidityinterval = 30 * 24 * 3600;
+ zone->keyvalidityinterval = 0;
zone->sigresigninginterval = 7 * 24 * 3600;
zone->view = NULL;
zone->prev_view = NULL;
static isc_result_t
update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
- isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
+ isc_stdtime_t inception, isc_stdtime_t expire,
+ isc_stdtime_t keyexpire, isc_stdtime_t now,
isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
zonediff_t *zonediff)
{
for (tuple = ISC_LIST_HEAD(diff->tuples);
tuple != NULL;
tuple = ISC_LIST_HEAD(diff->tuples)) {
+ isc_stdtime_t exp = expire;
+
+ if (keyexpire != 0 &&
+ (tuple->rdata.type == dns_rdatatype_dnskey ||
+ tuple->rdata.type == dns_rdatatype_cdnskey ||
+ tuple->rdata.type == dns_rdatatype_cds))
+ {
+ exp = keyexpire;
+ }
+
result = del_sigs(zone, db, version, &tuple->name,
tuple->rdata.type, zonediff,
zone_keys, nkeys, now, ISC_FALSE);
result = add_sigs(db, version, &tuple->name,
tuple->rdata.type, zonediff->diff,
zone_keys, nkeys, zone->mctx, inception,
- expire, check_ksk, keyset_kskonly);
+ exp, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"update_sigs:add_sigs -> %s",
if (nsec3chain != NULL)
dns_dbiterator_pause(nsec3chain->dbiterator);
result = update_sigs(&nsec3_diff, db, version, zone_keys,
- nkeys, zone, inception, expire, now,
+ nkeys, zone, inception, expire, 0, now,
check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
* above so we need to update the signatures.
*/
result = update_sigs(¶m_diff, db, version, zone_keys,
- nkeys, zone, inception, expire, now,
+ nkeys, zone, inception, expire, 0, now,
check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
}
result = update_sigs(&nsec_diff, db, version, zone_keys,
- nkeys, zone, inception, expire, now,
+ nkeys, zone, inception, expire, 0, now,
check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
result = update_sigs(&post_diff, db, version, zone_keys,
- nkeys, zone, inception, expire, now,
+ nkeys, zone, inception, expire, 0, now,
check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
return (zone->sigvalidityinterval);
}
+void
+dns_zone_setkeyvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ zone->keyvalidityinterval = interval;
+}
+
+isc_uint32_t
+dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ return (zone->keyvalidityinterval);
+}
+
void
dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
isc_time_t now;
isc_stdtime_t now, dns_diff_t *diff, zonediff_t *zonediff)
{
isc_result_t result;
- isc_stdtime_t inception, soaexpire;
+ isc_stdtime_t inception, soaexpire, keyexpire;
isc_boolean_t check_ksk, keyset_kskonly;
dst_key_t *zone_keys[DNS_MAXZONEKEYS];
unsigned int nkeys = 0, i;
inception = now - 3600; /* Allow for clock skew. */
soaexpire = now + dns_zone_getsigvalidityinterval(zone);
+ keyexpire = dns_zone_getkeyvalidityinterval(zone);
+ if (keyexpire == 0) {
+ keyexpire = soaexpire;
+ } else {
+ keyexpire += now;
+ }
+
check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
}
result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
zonediff->diff, zone_keys, nkeys, zone->mctx,
- inception, soaexpire, check_ksk,
+ inception, keyexpire, check_ksk,
keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
}
result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
- inception, soaexpire, now, check_ksk,
- keyset_kskonly, zonediff);
+ inception, soaexpire, keyexpire, now,
+ check_ksk, keyset_kskonly, zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
{ "sig-validity-interval", &cfg_type_validityinterval,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
},
+ { "dnskey-sig-validity", &cfg_type_uint32,
+ CFG_ZONE_MASTER | CFG_ZONE_SLAVE
+ },
{ "transfer-source", &cfg_type_sockaddr4wild,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
},
./bin/tests/system/checkconf/bad-acl.conf CONF-C 2016,2018
./bin/tests/system/checkconf/bad-also-notify.conf CONF-C 2012,2013,2016,2018
./bin/tests/system/checkconf/bad-catz-zone.conf CONF-C 2016,2018
+./bin/tests/system/checkconf/bad-dnskey-validity.conf CONF-C 2018
./bin/tests/system/checkconf/bad-dnssec.conf CONF-C 2012,2013,2016,2018
./bin/tests/system/checkconf/bad-glue-cache-bogus.conf CONF-C 2017,2018
./bin/tests/system/checkconf/bad-hint.conf CONF-C 2014,2016,2018
./bin/tests/system/checkconf/bad-sharedwritable2.conf CONF-C 2014,2016,2018
./bin/tests/system/checkconf/bad-sharedzone1.conf CONF-C 2013,2016,2018
./bin/tests/system/checkconf/bad-sharedzone2.conf CONF-C 2013,2016,2018
+./bin/tests/system/checkconf/bad-sig-validity.conf CONF-C 2018
./bin/tests/system/checkconf/bad-tsig.conf CONF-C 2012,2013,2016,2018
./bin/tests/system/checkconf/bad-update-policy1.conf CONF-C 2018
./bin/tests/system/checkconf/bad-update-policy2.conf CONF-C 2018