Commit 2f67ba42 authored by Mark Karpilovskij's avatar Mark Karpilovskij Committed by Daniel Salzman

mod-cookies: manually configurable Server Secret

parent f83685b8
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2019 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
......@@ -36,13 +36,26 @@
#define MOD_SECRET_LIFETIME "\x0F""secret-lifetime"
#define MOD_BADCOOKIE_SLIP "\x0E""badcookie-slip"
#define MOD_SECRET "\x06""secret"
const yp_item_t cookies_conf[] = {
{ MOD_SECRET_LIFETIME, YP_TINT, YP_VINT = { 1, 36*24*3600, 26*3600, YP_STIME } },
{ MOD_BADCOOKIE_SLIP, YP_TINT, YP_VINT = { 1, INT32_MAX, 1 } },
{ MOD_SECRET, YP_THEX, YP_VNONE },
{ NULL }
};
int cookies_conf_check(knotd_conf_check_args_t *args)
{
knotd_conf_t conf = knotd_conf_check_item(args, MOD_SECRET);
if (conf.count == 1 && conf.single.data_len != KNOT_EDNS_COOKIE_SECRET_SIZE) {
args->err_str = "the length of the cookie secret "
"MUST BE 16 bytes (32 HEX characters)";
return KNOT_EINVAL;
}
return KNOT_EOK;
}
typedef struct {
struct {
uint64_t variable;
......@@ -221,10 +234,7 @@ int cookies_load(knotd_mod_t *mod)
ctx->badcookie_ctr = BADCOOKIE_CTR_INIT;
// Set up configurable items.
knotd_conf_t conf = knotd_conf_mod(mod, MOD_SECRET_LIFETIME);
ctx->secret_lifetime = conf.single.integer;
conf = knotd_conf_mod(mod, MOD_BADCOOKIE_SLIP);
knotd_conf_t conf = knotd_conf_mod(mod, MOD_BADCOOKIE_SLIP);
ctx->badcookie_slip = conf.single.integer;
// Set up statistics counters.
......@@ -235,17 +245,27 @@ int cookies_load(knotd_mod_t *mod)
}
// Initialize the server secret.
ret = dnssec_random_buffer((uint8_t *)&ctx->secret, sizeof(ctx->secret));
if (ret != KNOT_EOK) {
free(ctx);
return ret;
}
conf = knotd_conf_mod(mod, MOD_SECRET);
if (conf.count == 1) {
assert(conf.single.data_len == KNOT_EDNS_COOKIE_SECRET_SIZE);
memcpy(&ctx->secret, conf.single.data, conf.single.data_len);
assert(ctx->secret_lifetime == 0);
} else {
ret = dnssec_random_buffer((uint8_t *)&ctx->secret, sizeof(ctx->secret));
if (ret != KNOT_EOK) {
free(ctx);
return ret;
}
knotd_mod_ctx_set(mod, ctx);
conf = knotd_conf_mod(mod, MOD_SECRET_LIFETIME);
ctx->secret_lifetime = conf.single.integer;
// Start the secret rollover thread.
if (pthread_create(&ctx->update_secret, NULL, update_secret, (void *)mod)) {
knotd_mod_log(mod, LOG_ERR, "failed to create the secret rollover thread");
// Start the secret rollover thread.
if (pthread_create(&ctx->update_secret, NULL, update_secret, (void *)mod)) {
knotd_mod_log(mod, LOG_ERR, "failed to create the secret rollover thread");
free(ctx);
return KNOT_ERROR;
}
}
#ifndef HAVE_ATOMIC
......@@ -253,17 +273,21 @@ int cookies_load(knotd_mod_t *mod)
ctx->badcookie_slip = 1;
#endif
knotd_mod_ctx_set(mod, ctx);
return knotd_mod_hook(mod, KNOTD_STAGE_BEGIN, cookies_process);
}
void cookies_unload(knotd_mod_t *mod)
{
cookies_ctx_t *ctx = knotd_mod_ctx(mod);
if (ctx->secret_lifetime > 0) {
(void)pthread_cancel(ctx->update_secret);
(void)pthread_join(ctx->update_secret, NULL);
}
memzero(&ctx->secret, sizeof(ctx->secret));
(void)pthread_cancel(ctx->update_secret);
(void)pthread_join(ctx->update_secret, NULL);
free(ctx);
}
KNOTD_MOD_API(cookies, KNOTD_MOD_FLAG_SCOPE_ANY | KNOTD_MOD_FLAG_OPT_CONF,
cookies_load, cookies_unload, cookies_conf, NULL);
cookies_load, cookies_unload, cookies_conf, cookies_conf_check);
......@@ -34,6 +34,15 @@ It is recommended to enable DNS Cookies globally, not per zone.
- id: default
global-module: mod-cookies/default # Enable DNS Cookies globally
The value of the Server Secret may also be managed manually using the :ref:`mod-cookies_secret` option. In this case
the server does not automatically regenerate the Server Secret.
::
mod-cookies:
- id: default
secret: 0xdeadbeefdeadbeefdeadbeefdeadbeef
Module reference
----------------
......@@ -43,6 +52,7 @@ Module reference
- id: STR
secret-lifetime: TIME
badcookie-slip: INT
secret: STR|HEXSTR
.. _mod-cookies_id:
......@@ -56,7 +66,7 @@ A module identifier.
secret-lifetime
...............
This option configures how often the server secret is regenerated.
This option configures how often the Server Secret is regenerated.
The maximum allowed value is 36 days (:rfc:`7873#section-7.1`).
*Default:* 26 hours
......@@ -76,3 +86,14 @@ an invalid cookie by sending them the correct cookie.
query with an invalid cookie, the rest of the queries is dropped.
*Default:* 1
.. _mod-cookies_secret:
secret
......
Use this option to set the Server Secret manually. If this option is used, the
Server Secret remains the same until changed manually and the :ref:`mod-cookies_secret-lifetime` option is ignored.
The size of the Server Secret currently MUST BE 16 bytes, or 32 hexadecimal characters.
*Default:* not set
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