Commit d3477086 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).

Manually edits: resolve conflicts, replace isc_random_uniform
with isc_random_jitter.

(cherry picked from commit 6b2fd402)
parent 361371a2
......@@ -21,6 +21,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>
......@@ -1380,6 +1381,27 @@ 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);
uint32_t jitter;
isc_random_get(&jitter);
if (sigvalidityinterval < 7200U) {
expiryinterval = 1200;
} else if (expiryinterval > sigvalidityinterval) {
expiryinterval = sigvalidityinterval;
} else {
expiryinterval = sigvalidityinterval - expiryinterval;
}
jitter %= 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,
......@@ -1433,7 +1455,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);
/*
* Do we look at the KSK flag on the DNSKEY to determining which
......
......@@ -6542,8 +6542,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;
......@@ -6591,21 +6591,37 @@ 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) {
isc_random_get(&jitter);
uint32_t normaljitter, fulljitter;
isc_random_get(&normaljitter);
isc_random_get(&fulljitter);
if (sigvalidityinterval > 7200U) {
jitter %= 3600;
normaljitter %= 3600;
fulljitter %= expiryinterval;
} else {
jitter %= 1200;
normaljitter %= 1200;
fulljitter %= 1200;
}
expire = soaexpire - jitter - 1;
expire = soaexpire - normaljitter - 1;
fullexpire = soaexpire - fulljitter - 1;
} else {
expire = soaexpire - 1;
expire = fullexpire = soaexpire - 1;
}
stop = now + 5;
......@@ -6645,9 +6661,16 @@ 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, covers, zonediff.diff,
zone_keys, nkeys, zone->mctx, inception,
expire, check_ksk, keyset_kskonly);
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",
......@@ -7540,7 +7563,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;
......@@ -7612,6 +7635,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
......@@ -7621,7 +7650,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (sigvalidityinterval >= 3600U) {
isc_random_get(&jitter);
if (sigvalidityinterval > 7200U) {
jitter %= 3600;
jitter %= expiryinterval;
} else {
jitter %= 1200;
}
......
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