Nginx holding subrequests when using thread pool
Jabasukuriputo Wang
lllkjok at gmail.com
Sat Aug 13 03:07:33 UTC 2022
Hi,
I’m trying to modify the ModSecurity NGINX connector to use the thread
pool feature offered by NGINX. However when running the test suites
involving auth_request, as long as I did a ngx_thread_task_post in
either the rewrite phase or preaccess phase, the auth subrequest
always seems to somehow block until the main request canceled. What
happened in between?
Cheers,
W.
NGINX version: 1.21.4
Code of rewrite handler:
ngx_int_t ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
{
ngx_http_modsecurity_rewrite_thread_ctx_t *ctx;
ngx_http_modsecurity_ctx_t *m_ctx;
ngx_thread_task_t *task;
m_ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "recovering
ctx: %p", m_ctx);
task = ngx_thread_task_alloc(r->pool,
sizeof(ngx_http_modsecurity_rewrite_thread_ctx_t));
ctx = task->ctx;
ctx->r = r;
ctx->ctx = m_ctx;
ctx->return_code = NGX_DECLINED;
task->handler = ngx_http_modsecurity_rewrite_worker;
task->event.handler = ngx_http_modsecurity_rewrite_finalizer;
task->event.data = ctx;
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "[ModSecurity]
Using Thread Pool: %p", mcf->thread_pool);
if (ngx_thread_task_post(mcf->thread_pool, task) != NGX_OK)
{
return NGX_ERROR;
}
return NGX_DONE;
}
The completion handler:
void ngx_http_modsecurity_rewrite_finalizer(ngx_event_t *ev)
{
ngx_http_modsecurity_rewrite_thread_ctx_t *ctx = ev->data;
ngx_http_core_main_conf_t *cmcf;
ngx_log_error(NGX_LOG_DEBUG, ctx->r->connection->log, 0,
"[ModSecurity] Rewrite Job Finalized");
cmcf = ngx_http_get_module_main_conf(ctx->r, ngx_http_core_module);
switch (ctx->return_code)
{
case NGX_OK:
ctx->r->phase_handler = cmcf->phase_engine.handlers->next;
ngx_http_core_run_phases(ctx->r);
break;
case NGX_DECLINED:
ctx->r->phase_handler++;
ngx_http_core_run_phases(ctx->r);
break;
case NGX_AGAIN:
case NGX_DONE:
// ngx_http_core_run_phases(ctx->r);
break;
default:
ngx_http_finalize_request(ctx->r, ctx->return_code);
}
}
Note that even if I don’t do anything in
ngx_http_modsecurity_rewrite_worker, it still seems to block.
Relevant Config:
location = /auth {
return 200;
}
location = /useauth {
modsecurity on;
modsecurity_rules '
SecRuleEngine On
SecRequestBodyAccess On
';
auth_request /auth;
proxy_pass http://127.0.0.1:8081;
}
Debug log (notice the gap, that’s when I Ctrl-C the curl):
2022/08/12 19:29:17 [debug] 17157#17160: Nothing to add on the body
inspection, reclaiming a NGX_DECLINED
2022/08/12 19:29:17 [debug] 17157#17160: complete task #2 in thread
pool "default"
2022/08/12 19:29:17 [debug] 17157#17157: epoll: fd:11 ev:0001 d:00005558A9EA4560
2022/08/12 19:29:17 [debug] 17157#17157: thread pool handler
2022/08/12 19:29:17 [debug] 17157#17157: run completion handler for task #2
2022/08/12 19:29:17 [debug] 17157#17157: *2 generic phase: 6
2022/08/12 19:29:17 [debug] 17157#17157: *2 generic phase: 7
2022/08/12 19:29:17 [debug] 17157#17157: *2 access phase: 8
2022/08/12 19:29:17 [debug] 17157#17157: *2 access phase: 9
2022/08/12 19:29:17 [debug] 17157#17157: *2 access phase: 10
2022/08/12 19:29:17 [debug] 17157#17157: *2 auth request handler
2022/08/12 19:29:17 [debug] 17157#17157: *2 http subrequest "/auth?"
2022/08/12 19:29:17 [debug] 17157#17157: timer delta: 0
2022/08/12 19:29:17 [debug] 17157#17157: worker cycle
2022/08/12 19:29:17 [debug] 17157#17157: epoll timer: -1
2022/08/12 19:29:23 [debug] 17157#17157: epoll: fd:3 ev:2001 d:00005558AB3ED909
2022/08/12 19:29:23 [debug] 17157#17157: *2 http run request: "/auth?"
2022/08/12 19:29:23 [debug] 17157#17157: *2 http request empty handler
2022/08/12 19:29:23 [debug] 17157#17157: *2 http posted request: "/auth?"
2022/08/12 19:29:23 [debug] 17157#17157: *2 rewrite phase: 0
2022/08/12 19:29:23 [debug] 17157#17157: *2 test location: "/bodylimitreject"
2022/08/12 19:29:23 [debug] 17157#17157: *2 test location: "/bodyaccess"
2022/08/12 19:29:23 [debug] 17157#17157: *2 test location: "/auth"
2022/08/12 19:29:23 [debug] 17157#17157: *2 using configuration "=/auth"
2022/08/12 19:29:23 [debug] 17157#17157: *2 http cl:-1 max:1048576
2022/08/12 19:29:23 [debug] 17157#17157: *2 rewrite phase: 2
2022/08/12 19:29:23 [debug] 17157#17157: *2 catching a new _rewrite_
phase handler
This is the log when I don’t bother with the thread pool:
2022/08/12 19:29:45 [debug] 18087#18087: *1 catching a new _rewrite_
phase handler
2022/08/12 19:29:45 [error] 18087#18087: *1 ModSecurity not enabled...
returning, client: 127.0.0.1, server: localhost, request: "GET
/useauth HTTP/1.1", host: "127.0.0.1:8080"
2022/08/12 19:29:45 [debug] 18087#18087: *1 rewrite phase: 3
2022/08/12 19:29:45 [debug] 18087#18087: *1 post rewrite phase: 4
2022/08/12 19:29:45 [debug] 18087#18087: *1 generic phase: 5
2022/08/12 19:29:45 [debug] 18087#18087: *1 catching a new _preaccess_
phase handler
2022/08/12 19:29:45 [error] 18087#18087: *1 ModSecurity not enabled...
returning, client: 127.0.0.1, server: localhost, request: "GET
/useauth HTTP/1.1", host: "127.0.0.1:8080"
2022/08/12 19:29:45 [debug] 18087#18087: *1 generic phase: 6
2022/08/12 19:29:45 [debug] 18087#18087: *1 generic phase: 7
2022/08/12 19:29:45 [debug] 18087#18087: *1 access phase: 8
2022/08/12 19:29:45 [debug] 18087#18087: *1 access phase: 9
2022/08/12 19:29:45 [debug] 18087#18087: *1 access phase: 10
2022/08/12 19:29:45 [debug] 18087#18087: *1 auth request handler
2022/08/12 19:29:45 [debug] 18087#18087: *1 http subrequest "/auth?"
2022/08/12 19:29:45 [debug] 18087#18087: *1 http posted request: "/auth?"
2022/08/12 19:29:45 [debug] 18087#18087: *1 rewrite phase: 0
2022/08/12 19:29:45 [debug] 18087#18087: *1 test location: "/bodylimitreject"
2022/08/12 19:29:45 [debug] 18087#18087: *1 test location: "/bodyaccess"
2022/08/12 19:29:45 [debug] 18087#18087: *1 test location: "/auth"
2022/08/12 19:29:45 [debug] 18087#18087: *1 using configuration "=/auth"
2022/08/12 19:29:45 [debug] 18087#18087: *1 http cl:-1 max:1048576
2022/08/12 19:29:45 [debug] 18087#18087: *1 rewrite phase: 2
2022/08/12 19:29:45 [debug] 18087#18087: *1 catching a new _rewrite_
phase handler
2022/08/12 19:29:45 [error] 18087#18087: *1 ModSecurity not enabled...
returning, client: 127.0.0.1, server: localhost, request: "GET
/useauth HTTP/1.1", subrequest: "/auth", host: "127.0.0.1:8080"
2022/08/12 19:29:45 [debug] 18087#18087: *1 rewrite phase: 3
2022/08/12 19:29:45 [debug] 18087#18087: *1 header filter, recovering
ctx: 0000000000000000
More information about the nginx-devel
mailing list