diff --git a/doc/man/kzonesign.1in b/doc/man/kzonesign.1in index e2b93e36f6e905f01d72a7604b16f4d37d225deb..397b67a1977a4da096421ba87005c9fa721baad9 100644 --- a/doc/man/kzonesign.1in +++ b/doc/man/kzonesign.1in @@ -58,8 +58,11 @@ Write the output zone file to the specified directory instead of the configured Allow key roll\-overs and NSEC3 re\-salt. In order to finish possible KSK submission, set the KSK\(aqs \fBactive\fP timestamp to now (\fB+0\fP) using keymgr\&. .TP +\fB\-v\fP, \fB\-\-verify\fP +Instead of (re\-)signing the zone, just verify that the zone is correctly signed. +.TP \fB\-t\fP, \fB\-\-time\fP \fItimestamp\fP -Sign the zone (and roll the keys if necessary) as if it was at the time +Sign/verify the zone (and roll the keys if necessary) as if it was at the time specified by timestamp. .TP \fB\-h\fP, \fB\-\-help\fP diff --git a/doc/man_kzonesign.rst b/doc/man_kzonesign.rst index 5c2499da2ea4c37b3ba9e4a962cba00310dfa298..a165f2ca2043a807e65281691d2e18c916764901 100644 --- a/doc/man_kzonesign.rst +++ b/doc/man_kzonesign.rst @@ -35,8 +35,11 @@ Options Allow key roll-overs and NSEC3 re-salt. In order to finish possible KSK submission, set the KSK's **active** timestamp to now (**+0**) using :doc:`keymgr<man_keymgr>`. +**-v**, **--verify** + Instead of (re-)signing the zone, just verify that the zone is correctly signed. + **-t**, **--time** *timestamp* - Sign the zone (and roll the keys if necessary) as if it was at the time + Sign/verify the zone (and roll the keys if necessary) as if it was at the time specified by timestamp. **-h**, **--help** diff --git a/src/knot/dnssec/zone-events.c b/src/knot/dnssec/zone-events.c index 0dcb06516b200d5aba0354098d4bb9b3e8287919..655df2f25f0fd8522cf0cff786f1ab634ba164ac 100644 --- a/src/knot/dnssec/zone-events.c +++ b/src/knot/dnssec/zone-events.c @@ -397,10 +397,13 @@ knot_time_t knot_dnssec_failover_delay(const kdnssec_ctx_t *ctx) } } -int knot_dnssec_validate_zone(zone_update_t *update, conf_t *conf, bool incremental) +int knot_dnssec_validate_zone(zone_update_t *update, conf_t *conf, knot_time_t now, bool incremental) { kdnssec_ctx_t ctx = { 0 }; int ret = kdnssec_validation_ctx(conf, &ctx, update->new_cont); + if (now != 0) { + ctx.now = now; + } if (ret == KNOT_EOK) { ret = knot_zone_check_nsec_chain(update, &ctx, incremental); } diff --git a/src/knot/dnssec/zone-events.h b/src/knot/dnssec/zone-events.h index b1c389d56a2ef43a9f304fefe8d70528374a171a..d3667f351205877debba589eb0976976d3e69075 100644 --- a/src/knot/dnssec/zone-events.h +++ b/src/knot/dnssec/zone-events.h @@ -126,8 +126,9 @@ knot_time_t knot_dnssec_failover_delay(const kdnssec_ctx_t *ctx); * * \param update Zone update with contents. * \param conf Knot configuration. + * \param now If not zero: adjust "now" to this timestamp. * \param incremental Try to validate incrementally. * * \return KNOT_E* */ -int knot_dnssec_validate_zone(zone_update_t *update, conf_t *conf, bool incremental); +int knot_dnssec_validate_zone(zone_update_t *update, conf_t *conf, knot_time_t now, bool incremental); diff --git a/src/knot/updates/zone-update.c b/src/knot/updates/zone-update.c index 44af6079306620dfb8d667bb5262ec62119046ec..944a6f9ceaf232e34895813d6b1d506f1e455757 100644 --- a/src/knot/updates/zone-update.c +++ b/src/knot/updates/zone-update.c @@ -921,7 +921,7 @@ int zone_update_commit(conf_t *conf, zone_update_t *update) bool incr_valid = update->flags & UPDATE_INCREMENTAL; const char *msg_valid = incr_valid ? "incremental " : ""; - ret = knot_dnssec_validate_zone(update, conf, incr_valid); + ret = knot_dnssec_validate_zone(update, conf, 0, incr_valid); if (ret != KNOT_EOK) { log_zone_error(update->zone->name, "DNSSEC, %svalidation failed (%s)", msg_valid, knot_strerror(ret)); diff --git a/src/utils/common/msg.h b/src/utils/common/msg.h index 9ab5a493f1e275c650b965bfa3aa83f5c43f525f..137870a079c26b0bd6966e6e7d5daa79bff83ebd 100644 --- a/src/utils/common/msg.h +++ b/src/utils/common/msg.h @@ -39,3 +39,4 @@ int msg_debug(const char *fmt, ...); #define ERR2(msg, ...) { fprintf(stderr, "Error: " msg, ##__VA_ARGS__); fflush(stderr); } #define WARN2(msg, ...) { fprintf(stderr, "Warning: " msg, ##__VA_ARGS__); fflush(stderr); } +#define INFO2(msg, ...) { fprintf(stdout, msg, ##__VA_ARGS__); fflush(stdout); } diff --git a/src/utils/kzonesign/main.c b/src/utils/kzonesign/main.c index 9c3666a4007ea48786a267478d097383023f34c2..b72e25d183fd79b9b30fba71028fc8cd2bc33fe8 100644 --- a/src/utils/kzonesign/main.c +++ b/src/utils/kzonesign/main.c @@ -20,6 +20,7 @@ #include "knot/dnssec/zone-events.h" #include "knot/updates/zone-update.h" #include "knot/server/server.h" +#include "knot/zone/adjust.h" #include "knot/zone/zone-load.h" #include "knot/zone/zonefile.h" #include "utils/common/msg.h" @@ -40,6 +41,7 @@ static void print_help(void) " (default %s)\n" " -o, --outdir <dir_name> Output directory.\n" " -r, --rollover Allow key rollovers and NSEC3 re-salt.\n" + " -v, --verify Only verify if zone is signed correctly.\n" " -t, --time <timestamp> Current time specification.\n" " (default current UNIX time)\n" " -h, --help Print the program help.\n" @@ -54,6 +56,7 @@ typedef struct { const char *outdir; zone_sign_roll_flags_t rollover; int64_t timestamp; + bool verify; } sign_params_t; static int zonesign(sign_params_t *params) @@ -98,6 +101,30 @@ static int zonesign(sign_params_t *params) goto fail; } + if (params->verify) { + val = conf_zone_get(conf(), C_ADJUST_THR, params->zone_name); + ret = zone_adjust_full(up.new_cont, conf_int(&val)); + if (ret != KNOT_EOK) { + ERR2("failed to adjust the zone (%s)\n", knot_strerror(ret)); + zone_update_clear(&up); + goto fail; + } + + ret = knot_dnssec_validate_zone(&up, conf(), params->timestamp, false); + if (ret != KNOT_EOK) { + ERR2("DNSSEC validation failed (%s)\n", knot_strerror(ret)); + char name_str[KNOT_DNAME_TXT_MAXLEN], type_str[16]; + if (knot_dname_to_str(name_str, up.validation_hint.node, sizeof(name_str)) != NULL && + knot_rrtype_to_string(up.validation_hint.rrtype, type_str, sizeof(type_str)) >= 0) { + ERR2("affected node: '%s' type '%s'\n", name_str, type_str); + } + } else { + INFO2("DNSSEC validation successful\n"); + } + zone_update_clear(&up); + goto fail; + } + kasp_db_ensure_init(&fake_server.kaspdb, conf()); zone_struct->server = &fake_server; @@ -166,6 +193,7 @@ int main(int argc, char *argv[]) { "confdb", required_argument, NULL, 'C' }, { "outdir", required_argument, NULL, 'o' }, { "rollover", no_argument, NULL, 'r' }, + { "verify" , no_argument, NULL, 'v' }, { "time", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, @@ -175,7 +203,7 @@ int main(int argc, char *argv[]) tzset(); int opt = 0; - while ((opt = getopt_long(argc, argv, "c:C:o:rt:hV", opts, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "c:C:o:rvt:hV", opts, NULL)) != -1) { switch (opt) { case 'c': if (util_conf_init_file(optarg) != KNOT_EOK) { @@ -193,6 +221,9 @@ int main(int argc, char *argv[]) case 'r': params.rollover = KEY_ROLL_ALLOW_ALL; break; + case 'v': + params.verify = true; + break; case 't': ; uint32_t num = 0; if (str_to_u32(optarg, &num) != KNOT_EOK || num == 0) {