Commit c592655c authored by Evan Hunt's avatar Evan Hunt
Browse files

new option "dnskey-sig-validity"

- overrides "sig-validity-interval" for DNSKEY, CDNSKEY and CDS RRSIGs
parent d4086d6b
Pipeline #1315 passed with stages
in 7 minutes and 13 seconds
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
......
......@@ -248,6 +248,7 @@ options {\n\
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\
......
......@@ -1440,6 +1440,12 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
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);
......
/*
* 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 */
};
/*
* 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;
};
......@@ -96,3 +96,4 @@ rm -f signer/general/signed.zone
rm -f signer/general/signer.out.*
rm -f signer/general/dsset*
rm -f signing.out*
rm -f python.out.*
......@@ -13,6 +13,7 @@ zone "siginterval.example" {
type master;
allow-update { any; };
sig-validity-interval 35 28;
dnskey-sig-validity 90;
auto-dnssec maintain;
file "siginterval.example.db";
};
......@@ -2997,6 +2997,28 @@ n=`expr $n + 1`
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
......
......@@ -8973,6 +8973,11 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
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
......@@ -8982,6 +8987,24 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</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>
......
......@@ -78,6 +78,13 @@
'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>
......
......@@ -1084,6 +1084,22 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
}
}
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) {
......
......@@ -1444,9 +1444,9 @@ dns_zone_getmgr(dns_zone_t *zone);
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.
......@@ -1455,7 +1455,33 @@ dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval);
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.
......
......@@ -1362,7 +1362,7 @@ struct dns_update_state {
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,
......@@ -1423,6 +1423,12 @@ dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
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
......@@ -1518,13 +1524,22 @@ dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
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++;
......
......@@ -301,6 +301,7 @@ struct dns_zone {
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;
......@@ -1013,6 +1014,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
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;
......@@ -7286,7 +7288,8 @@ need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
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)
{
......@@ -7296,6 +7299,16 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
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);
......@@ -7308,7 +7321,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
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",
......@@ -7961,7 +7974,7 @@ zone_nsec3chain(dns_zone_t *zone) {
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:"
......@@ -7974,7 +7987,7 @@ zone_nsec3chain(dns_zone_t *zone) {
* above so we need to update the signatures.
*/
result = update_sigs(&param_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:"
......@@ -7994,7 +8007,7 @@ zone_nsec3chain(dns_zone_t *zone) {
}
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:"
......@@ -8577,7 +8590,7 @@ zone_sign(dns_zone_t *zone) {
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:"
......@@ -15333,6 +15346,20 @@ dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
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;
......@@ -17477,7 +17504,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
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;
......@@ -17495,6 +17522,13 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
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);
......@@ -17523,7 +17557,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
}
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,
......@@ -17534,8 +17568,8 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
}
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,
......
......@@ -2188,6 +2188,9 @@ zone_clauses[] = {
{ "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
},
......
......@@ -633,6 +633,7 @@
./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
......@@ -674,6 +675,7 @@
./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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment