Skip to content
Snippets Groups Projects
Commit 44d12f83 authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman
Browse files

dnssec: implemented RRSIG pre-refresh to avoid freqent sign events

parent f4f8932f
No related branches found
No related tags found
1 merge request!1038dnssec: implemented RRSIG pre-refresh to avoid freqent sign events
Pipeline #51476 passed
......@@ -851,9 +851,17 @@ time period is not counted to the signature lifetime.
\fIDefault:\fP 14 days
.SS rrsig\-refresh
.sp
A period how long before a signature expiration the signature will be refreshed.
A period how long at least before a signature expiration the signature will be refreshed,
in order to prevent expired RRSIGs on slaves or resolvers\(aq caches.
.sp
\fIDefault:\fP 7 days
.SS rrsig\-pre\-refresh
.sp
A period how long at most before a signature refresh time the signature might be refreshed,
in order to refresh RRSIGs in bigger batches on a frequently updated zone
(avoid re\-sign event too often).
.sp
\fIDefault:\fP 1 hour
.SS nsec3
.sp
Specifies if NSEC3 will be used instead of NSEC.
......
......@@ -935,10 +935,22 @@ A validity period of newly issued signatures.
rrsig-refresh
-------------
A period how long before a signature expiration the signature will be refreshed.
A period how long at least before a signature expiration the signature will be refreshed,
in order to prevent expired RRSIGs on slaves or resolvers' caches.
*Default:* 7 days
.. _policy_rrsig-pre-refresh:
rrsig-pre-refresh
-----------------
A period how long at most before a signature refresh time the signature might be refreshed,
in order to refresh RRSIGs in bigger batches on a frequently updated zone
(avoid re-sign event too often).
*Default:* 1 hour
.. _policy_nsec:
nsec3
......
......@@ -281,6 +281,8 @@ static const yp_item_t desc_policy[] = {
CONF_IO_FRLD_ZONES },
{ C_RRSIG_REFRESH, YP_TINT, YP_VINT = { 1, UINT32_MAX, DAYS(7), YP_STIME },
CONF_IO_FRLD_ZONES },
{ C_RRSIG_PREREFRESH, YP_TINT, YP_VINT = { 0, UINT32_MAX, HOURS(1), YP_STIME },
CONF_IO_FRLD_ZONES },
{ C_NSEC3, YP_TBOOL, YP_VNONE, CONF_IO_FRLD_ZONES },
{ C_NSEC3_ITER, YP_TINT, YP_VINT = { 0, UINT16_MAX, 10 }, CONF_IO_FRLD_ZONES },
{ C_NSEC3_OPT_OUT, YP_TBOOL, YP_VNONE, CONF_IO_FRLD_ZONES },
......
......@@ -90,6 +90,7 @@
#define C_RMT "\x06""remote"
#define C_RRSIG_LIFETIME "\x0E""rrsig-lifetime"
#define C_RRSIG_REFRESH "\x0D""rrsig-refresh"
#define C_RRSIG_PREREFRESH "\x11""rrsig-pre-refresh"
#define C_RUNDIR "\x06""rundir"
#define C_SBM "\x0A""submission"
#define C_SECRET "\x06""secret"
......
......@@ -330,7 +330,8 @@ int check_policy(
C_RRSIG_LIFETIME, args->id, args->id_len);
conf_val_t refresh = conf_rawid_get_txn(args->extra->conf, args->extra->txn, C_POLICY,
C_RRSIG_REFRESH, args->id, args->id_len);
conf_val_t prerefresh = conf_rawid_get_txn(args->extra->conf, args->extra->txn, C_POLICY,
C_RRSIG_PREREFRESH, args->id, args->id_len);
conf_val_t prop_del = conf_rawid_get_txn(args->extra->conf, args->extra->txn, C_POLICY,
C_PROPAG_DELAY, args->id, args->id_len);
conf_val_t zsk_life = conf_rawid_get_txn(args->extra->conf, args->extra->txn, C_POLICY,
......@@ -362,8 +363,9 @@ int check_policy(
int64_t lifetime_val = conf_int(&lifetime);
int64_t refresh_val = conf_int(&refresh);
if (lifetime_val <= refresh_val) {
args->err_str = "RRSIG refresh has to be lower than RRSIG lifetime";
int64_t preref_val = conf_int(&prerefresh);
if (lifetime_val <= refresh_val + preref_val) {
args->err_str = "RRSIG refresh + pre-refresh has to be lower than RRSIG lifetime";
return KNOT_EINVAL;
}
......
......@@ -77,6 +77,9 @@ static void policy_load(knot_kasp_policy_t *policy, conf_val_t *id)
val = conf_id_get(conf(), C_POLICY, C_RRSIG_REFRESH, id);
policy->rrsig_refresh_before = conf_int(&val);
val = conf_id_get(conf(), C_POLICY, C_RRSIG_PREREFRESH, id);
policy->rrsig_prerefresh = conf_int(&val);
val = conf_id_get(conf(), C_POLICY, C_NSEC3, id);
policy->nsec3_enabled = conf_bool(&val);
......
......@@ -101,6 +101,7 @@ typedef struct {
// RRSIG
uint32_t rrsig_lifetime; // like knot_time_t
uint32_t rrsig_refresh_before; // like knot_timediff_t
uint32_t rrsig_prerefresh; // like knot_timediff_t
// NSEC3
bool nsec3_enabled;
bool nsec3_opt_out;
......
......@@ -365,8 +365,10 @@ int knot_check_signature(const knot_rrset_t *covered,
knot_rdata_t *rrsig = knot_rdataset_at(&rrsigs->rrs, pos);
assert(rrsig);
if (is_expired_signature(rrsig, dnssec_ctx->now,
dnssec_ctx->policy->rrsig_refresh_before)) {
// consider signature invalid even if validity ends in refresh - in order to refresh it soon enough
knot_timediff_t refresh = dnssec_ctx->policy->rrsig_refresh_before +
dnssec_ctx->policy->rrsig_prerefresh;
if (is_expired_signature(rrsig, dnssec_ctx->now, refresh)) {
return DNSSEC_INVALID_SIGNATURE;
}
......
#!/usr/bin/env python3
'''Test for batch pre-refresh of RRSIGs.'''
from dnstest.utils import *
from dnstest.test import Test
t = Test()
master = t.server("knot")
zone = t.zone("example.com.")
t.link(zone, master)
master.dnssec(zone).enable = True
master.dnssec(zone).rrsig_lifetime = 20
master.dnssec(zone).rrsig_refresh = 2
master.dnssec(zone).rrsig_prerefresh = 4
t.start()
serial_init = master.zone_wait(zone)
master.ctl("zone-sign")
t.sleep(2)
up = master.update(zone)
up.add("record1.example.com.", 3600, "A", "1.2.3.4")
up.send("NOERROR")
serial_updates = master.zone_wait(zone)
serial_refresh = master.zone_wait(zone, serial_updates)
t.sleep(10)
serial_wait = master.zone_wait(zone)
if serial_wait != serial_refresh:
set_err("RRSIGs refreshed separately (%d != %d)" % (serial_wait, serial_refresh))
t.stop()
......@@ -50,6 +50,7 @@ class ZoneDnssec(object):
self.propagation_delay = None
self.rrsig_lifetime = None
self.rrsig_refresh = None
self.rrsig_prerefresh = None
self.nsec3 = None
self.nsec3_iters = None
self.nsec3_opt_out = None
......@@ -1211,6 +1212,7 @@ class Knot(Server):
self._str(s, "propagation-delay", z.dnssec.propagation_delay)
self._str(s, "rrsig-lifetime", z.dnssec.rrsig_lifetime)
self._str(s, "rrsig-refresh", z.dnssec.rrsig_refresh)
self._str(s, "rrsig-pre-refresh", z.dnssec.rrsig_prerefresh)
self._bool(s, "nsec3", z.dnssec.nsec3)
self._str(s, "nsec3-iterations", z.dnssec.nsec3_iters)
self._bool(s, "nsec3-opt-out", z.dnssec.nsec3_opt_out)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment