Commit c82fb9c4 authored by Daniel Salzman's avatar Daniel Salzman

Merge branch 'knotc_key_rollover' into 'master'

dnssec: implement commands in knotc to trigger immediate key rollovers

Closes #590

See merge request !928
parents 5e0d4939 94a2abcc
......@@ -125,6 +125,11 @@ directory.
Trigger a DNSSEC re\-sign of the zone. Existing signatures will be dropped.
This command is valid for zones with automatic DNSSEC signing.
.TP
\fBzone\-key\-rollover\fP \fIzone\fP \fIkey_type\fP
On the specified zone with automatic DNSSEC signing and key management,
even when the key has a lifetime to go, publish new key and immediately
start the key rollover. Key type can be \fBksk\fP (also for CSK) or \fBzsk\fP\&.
.TP
\fBzone\-read\fP \fIzone\fP [\fIowner\fP [\fItype\fP]]
Get zone data that are currently being presented.
.TP
......
......@@ -102,6 +102,11 @@ Actions
Trigger a DNSSEC re-sign of the zone. Existing signatures will be dropped.
This command is valid for zones with automatic DNSSEC signing.
**zone-key-rollover** *zone* *key_type*
On the specified zone with automatic DNSSEC signing and key management,
even when the key has a lifetime to go, publish new key and immediately
start the key rollover. Key type can be **ksk** (also for CSK) or **zsk**.
**zone-read** *zone* [*owner* [*type*]]
Get zone data that are currently being presented.
......
......@@ -352,6 +352,27 @@ static int zone_sign(zone_t *zone, ctl_args_t *args)
return KNOT_EOK;
}
static int zone_key_roll(zone_t *zone, ctl_args_t *args)
{
conf_val_t val = conf_zone_get(conf(), C_DNSSEC_SIGNING, zone->name);
if (!conf_bool(&val)) {
return KNOT_ENOTSUP;
}
const char *key_type = args->data[KNOT_CTL_IDX_TYPE];
if (strncasecmp(key_type, "ksk", 3) == 0) {
zone->flags |= ZONE_FORCE_KSK_ROLL;
} else if (strncasecmp(key_type, "zsk", 3) == 0) {
zone->flags |= ZONE_FORCE_ZSK_ROLL;
} else {
return KNOT_EINVAL;
}
zone_events_schedule_user(zone, ZONE_EVENT_DNSSEC);
return KNOT_EOK;
}
static int zone_ksk_sbm_confirm(zone_t *zone, ctl_args_t *args)
{
UNUSED(args);
......@@ -1334,6 +1355,8 @@ static int ctl_zone(ctl_args_t *args, ctl_cmd_t cmd)
return zones_apply(args, zone_flush);
case CTL_ZONE_SIGN:
return zones_apply(args, zone_sign);
case CTL_ZONE_KEY_ROLL:
return zones_apply(args, zone_key_roll);
case CTL_ZONE_KSK_SBM:
return zones_apply(args, zone_ksk_sbm_confirm);
case CTL_ZONE_FREEZE:
......@@ -1762,16 +1785,17 @@ static const desc_t cmd_table[] = {
[CTL_RELOAD] = { "reload", ctl_server },
[CTL_STATS] = { "stats", ctl_stats },
[CTL_ZONE_STATUS] = { "zone-status", ctl_zone },
[CTL_ZONE_RELOAD] = { "zone-reload", ctl_zone },
[CTL_ZONE_REFRESH] = { "zone-refresh", ctl_zone },
[CTL_ZONE_RETRANSFER] = { "zone-retransfer", ctl_zone },
[CTL_ZONE_NOTIFY] = { "zone-notify", ctl_zone },
[CTL_ZONE_FLUSH] = { "zone-flush", ctl_zone },
[CTL_ZONE_SIGN] = { "zone-sign", ctl_zone },
[CTL_ZONE_STATUS] = { "zone-status", ctl_zone },
[CTL_ZONE_RELOAD] = { "zone-reload", ctl_zone },
[CTL_ZONE_REFRESH] = { "zone-refresh", ctl_zone },
[CTL_ZONE_RETRANSFER] = { "zone-retransfer", ctl_zone },
[CTL_ZONE_NOTIFY] = { "zone-notify", ctl_zone },
[CTL_ZONE_FLUSH] = { "zone-flush", ctl_zone },
[CTL_ZONE_SIGN] = { "zone-sign", ctl_zone },
[CTL_ZONE_KEY_ROLL] = { "zone-key-rollover", ctl_zone },
[CTL_ZONE_KSK_SBM] = { "zone-ksk-submitted", ctl_zone },
[CTL_ZONE_FREEZE] = { "zone-freeze", ctl_zone },
[CTL_ZONE_THAW] = { "zone-thaw", ctl_zone },
[CTL_ZONE_FREEZE] = { "zone-freeze", ctl_zone },
[CTL_ZONE_THAW] = { "zone-thaw", ctl_zone },
[CTL_ZONE_READ] = { "zone-read", ctl_zone },
[CTL_ZONE_BEGIN] = { "zone-begin", ctl_zone },
......
......@@ -54,6 +54,7 @@ typedef enum {
CTL_ZONE_NOTIFY,
CTL_ZONE_FLUSH,
CTL_ZONE_SIGN,
CTL_ZONE_KEY_ROLL,
CTL_ZONE_KSK_SBM,
CTL_ZONE_FREEZE,
CTL_ZONE_THAW,
......
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -192,6 +192,15 @@ static int share_or_generate_key(kdnssec_ctx_t *ctx, kdnssec_generate_flags_t fl
#define GEN_KSK_FLAGS (DNSKEY_GENERATE_KSK | (ctx->policy->singe_type_signing ? DNSKEY_GENERATE_ZSK : 0))
static int generate_ksk(kdnssec_ctx_t *ctx, knot_time_t when_active, bool pre_active)
{
if (ctx->policy->ksk_shared) {
return share_or_generate_key(ctx, GEN_KSK_FLAGS, when_active, pre_active);
} else {
return generate_key(ctx, GEN_KSK_FLAGS, when_active, pre_active);
}
}
static bool running_rollover(const kdnssec_ctx_t *ctx)
{
bool res = false;
......@@ -343,7 +352,7 @@ static knot_time_t alg_remove_time(knot_time_t post_active_time, const kdnssec_c
return MAX(ksk_remove_time(post_active_time, ctx), zsk_remove_time(post_active_time, ctx));
}
static roll_action_t next_action(kdnssec_ctx_t *ctx)
static roll_action_t next_action(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags)
{
roll_action_t res = { 0 };
res.time = 0;
......@@ -352,7 +361,9 @@ static roll_action_t next_action(kdnssec_ctx_t *ctx)
knot_kasp_key_t *key = &ctx->zone->keys[i];
knot_time_t keytime = 0;
roll_action_type_t restype = INVALID;
if (key->is_pub_only) {
if (key->is_pub_only ||
(key->is_ksk && !(flags & KEY_ROLL_ALLOW_KSK_ROLL)) ||
(key->is_zsk && !(flags & KEY_ROLL_ALLOW_ZSK_ROLL))) {
continue;
}
if (key->is_ksk) {
......@@ -537,7 +548,8 @@ static int exec_remove_old_key(kdnssec_ctx_t *ctx, knot_kasp_key_t *key)
return kdnssec_delete_key(ctx, key);
}
int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *reschedule)
int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags,
zone_sign_reschedule_t *reschedule)
{
if (ctx == NULL || reschedule == NULL) {
return KNOT_EINVAL;
......@@ -546,6 +558,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
return KNOT_EOK;
}
int ret = KNOT_EOK;
bool allowed_general_roll = ((flags & KEY_ROLL_ALLOW_KSK_ROLL) && (flags & KEY_ROLL_ALLOW_ZSK_ROLL));
// generate initial keys if missing
if (!key_present(ctx, true, false) && !key_present(ctx, true, true)) {
if (ctx->policy->ksk_shared) {
......@@ -562,14 +575,36 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
}
}
}
// algorithm rollover
if (algorithm_present(ctx, ctx->policy->algorithm) == 0 &&
!running_rollover(ctx) && ret == KNOT_EOK) {
if (ctx->policy->ksk_shared) {
ret = share_or_generate_key(ctx, GEN_KSK_FLAGS, 0, true);
// forced KSK rollover
if ((flags & KEY_ROLL_FORCE_KSK_ROLL) && ret == KNOT_EOK) {
flags &= ~KEY_ROLL_FORCE_KSK_ROLL;
if (running_rollover(ctx)) {
log_zone_warning(ctx->zone->dname, "DNSSEC, ignoring forced KSK rollover "
"due to running rollover");
} else {
ret = generate_key(ctx, GEN_KSK_FLAGS, 0, true);
ret = generate_ksk(ctx, 0, false);
if (ret == KNOT_EOK) {
log_zone_info(ctx->zone->dname, "DNSSEC, KSK rollover started");
}
}
}
// forced ZSK rollover
if ((flags & KEY_ROLL_FORCE_ZSK_ROLL) && ret == KNOT_EOK) {
flags &= ~KEY_ROLL_FORCE_ZSK_ROLL;
if (running_rollover(ctx)) {
log_zone_warning(ctx->zone->dname, "DNSSEC, ignoring forced ZSK rollover "
"due to running rollover");
} else {
ret = generate_key(ctx, DNSKEY_GENERATE_ZSK, 0, false);
if (ret == KNOT_EOK) {
log_zone_info(ctx->zone->dname, "DNSSEC, ZSK rollover started");
}
}
}
// algorithm rollover
if (algorithm_present(ctx, ctx->policy->algorithm) == 0 &&
!running_rollover(ctx) && allowed_general_roll && ret == KNOT_EOK) {
ret = generate_ksk(ctx, 0, true);
if (!ctx->policy->singe_type_signing && ret == KNOT_EOK) {
ret = generate_key(ctx, DNSKEY_GENERATE_ZSK, 0, true);
}
......@@ -579,13 +614,9 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
}
}
// scheme rollover
if (!signing_scheme_present(ctx) &&
if (!signing_scheme_present(ctx) && allowed_general_roll &&
!running_rollover(ctx) && ret == KNOT_EOK) {
if (ctx->policy->ksk_shared) {
ret = share_or_generate_key(ctx, GEN_KSK_FLAGS, 0, false);
} else {
ret = generate_key(ctx, GEN_KSK_FLAGS, 0, false);
}
ret = generate_ksk(ctx, 0, false);
if (!ctx->policy->singe_type_signing && ret == KNOT_EOK) {
ret = generate_key(ctx, DNSKEY_GENERATE_ZSK, 0, false);
}
......@@ -598,17 +629,17 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
return ret;
}
roll_action_t next = next_action(ctx);
roll_action_t next = next_action(ctx, flags);
reschedule->next_rollover = next.time;
if (knot_time_cmp(reschedule->next_rollover, ctx->now) <= 0) {
switch (next.type) {
case GENERATE:
if (next.ksk && ctx->policy->ksk_shared) {
ret = share_or_generate_key(ctx, GEN_KSK_FLAGS, 0, false);
if (next.ksk) {
ret = generate_ksk(ctx, 0, false);
} else {
ret = generate_key(ctx, next.ksk ? GEN_KSK_FLAGS : DNSKEY_GENERATE_ZSK, 0, false);
ret = generate_key(ctx, DNSKEY_GENERATE_ZSK, 0, false);
}
if (ret == KNOT_EOK) {
log_zone_info(ctx->zone->dname, "DNSSEC, %cSK rollover started",
......@@ -637,7 +668,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
if (ret == KNOT_EOK) {
reschedule->keys_changed = true;
next = next_action(ctx);
next = next_action(ctx, flags);
reschedule->next_rollover = next.time;
} else {
log_zone_warning(ctx->zone->dname, "DNSSEC, key rollover, action %s (%s)",
......@@ -648,7 +679,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
}
if (ret == KNOT_EOK && knot_time_cmp(reschedule->next_rollover, ctx->now) <= 0) {
return knot_dnssec_key_rollover(ctx, reschedule);
return knot_dnssec_key_rollover(ctx, flags, reschedule);
}
if (reschedule->keys_changed) {
......
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -30,12 +30,14 @@
* but also during zone load so that the zone gets loaded already with
* proper DNSSEC chain.
*
* \param ctx zone signing context
* \param reschedule Out: timestamp of desired next invoke
* \param ctx Zone signing context
* \param flags Determine if some actions are forced
* \param reschedule Out: timestamp of desired next invoke
*
* \return KNOT_E*
*/
int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *reschedule);
int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags,
zone_sign_reschedule_t *reschedule);
/*!
* \brief Set the submitted KSK to active state and the active one to retired
......
......@@ -28,7 +28,7 @@
#include "knot/dnssec/zone-nsec.h"
#include "knot/dnssec/zone-sign.h"
static int sign_init(const zone_contents_t *zone, zone_sign_flags_t flags,
static int sign_init(const zone_contents_t *zone, zone_sign_flags_t flags, zone_sign_roll_flags_t roll_flags,
kdnssec_ctx_t *ctx, zone_sign_reschedule_t *reschedule)
{
assert(zone);
......@@ -43,15 +43,12 @@ static int sign_init(const zone_contents_t *zone, zone_sign_flags_t flags,
// perform nsec3resalt if pending
if (reschedule->allow_nsec3resalt) {
r = knot_dnssec_nsec3resalt(ctx, &reschedule->allow_nsec3resalt, &reschedule->next_nsec3resalt);
if (roll_flags & KEY_ROLL_DO_NSEC3RESALT) {
r = knot_dnssec_nsec3resalt(ctx, &reschedule->last_nsec3resalt, &reschedule->next_nsec3resalt);
}
// perform key rollover if needed
if (reschedule->allow_rollover) {
r = knot_dnssec_key_rollover(ctx, reschedule);
}
r = knot_dnssec_key_rollover(ctx, roll_flags, reschedule);
if (r != KNOT_EOK) {
return r;
}
......@@ -105,7 +102,7 @@ static int generate_salt(dnssec_binary_t *salt, uint16_t length)
// TODO preserve the resalt timeout in timers-db instead of kasp_db
int knot_dnssec_nsec3resalt(kdnssec_ctx_t *ctx, bool *salt_changed, knot_time_t *when_resalt)
int knot_dnssec_nsec3resalt(kdnssec_ctx_t *ctx, knot_time_t *salt_changed, knot_time_t *when_resalt)
{
int ret = KNOT_EOK;
......@@ -130,7 +127,7 @@ int knot_dnssec_nsec3resalt(kdnssec_ctx_t *ctx, bool *salt_changed, knot_time_t
if (ret == KNOT_EOK) {
ctx->zone->nsec3_salt_created = ctx->now;
ret = kdnssec_ctx_commit(ctx);
*salt_changed = true;
*salt_changed = ctx->now;
}
// continue to planning next resalt even if NOK
*when_resalt = knot_time_add(ctx->now, ctx->policy->nsec3_salt_lifetime);
......@@ -141,6 +138,7 @@ int knot_dnssec_nsec3resalt(kdnssec_ctx_t *ctx, bool *salt_changed, knot_time_t
int knot_dnssec_zone_sign(zone_update_t *update,
zone_sign_flags_t flags,
zone_sign_roll_flags_t roll_flags,
zone_sign_reschedule_t *reschedule)
{
if (!update || !reschedule) {
......@@ -154,7 +152,7 @@ int knot_dnssec_zone_sign(zone_update_t *update,
// signing pipeline
result = sign_init(update->new_cont, flags, &ctx, reschedule);
result = sign_init(update->new_cont, flags, roll_flags, &ctx, reschedule);
if (result != KNOT_EOK) {
log_zone_error(zone_name, "DNSSEC, failed to initialize (%s)",
knot_strerror(result));
......@@ -239,7 +237,7 @@ int knot_dnssec_sign_update(zone_update_t *update, zone_sign_reschedule_t *resch
// signing pipeline
result = sign_init(update->new_cont, 0, &ctx, reschedule);
result = sign_init(update->new_cont, 0, 0, &ctx, reschedule);
if (result != KNOT_EOK) {
log_zone_error(zone_name, "DNSSEC, failed to initialize (%s)",
knot_strerror(result));
......
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -31,14 +31,21 @@ enum zone_sign_flags {
typedef enum zone_sign_flags zone_sign_flags_t;
typedef enum {
KEY_ROLL_ALLOW_KSK_ROLL = (1 << 0),
KEY_ROLL_FORCE_KSK_ROLL = (1 << 1),
KEY_ROLL_ALLOW_ZSK_ROLL = (1 << 2),
KEY_ROLL_FORCE_ZSK_ROLL = (1 << 3),
KEY_ROLL_DO_NSEC3RESALT = (1 << 4),
} zone_sign_roll_flags_t;
typedef struct {
knot_time_t next_sign;
knot_time_t next_rollover;
knot_time_t next_nsec3resalt;
bool keys_changed;
bool plan_ds_query;
bool allow_rollover; // this one is set by the caller
bool allow_nsec3resalt; // this one is set by the caller and modified by the salter
knot_time_t next_sign;
knot_time_t next_rollover;
knot_time_t next_nsec3resalt;
knot_time_t last_nsec3resalt;
bool keys_changed;
bool plan_ds_query;
} zone_sign_reschedule_t;
/*!
......@@ -58,12 +65,14 @@ int knot_dnssec_sign_process_events(const kdnssec_ctx_t *kctx,
*
* \param update Zone Update structure with current zone contents to be updated by signing.
* \param flags Zone signing flags.
* \param roll_flags Key rollover flags.
* \param reschedule Signature refresh time of the oldest signature in zone.
*
* \return Error code, KNOT_EOK if successful.
*/
int knot_dnssec_zone_sign(zone_update_t *update,
zone_sign_flags_t flags,
zone_sign_roll_flags_t roll_flags,
zone_sign_reschedule_t *reschedule);
/*!
......@@ -87,9 +96,9 @@ int knot_dnssec_sign_update(zone_update_t *update, zone_sign_reschedule_t *resch
* proper DNSSEC chain.
*
* \param ctx zone signing context
* \param salt_changed output if KNOT_EOK: was the salt changed ? (if so, please re-sign)
* \param salt_changed output if KNOT_EOK: when was the salt last changed? (either ctx->now or 0)
* \param when_resalt output: tmestamp when next resalt takes place
*
* \return KNOT_E*
*/
int knot_dnssec_nsec3resalt(kdnssec_ctx_t *ctx, bool *salt_changed, knot_time_t *when_resalt);
int knot_dnssec_nsec3resalt(kdnssec_ctx_t *ctx, knot_time_t *salt_changed, knot_time_t *when_resalt);
......@@ -45,8 +45,8 @@ void event_dnssec_reschedule(conf_t *conf, zone_t *zone,
zone->timers.next_parent_ds_q = now;
}
if (refresh->allow_nsec3resalt) {
zone->timers.last_resalt = time(NULL);
if (refresh->last_nsec3resalt) {
zone->timers.last_resalt = refresh->last_nsec3resalt;
}
zone_events_schedule_at(zone,
......@@ -62,7 +62,7 @@ int event_dnssec(conf_t *conf, zone_t *zone)
assert(zone);
zone_sign_reschedule_t resch = { 0 };
resch.allow_rollover = true;
zone_sign_roll_flags_t r_flags = KEY_ROLL_ALLOW_KSK_ROLL | KEY_ROLL_ALLOW_ZSK_ROLL;
int sign_flags = 0;
if (zone->flags & ZONE_FORCE_RESIGN) {
......@@ -76,7 +76,16 @@ int event_dnssec(conf_t *conf, zone_t *zone)
}
if (zone_events_get_time(zone, ZONE_EVENT_NSEC3RESALT) <= time(NULL)) {
resch.allow_nsec3resalt = true;
r_flags |= KEY_ROLL_DO_NSEC3RESALT;
}
if (zone->flags & ZONE_FORCE_KSK_ROLL) {
zone->flags &= ~ZONE_FORCE_KSK_ROLL;
r_flags |= KEY_ROLL_FORCE_KSK_ROLL;
}
if (zone->flags & ZONE_FORCE_ZSK_ROLL) {
zone->flags &= ~ZONE_FORCE_ZSK_ROLL;
r_flags |= KEY_ROLL_FORCE_ZSK_ROLL;
}
zone_update_t up;
......@@ -85,7 +94,7 @@ int event_dnssec(conf_t *conf, zone_t *zone)
return ret;
}
ret = knot_dnssec_zone_sign(&up, sign_flags, &resch);
ret = knot_dnssec_zone_sign(&up, sign_flags, r_flags, &resch);
if (ret != KNOT_EOK) {
goto done;
}
......
......@@ -219,9 +219,10 @@ int event_load(conf_t *conf, zone_t *zone)
journal_conts = NULL;
// Sign zone using DNSSEC if configured.
zone_sign_reschedule_t dnssec_refresh = { .allow_rollover = true, .allow_nsec3resalt = true, };
zone_sign_reschedule_t dnssec_refresh = { 0 };
if (dnssec_enable) {
ret = knot_dnssec_zone_sign(&up, 0, &dnssec_refresh);
ret = knot_dnssec_zone_sign(&up, 0, KEY_ROLL_ALLOW_KSK_ROLL | KEY_ROLL_ALLOW_ZSK_ROLL | KEY_ROLL_DO_NSEC3RESALT,
&dnssec_refresh);
if (ret != KNOT_EOK) {
zone_update_clear(&up);
goto cleanup;
......
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,7 +19,7 @@
int event_nsec3resalt(conf_t *conf, zone_t *zone)
{
bool salt_changed = false;
knot_time_t salt_changed = 0;
knot_time_t next_resalt = 0;
kdnssec_ctx_t kctx = { 0 };
......@@ -30,8 +30,7 @@ int event_nsec3resalt(conf_t *conf, zone_t *zone)
}
ret = knot_dnssec_nsec3resalt(&kctx, &salt_changed, &next_resalt);
if (ret == KNOT_EOK && salt_changed) {
if (ret == KNOT_EOK && salt_changed != 0) {
zone_events_schedule_now(zone, ZONE_EVENT_DNSSEC);
zone->timers.last_resalt = kctx.now;
}
......
......@@ -247,8 +247,8 @@ static int axfr_finalize(struct refresh_data *data)
conf_val_t val = conf_zone_get(data->conf, C_DNSSEC_SIGNING, data->zone->name);
bool dnssec_enable = conf_bool(&val);
if (dnssec_enable) {
zone_sign_reschedule_t resch = { .allow_rollover = true };
ret = knot_dnssec_zone_sign(&up, ZONE_SIGN_KEEP_SERIAL, &resch);
zone_sign_reschedule_t resch = { 0 };
ret = knot_dnssec_zone_sign(&up, ZONE_SIGN_KEEP_SERIAL, KEY_ROLL_ALLOW_KSK_ROLL | KEY_ROLL_ALLOW_ZSK_ROLL, &resch);
if (ret != KNOT_EOK) {
zone_update_clear(&up);
return ret;
......@@ -461,7 +461,7 @@ static int ixfr_finalize(struct refresh_data *data)
conf_val_t val = conf_zone_get(data->conf, C_DNSSEC_SIGNING, data->zone->name);
bool dnssec_enable = conf_bool(&val);
if (dnssec_enable) {
zone_sign_reschedule_t resch = { .allow_rollover = true };
zone_sign_reschedule_t resch = { 0 };
ret = knot_dnssec_sign_update(&up, &resch);
if (ret != KNOT_EOK) {
zone_update_clear(&up);
......
......@@ -476,7 +476,7 @@ static knotd_in_state_t pre_routine(knotd_in_state_t state, knot_pkt_t *pkt,
knotd_qdata_t *qdata, knotd_mod_t *mod)
{
online_sign_ctx_t *ctx = knotd_mod_ctx(mod);
zone_sign_reschedule_t resch = { .allow_rollover = true };
zone_sign_reschedule_t resch = { 0 };
(void)pkt, (void)qdata;
......@@ -496,7 +496,7 @@ static knotd_in_state_t pre_routine(knotd_in_state_t state, knot_pkt_t *pkt,
}
}
if (ret == KNOT_EOK || knot_time_cmp(ctx->event_rollover, mod->dnssec->now) <= 0) {
ret = knot_dnssec_key_rollover(mod->dnssec, &resch);
ret = knot_dnssec_key_rollover(mod->dnssec, KEY_ROLL_ALLOW_KSK_ROLL | KEY_ROLL_ALLOW_ZSK_ROLL, &resch);
}
if (ret == KNOT_EOK) {
if (resch.plan_ds_query && mod->dnssec->policy->ksk_sbm_check_interval > 0) {
......@@ -614,10 +614,8 @@ static int online_sign_ctx_new(online_sign_ctx_t **ctx_ptr, knotd_mod_t *mod)
// Force Singe-Type signing scheme. This is only important for compatibility with older versions.
mod->dnssec->policy->singe_type_signing = true;
zone_sign_reschedule_t resch = {
.allow_rollover = true
};
ret = knot_dnssec_key_rollover(mod->dnssec, &resch);
zone_sign_reschedule_t resch = { 0 };
ret = knot_dnssec_key_rollover(mod->dnssec, KEY_ROLL_ALLOW_KSK_ROLL | KEY_ROLL_ALLOW_ZSK_ROLL, &resch);
if (ret != KNOT_EOK) {
free(ctx);
return ret;
......
......@@ -31,9 +31,11 @@ struct zone_update;
* \brief Zone flags.
*/
typedef enum zone_flag_t {
ZONE_FORCE_AXFR = 1 << 0, /* Force AXFR as next transfer. */
ZONE_FORCE_RESIGN = 1 << 1, /* Force zone re-sign. */
ZONE_FORCE_FLUSH = 1 << 2, /* Force zone flush. */
ZONE_FORCE_AXFR = 1 << 0, /* Force AXFR as next transfer. */
ZONE_FORCE_RESIGN = 1 << 1, /* Force zone re-sign. */
ZONE_FORCE_FLUSH = 1 << 2, /* Force zone flush. */
ZONE_FORCE_KSK_ROLL = 1 << 3, /* Force KSK/CSK rollover. */
ZONE_FORCE_ZSK_ROLL = 1 << 4, /* Force ZSK rollover. */
} zone_flag_t;
/*!
......
......@@ -44,9 +44,10 @@
#define CMD_ZONE_RELOAD "zone-reload"
#define CMD_ZONE_REFRESH "zone-refresh"
#define CMD_ZONE_RETRANSFER "zone-retransfer"
#define CMD_ZONE_NOTIFY "zone-notify"
#define CMD_ZONE_NOTIFY "zone-notify"
#define CMD_ZONE_FLUSH "zone-flush"
#define CMD_ZONE_SIGN "zone-sign"
#define CMD_ZONE_KEY_ROLL "zone-key-rollover"
#define CMD_ZONE_KSK_SBM "zone-ksk-submitted"
#define CMD_ZONE_FREEZE "zone-freeze"
#define CMD_ZONE_THAW "zone-thaw"
......@@ -242,6 +243,7 @@ static void format_data(ctl_cmd_t cmd, knot_ctl_type_t data_type,
case CTL_ZONE_NOTIFY:
case CTL_ZONE_FLUSH:
case CTL_ZONE_SIGN:
case CTL_ZONE_KEY_ROLL:
case CTL_ZONE_KSK_SBM:
case CTL_ZONE_BEGIN:
case CTL_ZONE_COMMIT:
......@@ -363,6 +365,7 @@ static void format_block(ctl_cmd_t cmd, bool failed, bool empty)
case CTL_ZONE_NOTIFY:
case CTL_ZONE_FLUSH:
case CTL_ZONE_SIGN:
case CTL_ZONE_KEY_ROLL:
case CTL_ZONE_KSK_SBM:
case CTL_ZONE_FREEZE:
case CTL_ZONE_THAW:
......@@ -644,6 +647,26 @@ static int cmd_zone_memstats(cmd_args_t *args)
return ret;
}
static int cmd_zone_key_roll_ctl(cmd_args_t *args)
{
int ret = check_args(args, 2, 2);
if (ret != KNOT_EOK) {
return ret;
}
knot_ctl_data_t data = {
[KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd),
[KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL,
[KNOT_CTL_IDX_ZONE] = args->argv[0],
[KNOT_CTL_IDX_TYPE] = args->argv[1],
};
CTL_SEND_DATA
CTL_SEND_BLOCK
return ctl_receive(args);
}
static int cmd_zone_ctl(cmd_args_t *args)
{
knot_ctl_data_t data = {
......@@ -1063,18 +1086,19 @@ const cmd_desc_t cmd_table[] = {
{ CMD_RELOAD, cmd_ctl, CTL_RELOAD },
{ CMD_STATS, cmd_stats_ctl, CTL_STATS },
{ CMD_ZONE_CHECK, cmd_zone_check, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD },
{ CMD_ZONE_MEMSTATS, cmd_zone_memstats, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD },
{ CMD_ZONE_STATUS, cmd_zone_filter_ctl, CTL_ZONE_STATUS, CMD_FOPT_ZONE },
{ CMD_ZONE_RELOAD, cmd_zone_ctl, CTL_ZONE_RELOAD, CMD_FOPT_ZONE },
{ CMD_ZONE_REFRESH, cmd_zone_ctl, CTL_ZONE_REFRESH, CMD_FOPT_ZONE },
{ CMD_ZONE_RETRANSFER, cmd_zone_ctl, CTL_ZONE_RETRANSFER, CMD_FOPT_ZONE },
{ CMD_ZONE_NOTIFY, cmd_zone_ctl, CTL_ZONE_NOTIFY, CMD_FOPT_ZONE },
{ CMD_ZONE_FLUSH, cmd_zone_filter_ctl, CTL_ZONE_FLUSH, CMD_FOPT_ZONE },
{ CMD_ZONE_SIGN, cmd_zone_ctl, CTL_ZONE_SIGN, CMD_FOPT_ZONE },
{ CMD_ZONE_KSK_SBM, cmd_zone_ctl, CTL_ZONE_KSK_SBM, CMD_FREQ_ZONE },
{ CMD_ZONE_FREEZE, cmd_zone_ctl, CTL_ZONE_FREEZE, CMD_FOPT_ZONE },
{ CMD_ZONE_THAW, cmd_zone_ctl, CTL_ZONE_THAW, CMD_FOPT_ZONE },
{ CMD_ZONE_CHECK, cmd_zone_check, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD },
{ CMD_ZONE_MEMSTATS, cmd_zone_memstats, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD },
{ CMD_ZONE_STATUS, cmd_zone_filter_ctl, CTL_ZONE_STATUS, CMD_FOPT_ZONE },
{ CMD_ZONE_RELOAD, cmd_zone_ctl, CTL_ZONE_RELOAD, CMD_FOPT_ZONE },
{ CMD_ZONE_REFRESH, cmd_zone_ctl, CTL_ZONE_REFRESH, CMD_FOPT_ZONE },
{ CMD_ZONE_RETRANSFER, cmd_zone_ctl, CTL_ZONE_RETRANSFER, CMD_FOPT_ZONE },
{ CMD_ZONE_NOTIFY, cmd_zone_ctl, CTL_ZONE_NOTIFY, CMD_FOPT_ZONE },
{ CMD_ZONE_FLUSH, cmd_zone_filter_ctl, CTL_ZONE_FLUSH, CMD_FOPT_ZONE },
{ CMD_ZONE_SIGN, cmd_zone_ctl, CTL_ZONE_SIGN, CMD_FOPT_ZONE },
{ CMD_ZONE_KEY_ROLL, cmd_zone_key_roll_ctl, CTL_ZONE_KEY_ROLL, CMD_FREQ_ZONE },
{ CMD_ZONE_KSK_SBM, cmd_zone_ctl, CTL_ZONE_KSK_SBM, CMD_FREQ_ZONE },
{ CMD_ZONE_FREEZE, cmd_zone_ctl, CTL_ZONE_FREEZE, CMD_FOPT_ZONE },
{ CMD_ZONE_THAW, cmd_zone_ctl, CTL_ZONE_THAW, CMD_FOPT_ZONE },
{ CMD_ZONE_READ, cmd_zone_node_ctl, CTL_ZONE_READ, CMD_FREQ_ZONE },
{ CMD_ZONE_BEGIN, cmd_zone_ctl, CTL_ZONE_BEGIN, CMD_FREQ_ZONE | CMD_FOPT_ZONE },
......@@ -1119,6 +1143,7 @@ static const cmd_help_t cmd_help_table[] = {
{ CMD_ZONE_RETRANSFER, "[<zone>...]", "Force slave zone retransfer (no serial check)." },
{ CMD_ZONE_FLUSH, "[<zone>...] [<filter>...]", "Flush zone journal into the zone file." },
{ CMD_ZONE_SIGN, "[<zone>...]", "Re-sign the automatically signed zone." },
{ CMD_ZONE_KEY_ROLL, "<zone> <keytype>", "Trigger an immediate key rollover on a zone with automatic key management." },
{ CMD_ZONE_KSK_SBM, "<zone>", "\b\b\bWhen KSK submission, confirm parent's DS presence manually." },
{ CMD_ZONE_FREEZE, "[<zone>...]", "Temporarily postpone automatic zone-changing events." },
{ CMD_ZONE_THAW, "[<zone>...]", "Dismiss zone freeze." },
......
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