[development][security][modsecurity][nginx] nginx / modsecurity development things
接续前节:[security][modsecurity][nginx] nginx 与 modsecurity
nginx开发手册:https://nginx.org/en/docs/dev/development_guide.html#introduction
modsecurity开发手册:https://modsecurity.org/developers.html
nginx 与 modsecurity的接口在这里:https://nginx.org/en/docs/dev/development_guide.html#Modules
1. 可以确定的事情:
1. modsecurity 是 nginx 的一个mod。
2. nginx加载一个mod的方法:
1. 在运行 configure 脚本时,使用参数:
using --add-module=/path/to/module for static compilation and --add-dynamic-module=/path/to/module for dynamic compilation.
2. 模块需要在这个路径下准备一个配置文件: config
3. 以及模块源码文件。
4. 2,3中的内容,在目录 github/ModSecurity/nginx/modsecurity/ 下。
modsecurity,好像是一个http类型的mod,读了Modules章节之后还要读HTTP章节。
https://nginx.org/en/docs/dev/development_guide.html#http
没太细啃,大概过了一下,总之就是没怎么看懂。。。
3. 如何写一个module:
参考:https://nginx.org/en/docs/dev/development_guide.html#http
3.1 关键的结构体:
struct ngx_module_s { ngx_uint_t ctx_index; ngx_uint_t index; char *name; ngx_uint_t spare0; ngx_uint_t spare1; ngx_uint_t version; const char *signature; void *ctx; ngx_command_t *commands; ngx_uint_t type; ngx_int_t (*init_master)(ngx_log_t *log); ngx_int_t (*init_module)(ngx_cycle_t *cycle); ngx_int_t (*init_process)(ngx_cycle_t *cycle); ngx_int_t (*init_thread)(ngx_cycle_t *cycle); void (*exit_thread)(ngx_cycle_t *cycle); void (*exit_process)(ngx_cycle_t *cycle); void (*exit_master)(ngx_cycle_t *cycle); uintptr_t spare_hook0; uintptr_t spare_hook1; uintptr_t spare_hook2; uintptr_t spare_hook3; uintptr_t spare_hook4; uintptr_t spare_hook5; uintptr_t spare_hook6; uintptr_t spare_hook7; };
modsecurity 中的实现:
ngx_module_t ngx_http_modsecurity = { NGX_MODULE_V1, &ngx_http_modsecurity_ctx, /* module context */ ngx_http_modsecurity_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ ngx_http_modsecurity_init_process, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ ngx_http_modsecurity_terminate, /* exit process */ ngx_http_modsecurity_terminate, /* exit master */ NGX_MODULE_V1_PADDING };
其中,成员commands,赋值为 NGX_HTTP_MODULE
结构体 ngx_http_modsecurity 是一切的开始。
3.2 关键的函数:
ngx_http_modsecurity_config()// 初始化配置文件的入口。
ngx_http_modsecurity_preconfiguration ()
L----> modsecInit ()
ngx_http_modsecurity_init ()
L: phases[NGX_HTTP_PREACCESS_PHASE].handlers = ngx_http_modsecurity_handler
参考:phases章节
Each HTTP request passes through a list of HTTP phases. Each phase is specialized in a particular type of processing.
Most phases allow installing handlers. The phase handlers are called successively once the request reaches the phase.
Many standard nginx modules install their phase handlers as a way to get called at a specific request processing stage.
在不同的阶段注册不同的回调函数, modsecurity 在 NGX_HTTP_PREACCESS_PHASE 阶段注册了函数 ngx_http_modsecurity_handler。
ngx_http_modsecurity_handler()
从注释看来,这里就是入口函数了:
/* ** [ENTRY POINT] does : this function called by nginx from the request handler */
3.3 关键函数
modsecurity_process_phase()
在apache2模块中,此函数基本上可以理解为是入口,与Eagle_eye中的使用,保持一致。
3.4 关键函数
好多函数的实现,采用次方式:
int modsecProcessRequestHeaders(request_rec *r) { return hookfn_post_read_request(r); }
这是一个宏,参考standalone/hooks.c
可以发现 函数hookfn_post_read_request 等于 函数ap_hook_post_read_request()中第一个参数对其进行的赋值。
格式为: hookfn%(NAME) ==> ap_hook%(NAME)
/home/tong/Src/thirdparty/github/ModSecurity [git::stable/cur *] [tong@T7] [16:36] > grep -r ap_hook_post_read_request ./ ./apache2/mod_security2.c: ap_hook_post_read_request(hook_request_early,
也就是说 hookfn_post_read_request 等价于 apache2/mod_security2.c:hook_request_early
从 nginx/modsecurity/config 的内容,也可以看见include了apache2的代码。
至此,nginx模块的入口,也统一到了函数:
modsecurity_process_phase()
3.5 API
standalone/api.h
apache2/mod_security2.c