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).
This commit is contained in:
committed by
Matthijs Mekking
parent
7c7f5884e5
commit
6b2fd40269
+21
-1
@@ -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;
|
||||
|
||||
+38
-10
@@ -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);
|
||||
}
|
||||
|
||||
+3
-3
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user