Commit 6b2fd402 authored by Witold Krecicki's avatar Witold Krecicki Committed by Matthijs Mekking

Jitter signatures times when adding dynamic records.

When doing regular signing expiry time is jittered to make sure
that the re-signing times are not clumped together. This expands
this behaviour to expiry times of dynamically added records.

When incrementally re-signing a zone use the full jitter range if
the server appears to have been offline for greater than 5 minutes
otherwise use a small jitter range of 3600 seconds.  This will stop
the signatures becoming more clustered if the server has been off
line for a significant period of time (> 5 minutes).
parent 7c7f5884
......@@ -19,6 +19,7 @@
#include <isc/netaddr.h>
#include <isc/platform.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/serial.h>
#include <isc/stats.h>
#include <isc/stdtime.h>
......@@ -1389,6 +1390,25 @@ struct dns_update_state {
sign_nsec, update_nsec3, process_nsec3, sign_nsec3 } state;
};
static uint32_t
dns__jitter_expire(dns_zone_t *zone, uint32_t sigvalidityinterval) {
/* Spread out signatures over time */
if (sigvalidityinterval >= 3600U) {
uint32_t expiryinterval = dns_zone_getsigresigninginterval(zone);
if (sigvalidityinterval < 7200U) {
expiryinterval = 1200;
} else if (expiryinterval > sigvalidityinterval) {
expiryinterval = sigvalidityinterval;
} else {
expiryinterval = sigvalidityinterval - expiryinterval;
}
uint32_t jitter = isc_random_uniform(expiryinterval);
sigvalidityinterval -= jitter;
}
return (sigvalidityinterval);
}
isc_result_t
dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *oldver, dns_dbversion_t *newver,
......@@ -1440,7 +1460,7 @@ 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->expire = now + dns__jitter_expire(zone, sigvalidityinterval);
state->keyexpire = dns_zone_getkeyvalidityinterval(zone);
if (state->keyexpire == 0) {
state->keyexpire = state->expire;
......
......@@ -6613,8 +6613,8 @@ zone_resigninc(dns_zone_t *zone) {
dst_key_t *zone_keys[DNS_MAXZONEKEYS];
bool check_ksk, keyset_kskonly = false;
isc_result_t result;
isc_stdtime_t now, inception, soaexpire, expire, stop;
uint32_t jitter, sigvalidityinterval;
isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop;
uint32_t sigvalidityinterval, expiryinterval;
unsigned int i;
unsigned int nkeys = 0;
unsigned int resign;
......@@ -6662,20 +6662,34 @@ zone_resigninc(dns_zone_t *zone) {
sigvalidityinterval = zone->sigvalidityinterval;
inception = now - 3600; /* Allow for clock skew. */
soaexpire = now + sigvalidityinterval;
expiryinterval = dns_zone_getsigresigninginterval(zone);
if (expiryinterval > sigvalidityinterval) {
expiryinterval = sigvalidityinterval;
} else {
expiryinterval = sigvalidityinterval - expiryinterval;
}
/*
* Spread out signatures over time if they happen to be
* clumped. We don't do this for each add_sigs() call as
* we still want some clustering to occur.
* we still want some clustering to occur. In normal operations
* the records should be re-signed as they fall due and they should
* already be spread out. However if the server is off for a
* period we need to ensure that the clusters don't become
* synchronised by using the full jitter range.
*/
if (sigvalidityinterval >= 3600U) {
uint32_t normaljitter, fulljitter;
if (sigvalidityinterval > 7200U) {
jitter = isc_random_uniform(3600);
normaljitter = isc_random_uniform(3600);
fulljitter = isc_random_uniform(expiryinterval);
} else {
jitter = isc_random_uniform(1200);
normaljitter = fulljitter = isc_random_uniform(1200);
}
expire = soaexpire - jitter - 1;
expire = soaexpire - normaljitter - 1;
fullexpire = soaexpire - fulljitter - 1;
} else {
expire = soaexpire - 1;
expire = fullexpire = soaexpire - 1;
}
stop = now + 5;
......@@ -6715,9 +6729,17 @@ zone_resigninc(dns_zone_t *zone) {
break;
}
/*
* If re-signing is over 5 minutes late use 'fullexpire'
* to redistribute the signature over the complete
* re-signing window, otherwise only add a small amount
* of jitter.
*/
result = add_sigs(db, version, name, zone, covers,
zonediff.diff, zone_keys, nkeys, zone->mctx,
inception, expire, check_ksk, keyset_kskonly);
inception,
resign > (now - 300) ? expire : fullexpire,
check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_resigninc:add_sigs -> %s",
......@@ -7677,7 +7699,7 @@ zone_nsec3chain(dns_zone_t *zone) {
bool first;
isc_result_t result;
isc_stdtime_t now, inception, soaexpire, expire;
uint32_t jitter, sigvalidityinterval;
uint32_t jitter, sigvalidityinterval, expiryinterval;
unsigned int i;
unsigned int nkeys = 0;
uint32_t nodes;
......@@ -7749,6 +7771,12 @@ zone_nsec3chain(dns_zone_t *zone) {
sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
inception = now - 3600; /* Allow for clock skew. */
soaexpire = now + sigvalidityinterval;
expiryinterval = dns_zone_getsigresigninginterval(zone);
if (expiryinterval > sigvalidityinterval) {
expiryinterval = sigvalidityinterval;
} else {
expiryinterval = sigvalidityinterval - expiryinterval;
}
/*
* Spread out signatures over time if they happen to be
......@@ -7757,7 +7785,7 @@ zone_nsec3chain(dns_zone_t *zone) {
*/
if (sigvalidityinterval >= 3600U) {
if (sigvalidityinterval > 7200U) {
jitter = isc_random_uniform(3600);
jitter = isc_random_uniform(expiryinterval);
} else {
jitter = isc_random_uniform(1200);
}
......
......@@ -3181,14 +3181,14 @@ update_action(isc_task_t *task, isc_event_t *event) {
CHECK(dns_nsec3param_deletechains(db, ver, zone,
true, &diff));
} else if (has_dnskey && isdnssec(db, ver, privatetype)) {
uint32_t interval;
dns_update_log_t log;
uint32_t interval = dns_zone_getsigvalidityinterval(zone);
interval = dns_zone_getsigvalidityinterval(zone);
log.func = update_log_cb;
log.arg = client;
result = dns_update_signatures(&log, zone, db, oldver,
ver, &diff, interval);
ver, &diff,
interval);
if (result != ISC_R_SUCCESS) {
update_log(client, zone,
......
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