はじめに
ModSecurity-nginxのソースコードリーディングについて記事にしました。Apacheのモジュールと同じように、Nginxからフックされていると思います。現状の認識はそのレベルです。Nginxとlibmodsecurity.so.3.0.6のコネクタのソースコードから見ていくことにしました。Nginxのフックを受けるのは、コネクタですので、分かり易いのではないかという想定です。
Nginxのフックフェーズ
どのフェーズでModSecurityのハンドラがコールされるかが分かると思う。
- NGX_HTTP_POST_READ_PHASE
- NGX_HTTP_SERVER_REWRITE_PHASE
- NGX_HTTP_FIND_CONFIG_PHASE
- NGX_HTTP_REWRITE_PHASE
- NGX_HTTP_POST_REWRITE_PHASE
- NGX_HTTP_PREACCESS_PHASE
- NGX_HTTP_ACCESS_PHASE
- NGX_HTTP_POST_ACCESS_PHASE
- NGX_HTTP_TRY_FILES_PHASE
- NGX_HTTP_CONTENT_PHASE
- NGX_HTTP_LOG_PHASE
Nginxモジュールの構造体
- ngx_http_module_t
- ngx_http_handler_pt
- ngx_http_core_main_conf_t
とりあえず、Nginxのフックフェーズでgrepしてみる
NGX_HTTP_REWRITE_PHASE、NGX_HTTP_PREACCESS_PHASE、NGX_HTTP_LOG_PHASEのハンドラを登録しているようです。
$ grep NGX_HTTP_ /home/ec2-user/download/ModSecurity-nginx/src/* | grep _PHASE
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: * NGX_HTTP_FIND_CONFIG_PHASE. it does not seems to
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: * TODO: check if we can hook prior to NGX_HTTP_REWRITE_PHASE phase.
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: h_rewrite = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: dd("Not able to create a new NGX_HTTP_REWRITE_PHASE handle");
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: h_preaccess = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: dd("Not able to create a new NGX_HTTP_PREACCESS_PHASE handle");
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: h_log = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: dd("Not able to create a new NGX_HTTP_LOG_PHASE handle");
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_rewrite.c: * we have to hook into NGX_HTTP_FIND_CONFIG_PHASE, it seems to be the
Nginxモジュールの構造体でgrepしてみる
$ grep ngx_http_module_t /home/ec2-user/download/ModSecurity-nginx/src/*
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c:static ngx_http_module_t ngx_http_modsecurity_ctx = {
$ grep ngx_http_handler_pt /home/ec2-user/download/ModSecurity-nginx/src/*
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: ngx_http_handler_pt *h_rewrite;
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: ngx_http_handler_pt *h_preaccess;
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: ngx_http_handler_pt *h_log;
$ grep ngx_http_core_main_conf_t /home/ec2-user/download/ModSecurity-nginx/src/*
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: ngx_http_core_main_conf_t *cmcf;
ModSecurity初期化
/ModSecurity-nginx/src/ngx_http_modsecurity_module.c
static ngx_int_t
ngx_http_modsecurity_init(ngx_conf_t *cf)
{
ngx_http_handler_pt *h_rewrite;
ngx_http_handler_pt *h_preaccess;
ngx_http_handler_pt *h_log;
ngx_http_core_main_conf_t *cmcf;
int rc = 0;
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
if (cmcf == NULL)
{
dd("We are not sure how this returns, NGINX doesn't seem to think it will ever be null");
return NGX_ERROR;
}
省略
h_rewrite = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
if (h_rewrite == NULL)
{
dd("Not able to create a new NGX_HTTP_REWRITE_PHASE handle");
return NGX_ERROR;
}
*h_rewrite = ngx_http_modsecurity_rewrite_handler; ←REWRITEフェーズのハンドラ登録
省略
h_preaccess = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
if (h_preaccess == NULL)
{
dd("Not able to create a new NGX_HTTP_PREACCESS_PHASE handle");
return NGX_ERROR;
}
*h_preaccess = ngx_http_modsecurity_pre_access_handler; ←PREACCESSフェーズのハンドラ登録
省略
h_log = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
if (h_log == NULL)
{
dd("Not able to create a new NGX_HTTP_LOG_PHASE handle");
return NGX_ERROR;
}
*h_log = ngx_http_modsecurity_log_handler; ←LOGフェーズのハンドラ登録
登録されたハンドラ名でgrep
$ grep ngx_http_modsecurity_rewrite_handler /home/ec2-user/download/ModSecurity-nginx/src/*
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_common.h:ngx_int_t ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r);
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: *h_rewrite = ngx_http_modsecurity_rewrite_handler;
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_rewrite.c:ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
$ grep ngx_http_modsecurity_pre_access_handler /home/ec2-user/download/ModSecurity-nginx/src/*
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_common.h:ngx_int_t ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r);
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: *h_preaccess = ngx_http_modsecurity_pre_access_handler;
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_pre_access.c:ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r)
$ grep ngx_http_modsecurity_log_handler /home/ec2-user/download/ModSecurity-nginx/src/*
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_common.h:ngx_int_t ngx_http_modsecurity_log_handler(ngx_http_request_t *r);
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_log.c:ngx_http_modsecurity_log_handler(ngx_http_request_t *r)
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: ngx_http_modsecurity_log_handler(r);
/home/ec2-user/download/ModSecurity-nginx/src/ngx_http_modsecurity_module.c: *h_log = ngx_http_modsecurity_log_handler;