diff --git a/doc/management.txt b/doc/management.txt index 791d29715..1d34f8436 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -1401,6 +1401,9 @@ disable agent / This command is restricted and can only be issued on sockets configured for level "admin". +disable dynamic-cookie backend + Disable the generation of dynamic cookies fot the backend + disable frontend Mark the frontend as temporarily stopped. This corresponds to the mode which is used during a soft restart : the frontend releases the port but can be @@ -1450,6 +1453,10 @@ enable agent / This command is restricted and can only be issued on sockets configured for level "admin". +enable dynamic-cookie backend + Enable the generation of dynamic cookies fot the backend + A secret key must also be provided + enable frontend Resume a frontend which was temporarily stopped. It is possible that some of the listening ports won't be able to bind anymore (eg: if another process @@ -1540,6 +1547,10 @@ prompt quit Close the connection when in interactive mode. +set dynamic-cookie-key backend + Modify the secret key used to generate the dynamic persistent cookies. + This will break the existing sessions. + set map [|#] Modify the value corresponding to each key in a map . is the # or returned by "show map". If the is used in place of diff --git a/include/proto/proxy.h b/include/proto/proxy.h index a0fa454d4..72f1e1d33 100644 --- a/include/proto/proxy.h +++ b/include/proto/proxy.h @@ -58,6 +58,7 @@ void init_new_proxy(struct proxy *p); int get_backend_server(const char *bk_name, const char *sv_name, struct proxy **bk, struct server **sv); struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg); +struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg); /* * This function returns a string containing the type of the proxy in a format diff --git a/src/proxy.c b/src/proxy.c index 41e40e666..c76d55d52 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -1244,6 +1245,30 @@ struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg) return px; } +/* Expects to find a backend named and returns it, otherwise displays various + * adequate error messages and returns NULL. This function is designed to be used by + * functions requiring a frontend on the CLI. + */ +struct proxy *cli_find_backend(struct appctx *appctx, const char *arg) +{ + struct proxy *px; + + if (!*arg) { + appctx->ctx.cli.msg = "A backend name is expected.\n"; + appctx->st0 = CLI_ST_PRINT; + return NULL; + } + + px = proxy_be_by_name(arg); + if (!px) { + appctx->ctx.cli.msg = "No such backend.\n"; + appctx->st0 = CLI_ST_PRINT; + return NULL; + } + return px; +} + + /* parse a "show servers" CLI line, returns 0 if it wants to start the dump or * 1 if it stops immediately. If an argument is specified, it will set the proxy * pointer into cli.p0 and its ID into cli.i0. @@ -1413,6 +1438,87 @@ static int cli_io_handler_show_backend(struct appctx *appctx) return 1; } +/* Parses the "enable dynamic-cookies backend" directive, it always returns 1 */ +static int cli_parse_enable_dyncookie_backend(char **args, struct appctx *appctx, void *private) +{ + struct proxy *px; + struct server *s; + + if (!cli_has_level(appctx, ACCESS_LVL_ADMIN)) + return 1; + + px = cli_find_backend(appctx, args[3]); + if (!px) + return 1; + + px->ck_opts |= PR_CK_DYNAMIC; + + for (s = px->srv; s != NULL; s = s->next) + srv_set_dyncookie(s); + + return 1; +} + +/* Parses the "disable dynamic-cookies backend" directive, it always returns 1 */ +static int cli_parse_disable_dyncookie_backend(char **args, struct appctx *appctx, void *private) +{ + struct proxy *px; + struct server *s; + + if (!cli_has_level(appctx, ACCESS_LVL_ADMIN)) + return 1; + + px = cli_find_backend(appctx, args[3]); + if (!px) + return 1; + + px->ck_opts &= ~PR_CK_DYNAMIC; + + for (s = px->srv; s != NULL; s = s->next) { + if (!(s->flags & SRV_F_COOKIESET)) { + free(s->cookie); + s->cookie = NULL; + } + } + + return 1; +} + +/* Parses the "set dynamic-cookie-key backend" directive, it always returns 1 */ +static int cli_parse_set_dyncookie_key_backend(char **args, struct appctx *appctx, void *private) +{ + struct proxy *px; + struct server *s; + char *newkey; + + if (!cli_has_level(appctx, ACCESS_LVL_ADMIN)) + return 1; + + px = cli_find_backend(appctx, args[3]); + if (!px) + return 1; + + if (!*args[4]) { + appctx->ctx.cli.msg = "String value expected.\n"; + appctx->st0 = CLI_ST_PRINT; + return 1; + } + + newkey = strdup(args[4]); + if (!newkey) { + appctx->ctx.cli.msg = "Failed to allocate memory.\n"; + appctx->st0 = CLI_ST_PRINT; + return 1; + } + free(px->dyncookie_key); + px->dyncookie_key = newkey; + + for (s = px->srv; s != NULL; s = s->next) + srv_set_dyncookie(s); + + return 1; +} + /* Parses the "set maxconn frontend" directive, it always returns 1 */ static int cli_parse_set_maxconn_frontend(char **args, struct appctx *appctx, void *private) { @@ -1554,6 +1660,9 @@ static struct cli_kw_list cli_kws = {{ },{ { { "show","servers", "state", NULL }, "show servers state [id]: dump volatile server information (for backend )", cli_parse_show_servers, cli_io_handler_servers_state }, { { "show", "backend", NULL }, "show backend : list backends in the current running config", NULL, cli_io_handler_show_backend }, { { "shutdown", "frontend", NULL }, "shutdown frontend : stop a specific frontend", cli_parse_shutdown_frontend, NULL, NULL }, + { { "set", "dynamic-cookie-key", "backend", NULL }, "set dynamic-cookie-key backend : change a backend secret key for dynamic cookies", cli_parse_set_dyncookie_key_backend, NULL }, + { { "enable", "dynamic-cookie", "backend", NULL }, "enable dynamic-cookie backend : enable dynamic cookies on a specific backend", cli_parse_enable_dyncookie_backend, NULL }, + { { "disable", "dynamic-cookie", "backend", NULL }, "disable dynamic-cookie backend : disable dynamic cookies on a specific backend", cli_parse_disable_dyncookie_backend, NULL }, {{},} }};