From 5dcbe0c6d1c52aaadb9f955d52d35337477a2174 Mon Sep 17 00:00:00 2001 From: Anton Demushkin Date: Tue, 24 Mar 2026 18:10:06 +0100 Subject: [PATCH] Support log reopen on SIGHUP and SIGUSR1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `msc_rules_reopen_logs()` only exists in rules_set.h (the newer API) — it's not available in the older rules.h at all. So the ``#ifdef MSC_USE_RULES_SET` guard is necessary here; without it, the build would fail against older libmodsecurity versions that don't have this function. --- src/ngx_http_modsecurity_common.h | 1 + src/ngx_http_modsecurity_module.c | 93 +++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/ngx_http_modsecurity_common.h b/src/ngx_http_modsecurity_common.h index 9f79b5b..b8cee52 100644 --- a/src/ngx_http_modsecurity_common.h +++ b/src/ngx_http_modsecurity_common.h @@ -109,6 +109,7 @@ typedef struct { ngx_uint_t rules_inline; ngx_uint_t rules_file; ngx_uint_t rules_remote; + ngx_open_file_t *log_reopen; } ngx_http_modsecurity_main_conf_t; diff --git a/src/ngx_http_modsecurity_module.c b/src/ngx_http_modsecurity_module.c index d3d9624..7ecc8d7 100644 --- a/src/ngx_http_modsecurity_module.c +++ b/src/ngx_http_modsecurity_module.c @@ -36,6 +36,10 @@ static void *ngx_http_modsecurity_create_conf(ngx_conf_t *cf); static char *ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child); static void ngx_http_modsecurity_cleanup_instance(void *data); static void ngx_http_modsecurity_cleanup_rules(void *data); +#if defined(MSC_USE_RULES_SET) +static int ngx_http_modsecurity_set_up_log_reopen(ngx_conf_t *cf, ngx_http_modsecurity_conf_t *mcf); +static void ngx_http_modsecurity_log_reopen(ngx_open_file_t *file, ngx_log_t *log); +#endif /* @@ -646,6 +650,7 @@ ngx_http_modsecurity_create_main_conf(ngx_conf_t *cf) * conf->rules_inline = 0; * conf->rules_file = 0; * conf->rules_remote = 0; + * conf->log_reopen = NULL; */ cln = ngx_pool_cleanup_add(cf->pool, 0); @@ -670,6 +675,28 @@ ngx_http_modsecurity_create_main_conf(ngx_conf_t *cf) msc_set_connector_info(conf->modsec, MODSECURITY_NGINX_WHOAMI); msc_set_log_cb(conf->modsec, ngx_http_modsecurity_log); +#if defined(MSC_USE_RULES_SET) + /* Set up log reopening on SIGUSR1/SIGHUP */ + { + ngx_str_t log_reopen_file = ngx_string("/dev/null"); + + conf->log_reopen = ngx_conf_open_file(cf->cycle, &log_reopen_file); + if (conf->log_reopen == NULL) { + dd("failed to open file for triggering log reopen"); + return NGX_CONF_ERROR; + } + + conf->log_reopen->data = ngx_list_create(cf->pool, 100, + sizeof(RulesSet *)); + if (conf->log_reopen->data == NULL) { + dd("failed to create list of rules sets for log reopen"); + return NGX_CONF_ERROR; + } + + conf->log_reopen->flush = ngx_http_modsecurity_log_reopen; + } +#endif + dd ("main conf created at: '%p', instance is: '%p'", conf, conf->modsec); return conf; @@ -780,6 +807,17 @@ ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child) return strdup(error); } +#if defined(MSC_USE_RULES_SET) + /* Reopen logs for the merged rules set and register for future reopens */ + if (msc_rules_reopen_logs(c->rules_set, &error) < 0) { + return strdup(error); + } + + if (ngx_http_modsecurity_set_up_log_reopen(cf, c) < 0) { + return strdup("failed to set up log reopen"); + } +#endif + #if defined(MODSECURITY_DDEBUG) && (MODSECURITY_DDEBUG) dd("NEW CHILD RULES"); msc_rules_dump(c->rules_set); @@ -820,4 +858,59 @@ ngx_http_modsecurity_cleanup_rules(void *data) } +#if defined(MSC_USE_RULES_SET) +static int +ngx_http_modsecurity_set_up_log_reopen(ngx_conf_t *cf, + ngx_http_modsecurity_conf_t *mcf) +{ + ngx_http_modsecurity_main_conf_t *mmcf; + ngx_list_t *list; + RulesSet **item; + + mmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_modsecurity_module); + list = mmcf->log_reopen->data; + + /* + * Each rules set may have audit and debug logs. We need to remember each + * rules set so we can ask for its logs to be reopened on SIGUSR1/SIGHUP. + */ + item = ngx_list_push(list); + if (item == NULL) { + dd("failed to set up a rules set for log reopen"); + return -1; + } + + *item = mcf->rules_set; + + return 0; +} + + +static void +ngx_http_modsecurity_log_reopen(ngx_open_file_t *file, ngx_log_t *log) +{ + ngx_list_t *list; + ngx_list_part_t *part; + ngx_uint_t i; + RulesSet **rules_sets; + const char *error = NULL; + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0, + "modsecurity reopening logs"); + + list = file->data; + + for (part = &list->part; part != NULL; part = part->next) { + rules_sets = part->elts; + for (i = 0; i < part->nelts; i++) { + if (msc_rules_reopen_logs(rules_sets[i], &error) < 0) { + ngx_log_error(NGX_LOG_ERR, log, 0, + "failed to reopen modsecurity logs: %s", error); + } + } + } +} +#endif + + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */