MINOR: ssl/cli: allow to filter expired certificates with 'show ssl sni'

-A option in 'show ssl sni' shows certificates that are past the
notAfter date.

The patch reworks the options parsing to get multiple.
This commit is contained in:
William Lallemand 2024-12-16 12:42:44 +01:00
parent bb88f68cf7
commit 7c8e38d4d6
2 changed files with 51 additions and 26 deletions

View File

@ -3761,12 +3761,15 @@ show ssl providers
- fips - fips
- base - base
show ssl sni [-f <frontend>] show ssl sni [-f <frontend>] [-A]
Dump every SNI configured for the designated frontend, or all frontends if no Dump every SNI configured for the designated frontend, or all frontends if no
frontend was specified. It allows to see what SNI are offered for a frontend, frontend was specified. It allows to see what SNI are offered for a frontend,
and to identify if a SNI is defined multiple times by multiple certificates for and to identify if a SNI is defined multiple times by multiple certificates for
the same frontend. the same frontend.
The -A option allows to filter the list and only displays the certificates
that are past the notAfter date, allowing to show only expired certificates.
Columns are separated by a single \t, allowing to parse it simply. Columns are separated by a single \t, allowing to parse it simply.
The 'Frontend/Bind' column shows the frontend name followed by the bind line The 'Frontend/Bind' column shows the frontend name followed by the bind line

View File

@ -87,13 +87,16 @@ struct show_cert_ctx {
int transaction; int transaction;
}; };
#define SHOW_SNI_OPT_1FRONTEND (1 << 0) /* show only the selected frontend */
#define SHOW_SNI_OPT_NOTAFTER (1 << 1) /* show certificates that are [A]fter the notAfter date */
/* CLI context used by "show ssl sni" */ /* CLI context used by "show ssl sni" */
struct show_sni_ctx { struct show_sni_ctx {
struct proxy *px; struct proxy *px;
struct bind_conf *bind; struct bind_conf *bind;
struct ebmb_node *n; struct ebmb_node *n;
int nodetype; int nodetype;
int onefrontend; int options;
}; };
/* CLI context used by "dump ssl cert" */ /* CLI context used by "dump ssl cert" */
@ -1570,7 +1573,8 @@ static int cli_io_handler_show_sni(struct appctx *appctx)
/* ctx->bind is NULL only once we finished dumping a frontend or when starting /* ctx->bind is NULL only once we finished dumping a frontend or when starting
* so let's dump the header in these cases*/ * so let's dump the header in these cases*/
if (ctx->bind == NULL && (ctx->onefrontend == 1 || (ctx->onefrontend == 0 && ctx->px == proxies_list))) if (ctx->bind == NULL && (ctx->options & SHOW_SNI_OPT_1FRONTEND ||
(!(ctx->options & SHOW_SNI_OPT_1FRONTEND) && ctx->px == proxies_list)))
chunk_appendf(trash, "# Frontend/Bind\tSNI\tNegative Filter\tType\tFilename\tNotAfter\tNotBefore\n"); chunk_appendf(trash, "# Frontend/Bind\tSNI\tNegative Filter\tType\tFilename\tNotAfter\tNotBefore\n");
if (applet_putchk(appctx, trash) == -1) if (applet_putchk(appctx, trash) == -1)
goto yield; goto yield;
@ -1615,6 +1619,13 @@ static int cli_io_handler_show_sni(struct appctx *appctx)
if (sni->neg) if (sni->neg)
continue; continue;
#ifdef HAVE_ASN1_TIME_TO_TM
if (ctx->options & SHOW_SNI_OPT_NOTAFTER) {
time_t notAfter = x509_get_notafter_time_t(sni->ckch_inst->ckch_store->data->cert);
if (!(date.tv_sec > notAfter))
continue;
}
#endif
chunk_appendf(trash, "%s/%s:%d\t", bind->frontend->id, bind->file, bind->line); chunk_appendf(trash, "%s/%s:%d\t", bind->frontend->id, bind->file, bind->line);
@ -1667,7 +1678,7 @@ static int cli_io_handler_show_sni(struct appctx *appctx)
} }
ctx->bind = NULL; ctx->bind = NULL;
/* only want to display the specified frontend */ /* only want to display the specified frontend */
if (ctx->onefrontend) if (ctx->options & SHOW_SNI_OPT_1FRONTEND)
break; break;
} }
ctx->px = NULL; ctx->px = NULL;
@ -1686,50 +1697,61 @@ static int cli_io_handler_show_sni(struct appctx *appctx)
} }
/* parsing function for 'show ssl sni [-f <frontend>]' */ /* parsing function for 'show ssl sni [-f <frontend>] [-A]' */
static int cli_parse_show_sni(char **args, char *payload, struct appctx *appctx, void *private) static int cli_parse_show_sni(char **args, char *payload, struct appctx *appctx, void *private)
{ {
struct show_sni_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx)); struct show_sni_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
int cur_arg = 3;
ctx->px = proxies_list; ctx->px = proxies_list;
/* look for the right <frontend> to display */ /* look for the right <frontend> to display */
if (*args[3]) {
while (*args[cur_arg]) {
struct proxy *px; struct proxy *px;
if (strcmp(args[3], "-f") != 0) if (strcmp(args[cur_arg], "-f") == 0) {
return cli_err(appctx, "'show ssl sni' only supports a '-f' option!\n");
if (*args[4] == '\0') if (*args[cur_arg+1] == '\0')
return cli_err(appctx, "'-f' requires a frontend name !\n"); return cli_err(appctx, "'-f' requires a frontend name!\n");
for (px = proxies_list; px; px = px->next) { for (px = proxies_list; px; px = px->next) {
/* only check the frontends */ /* only check the frontends */
if (!(px->cap & PR_CAP_FE)) if (!(px->cap & PR_CAP_FE))
continue; continue;
/* skip the internal proxies */ /* skip the internal proxies */
if (px->cap & PR_CAP_INT) if (px->cap & PR_CAP_INT)
continue; continue;
if (strcmp(px->id, args[3]) == 0) { if (strcmp(px->id, args[cur_arg+1]) == 0) {
ctx->px = px; ctx->px = px;
ctx->onefrontend = 1; ctx->options |= SHOW_SNI_OPT_1FRONTEND;
}
} }
cur_arg++; /* skip the argument */
if (ctx->px == NULL)
return cli_err(appctx, "Couldn't find the specified frontend!\n");
} else if (strcmp(args[cur_arg], "-A") == 0) {
/* when current date > notAfter */
ctx->options |= SHOW_SNI_OPT_NOTAFTER;
#ifndef HAVE_ASN1_TIME_TO_TM
return cli_err(appctx, "'-A' option is only supported with OpenSSL >= 1.1.1!\n");
#endif
} else {
return cli_err(appctx, "Invalid parameters, 'show ssl sni' only supports '-f', or '-A' options!\n");
} }
if (ctx->px == NULL) cur_arg++;
goto error;
} }
if (HA_SPIN_TRYLOCK(CKCH_LOCK, &ckch_lock)) if (HA_SPIN_TRYLOCK(CKCH_LOCK, &ckch_lock))
return cli_err(appctx, "Can't list SNIs\nOperations on certificates are currently locked!\n"); return cli_err(appctx, "Can't list SNIs\nOperations on certificates are currently locked!\n");
return 0; return 0;
error:
return cli_err(appctx, "Couldn't find the specified frontend!\n");
} }
/* release function of the `show ssl cert' command */ /* release function of the `show ssl cert' command */