From 2bcf38c7c844aa745c4603d37f8c94abc7572460 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 2 May 2024 14:22:24 +0200 Subject: [PATCH] MEDIUM: ssl: add ocsp-update.disable global option This option allow to disable completely the ocsp-update. To achieve this, the ocsp-update.mode global keyword don't rely anymore on SSL_SOCK_OCSP_UPDATE_OFF during parsing to call ssl_create_ocsp_update_task(). Instead, we will inherit the SSL_SOCK_OCSP_UPDATE_* value from ocsp-update.mode for each certificate which does not specify its own mode. To disable completely the ocsp without editing all crt entries, ocsp-update.disable is used instead of "ocsp-update.mode" which is now only used as the default value for crt. --- doc/configuration.txt | 7 +++++ include/haproxy/ssl_sock-t.h | 1 + src/ssl_ocsp.c | 52 +++++++++++++++++++++++++++++------- src/ssl_sock.c | 3 ++- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index b9612bb32..4eb3f79d7 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1290,6 +1290,7 @@ The following keywords are supported in the "global" section : - nbthread - node - numa-cpu-mapping + - ocsp-update.disable - ocsp-update.maxdelay - ocsp-update.mindelay - ocsp-update.httpproxy @@ -2173,6 +2174,12 @@ numa-cpu-mapping already specified, for example via the 'cpu-map' directive or the taskset utility. +ocsp-update.disable [ on | off ] + Disable completely the ocsp-update in HAProxy. Any ocsp-update configuration + will be ignored. Default is "off". + See option "ocsp-update" for more information about the auto update + mechanism. + ocsp-update.httpproxy
[:port] Allow to use an HTTP proxy for the OCSP updates. This only works with HTTP, HTTPS is not supported. This option will allow the OCSP updater to send diff --git a/include/haproxy/ssl_sock-t.h b/include/haproxy/ssl_sock-t.h index 0c44a1ea5..d111883dd 100644 --- a/include/haproxy/ssl_sock-t.h +++ b/include/haproxy/ssl_sock-t.h @@ -309,6 +309,7 @@ struct global_ssl { unsigned int delay_max; unsigned int delay_min; int mode; /* default mode used for ocsp auto-update (off, on) */ + int disable; } ocsp_update; #endif }; diff --git a/src/ssl_ocsp.c b/src/ssl_ocsp.c index 6e8af70cf..92b2f5a74 100644 --- a/src/ssl_ocsp.c +++ b/src/ssl_ocsp.c @@ -1919,8 +1919,6 @@ static int ssl_parse_global_ocsp_update_mode(char **args, int section_type, stru const struct proxy *defpx, const char *file, int line, char **err) { - int ret = 0; - if (!*args[1]) { memprintf(err, "'%s' : expecting ", args[0]); return ERR_ALERT | ERR_FATAL; @@ -1935,15 +1933,29 @@ static int ssl_parse_global_ocsp_update_mode(char **args, int section_type, stru return ERR_ALERT | ERR_FATAL; } - if (global_ssl.ocsp_update.mode != SSL_SOCK_OCSP_UPDATE_OFF) { - /* We might need to create the main ocsp update task */ - ret = ssl_create_ocsp_update_task(err); - } - - return ret; + return 0; } +static int ssl_parse_global_ocsp_update_disable(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (!*args[1]) { + memprintf(err, "'%s' : expecting ", args[0]); + return ERR_ALERT | ERR_FATAL; + } + if (strcmp(args[1], "on") == 0) + global_ssl.ocsp_update.disable = 1; + else if (strcmp(args[1], "off") == 0) + global_ssl.ocsp_update.disable = 0; + else { + memprintf(err, "'%s' : expecting ", args[0]); + return ERR_ALERT | ERR_FATAL; + } + + return 0; +} static int ocsp_update_parse_global_http_proxy(char **args, int section_type, struct proxy *curpx, const struct proxy *defpx, const char *file, int line, @@ -1979,7 +1991,10 @@ int ocsp_update_init(void *value, char *buf, struct ckch_data *d, char **err) int ocsp_update_mode = *(int *)value; int ret = 0; - if (ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON) { + /* inherit from global section */ + ocsp_update_mode = (ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_DFLT) ? global_ssl.ocsp_update.mode : ocsp_update_mode; + + if (!global_ssl.ocsp_update.disable && ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON) { /* We might need to create the main ocsp update task */ ret = ssl_create_ocsp_update_task(err); } @@ -1987,6 +2002,23 @@ int ocsp_update_init(void *value, char *buf, struct ckch_data *d, char **err) return ret; } +int ocsp_update_postparser_init() +{ + int ret = 0; + char *err = NULL; + + /* if the global ocsp-update.mode option is not set to "on", there is + * no need to start the task, it would have been started when parsing a + * crt-store or a crt-list */ + if (!global_ssl.ocsp_update.disable && (global_ssl.ocsp_update.mode == SSL_SOCK_OCSP_UPDATE_ON)) { + /* We might need to create the main ocsp update task */ + ret = ssl_create_ocsp_update_task(&err); + } + + return ret; +} + + static struct cli_kw_list cli_kws = {{ },{ { { "set", "ssl", "ocsp-response", NULL }, "set ssl ocsp-response : update a certificate's OCSP Response from a base64-encode DER", cli_parse_set_ocspresponse, NULL }, @@ -2002,6 +2034,7 @@ INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws); static struct cfg_kw_list cfg_kws = {ILH, { #ifndef OPENSSL_NO_OCSP + { CFG_GLOBAL, "ocsp-update.disable", ssl_parse_global_ocsp_update_disable }, { CFG_GLOBAL, "tune.ssl.ocsp-update.maxdelay", ssl_parse_global_ocsp_maxdelay }, { CFG_GLOBAL, "ocsp-update.maxdelay", ssl_parse_global_ocsp_maxdelay }, { CFG_GLOBAL, "tune.ssl.ocsp-update.mindelay", ssl_parse_global_ocsp_mindelay }, @@ -2014,6 +2047,7 @@ static struct cfg_kw_list cfg_kws = {ILH, { INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws); +REGISTER_CONFIG_POSTPARSER("ocsp-update", ocsp_update_postparser_init); /* * Local variables: * c-indent-level: 8 diff --git a/src/ssl_sock.c b/src/ssl_sock.c index b72cd8108..6a94e8b27 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -140,7 +140,8 @@ struct global_ssl global_ssl = { #ifndef OPENSSL_NO_OCSP .ocsp_update.delay_max = SSL_OCSP_UPDATE_DELAY_MAX, .ocsp_update.delay_min = SSL_OCSP_UPDATE_DELAY_MIN, - .ocsp_update.mode = SSL_SOCK_OCSP_UPDATE_DFLT, + .ocsp_update.mode = SSL_SOCK_OCSP_UPDATE_OFF, + .ocsp_update.disable = 0, #endif };