From 4c4fd2f022cd32db1d6b08ebda396ae826f3bedd Mon Sep 17 00:00:00 2001 From: ADD-SP Date: Sun, 4 Apr 2021 21:21:05 +0800 Subject: [PATCH] :sparkles: Use the directive `waf_priority` to change the rule priority. :bug: The statistics of CC protection are sometimes inaccurate. :boom: Deprecate the directive `waf_cc_deny_limit` and replace it all with `waf_cc_deny`. --- CHANGES-ZH-CN.md | 14 +- CHANGES.md | 14 +- docs/advance/changes.md | 14 +- docs/advance/priority.md | 12 +- docs/advance/syntax.md | 78 ++- docs/guide/configuration.md | 18 +- docs/guide/overview.md | 2 +- docs/zh-cn/advance/changes.md | 13 +- docs/zh-cn/advance/priority.md | 9 +- docs/zh-cn/advance/syntax.md | 67 ++- docs/zh-cn/guide/configuration.md | 12 +- docs/zh-cn/guide/overview.md | 2 +- inc/ngx_http_waf_module_check.h | 306 +++++----- inc/ngx_http_waf_module_config.h | 667 ++++++++++++--------- inc/ngx_http_waf_module_core.h | 9 + inc/ngx_http_waf_module_ip_trie.h | 75 ++- inc/ngx_http_waf_module_lru_cache.h | 76 +-- inc/ngx_http_waf_module_macro.h | 316 +++++----- inc/ngx_http_waf_module_mem_pool.h | 14 +- inc/ngx_http_waf_module_token_bucket_set.h | 57 +- inc/ngx_http_waf_module_type.h | 22 +- inc/ngx_http_waf_module_util.h | 201 +++++-- src/ngx_http_waf_module_core.c | 218 ++++--- test/nginx-dynamic-module.conf | 4 +- test/nginx-static-module.conf | 4 +- 25 files changed, 1315 insertions(+), 909 deletions(-) diff --git a/CHANGES-ZH-CN.md b/CHANGES-ZH-CN.md index 4b992861..1c63bfa1 100644 --- a/CHANGES-ZH-CN.md +++ b/CHANGES-ZH-CN.md @@ -2,21 +2,31 @@ ## [未发布] +### **警告** + +**此版本包含不兼容的更新(breaking changes)。** + ### 新增 * 新增了模式 `CACHE`,启用此模式后会缓存每次检查的结果,提高性能。 -* 新增了配置项 `waf_cache` 用于设置缓存相关的参数。 +* 新增了配置 `waf_cache` 用于设置缓存相关的参数。 +* 新增了配置 `waf_cc_deny`,用于设置 CC 防护相关的参数。 +* 新增了配置 `waf_priority`,用来设置除了 POST 检查以外所有的检查项目的优先级。 ### 移除 +* 废弃了配置 `waf_cc_deny_limit`,使用新的配置 `waf_cc_deny` 替代。 + ### 变动 -* 互换了 CC 防护和 IP 白名单检查的优先级。 +* 互换了 CC 防护和 IP 白名单检查的默认优先级。 ### 修复 * 修复了当 worker 进程数量大于一时的段错误。 +* 修复了 CC 防护统计有时不准的错误。 + *** ## [4.0.0] - 2021-03-22 GMT+0800 diff --git a/CHANGES.md b/CHANGES.md index 75b0c619..0df308a5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,22 +2,34 @@ ## [Unreleased] +### **WARNING** + +**This version contains breaking changes.** + ### Added * A new mode `CACHE` has been added, enabling this mode will cache the results of each inspection to improve performance. * New configuration `waf_cache` has been added to set parameters related to cache. +* Added directive `waf_cc_deny` to set CC protection related parameters. + +* New directive `waf_priority` has been added to set the priority of all checks except for POST checks. + ### Removed +* The directive `waf_cc_deny_limit` is deprecated and replaced with the new directive `waf_cc_deny`. + ### Changed -* Swaps the priority of CC protection and IP whitelist inspection. +* Swaps the default priority of CC protection and IP whitelist inspection. ### Fixed * Fixed a segmentation fault when the number of worker processes is greater than one. +* Fixed a bug where CC protection statistics were sometimes inaccurate. + *** ## [4.0.0] - 2021-03-22 GMT+0800 diff --git a/docs/advance/changes.md b/docs/advance/changes.md index ba9bb27c..7870afea 100644 --- a/docs/advance/changes.md +++ b/docs/advance/changes.md @@ -7,22 +7,34 @@ lang: en ## [Unreleased] +### **WARNING** + +**This version contains breaking changes.** + ### Added * A new mode `CACHE` has been added, enabling this mode will cache the results of each inspection to improve performance. * New configuration `waf_cache` has been added to set parameters related to cache. +* Added directive `waf_cc_deny` to set CC protection related parameters. + +* New directive `waf_priority` has been added to set the priority of all checks except for POST checks. + ### Removed +* The directive `waf_cc_deny_limit` is deprecated and replaced with the new directive `waf_cc_deny`. + ### Changed -* Swaps the priority of CC protection and IP whitelist inspection. +* Swaps the default priority of CC protection and IP whitelist inspection. ### Fixed * Fixed a segmentation fault when the number of worker processes is greater than one. +* Fixed a bug where CC protection statistics were sometimes inaccurate. + *** ## [4.0.0] - 2021-03-22 GMT+0800 diff --git a/docs/advance/priority.md b/docs/advance/priority.md index 9fde37f1..60f6cd11 100644 --- a/docs/advance/priority.md +++ b/docs/advance/priority.md @@ -5,7 +5,7 @@ lang: en # Rule Priority -There are many inspection items in this module, so it is important to specify the inspection priority of each inspection item to avoid illogical inspection results. +There are many inspection process in this module, so it is important to specify the inspection priority of each inspection process to avoid illogical inspection results. The following is a list of all the tests in order of priority, from top to bottom. @@ -21,8 +21,16 @@ The following is a list of all the tests in order of priority, from top to botto 10. Cookie blacklist inspection 11. Post request body blacklist + +::: tip Change priority + +You can modify the priority through the configuration file, but the priority of the POST request body detection is not allowed to be modified, it will always have the lowest priority. See [waf_priority](syntax.md#waf-priority) for details + +::: + + ::: tip CHANGES IN THE DEVELOPMENT VERSION -Swaps the priority of CC protection and IP whitelist inspection. +Swaps the default priority of CC protection and IP whitelist inspection. ::: diff --git a/docs/advance/syntax.md b/docs/advance/syntax.md index 04a1a9ef..1a54e263 100644 --- a/docs/advance/syntax.md +++ b/docs/advance/syntax.md @@ -7,15 +7,15 @@ lang: en ## `waf` -* syntax: `waf ;` -* default: `waf off;` +* syntax: waf \<*on* | *off*\> +* default: waf *off* * context: server Whether to enable this module. ## `waf_rule_path` -* syntax: `waf_rule_path ;` +* syntax: waf_rule_path \<*dir*\> * default: — * context: server @@ -23,7 +23,7 @@ The absolute path to the directory where the rule file is located, and must end ## `waf_mode` -* syntax: `waf_mode ...;` +* syntax: waf_mode \<*mode_type*\> ... * default: — * context: server @@ -90,7 +90,7 @@ The following modes have changed: ## `waf_cc_deny_limit` -* syntax: `waf_cc_deny_limit [buffer_size];` +* syntax: waf_cc_deny_limit \<*rate*\> \<*duration*\> \[*buffer_size*\] * default: —— * context: server @@ -101,17 +101,43 @@ Set the parameters related to CC protection. * `buffer_size`: used to set the size of the memory for recording IP accesses, such as `10m`, `10240k`, must not be less than `10m`, if not specified then the default is `10m`. +::: tip CHANGES IN DEVELOPMENT + +* syntax: waf_cc_deny \ \[duration=*1h*\] \[buffer_size=*20m*\] +* default: —— +* context: server + +Set the parameters related to CC protection. + +* `rate`: indicates the maximum number of requests per minute, e.g. `60r/m` means the maximum number of requests per minute is 60. +* `duration`: indicates the IP band oh after exceeding the limit of the first parameter `rate`, such as `60s`, `60m`, `60h` and `60d`, if not specified, the default is `1h`. +* `buffer_size`: Used to set the size of the memory for recording IP accesses, such as `20m`, `2048k`, must not be less than `20m`, if not specified, the default is `20m`. + + +::: + + + ## `waf_cache` -* syntax: `waf_cache [interval] [percent];` +* syntax: waf_cache \ \[interval=*1h*\] \[percent=*50*\] * default: —— * context: server -Set parameters related to caching rule inspection results. +Set the parameters related to cache rule inspection results. -* `capacity`: For some inspections with the caching mechanism enabled, the maximum number of inspection results for each inspection target is cached. -* `interval`: Used to set the period of batch cache cleaning in minutes. If not specified, the default is `60`, which is 60 minutes. -* `percent`: what percentage of the cache will be eliminated each time the cache is eliminated in bulk. You need to specify an integer greater than 0 and less than or equal to 100. A setting of 50 means that half of the cache is eliminated. If not specified, the default is `50`. +* `capacity`: for some inspection items with caching mechanism enabled, the maximum number of inspection results per inspection item to be cached for each inspection target. +* `interval`: set the period of the batch cull cache in minutes, such as `60s`, `60m`, `60h` and `60d`, or `1h` if not specified. If not specified, the default is `1h`, which is one hour. +* `percent`: what percentage of the cache is eliminated each time the batch eliminates the cache. Specify an integer greater than 0 and less than or equal to 100. A setting of 50 means that half of the cache is eliminated. If not specified, the default is `50`. + + +::: warning WARNING + +This configuration is a new feature in the development version, +and can only be used in the development version, +and will be merged into the stable version when it is stable. + +::: ::: tip Cache-enabled inspections @@ -131,11 +157,35 @@ So please set it reasonably according to your actual needs. ::: -::: warning WARNING +## `waf_priority` -This configuration is a new feature in the development version, -and can only be used in the development version, -and will be merged into the stable version when it is stable. +* syntax: waf_priority "*str*" +* default: waf_priority "W-IP B-IP CC W-URL URL ARGS UA W-REFERER REFERER COOKIE" +* context: server + +Set the priority of each inspection process, except for POST detection, which always has the lowest priority. + +* `W-IP`: IP whitelist inspection +* `IP`: IP Blacklist inspection +* `CC`: CC protection +* `W-URL`: URL whitelist inspection +* `URL`: URL blacklist inspection +* `ARGS`: URL parameter (query string) blacklist inspection +* `UA`: User-Agent blacklist inspection +* `W-REFERER`: Referer whitelist inspection +* `REFERER`: Referer blacklist inspection +* `COOKIE`: Cookie blacklist inspection + + +::: warning warning + +This configuration is a new feature in the development version, and can only be used in the development version, and will be merged into the stable version when it is stable. + +::: + +::: warning warning + +`str` must be wrapped in single or double quotes, and `str` must contain all of the inspection process. ::: diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index b9668b65..54abd2d8 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -21,20 +21,24 @@ http { ... # on means enabled, off means disabled. waf on; + # The absolute path to the directory where the rule file is located, must end with /. waf_rule_path /usr/local/src/ngx_waf/rules/; + # Firewall working mode, STD indicates standard mode. waf_mode STD; - # CC protection parameter, 1000 maximum number of requests per minute, - # 60 means the corresponding ip is blocked for 60 minutes after exceeding the limit. - waf_cc_deny_limit 1000 60; + + # CC defense parameter, 1000 requests per minute limit, + # block the corresponding ip for 60 minutes after exceeding the limit. + waf_cc_deny rate=1000r/m duration=60m; + # The following directives are for the development version only. - # Cache the results of up to as many inspection targets as possible, - # effective for all inspections - # except IP black and white list inspection, CC protection and POST inspection. - waf_cache 60; + # Cache detection results for up to 50 detection targets, + # effective for all detections + # except IP black and white list detection, CC protection and POST detection. + waf_cache capacity=50; ... } ... diff --git a/docs/guide/overview.md b/docs/guide/overview.md index 1a566c57..2e973666 100644 --- a/docs/guide/overview.md +++ b/docs/guide/overview.md @@ -22,7 +22,7 @@ When the number of worker processes in nginx is greater than one, the current st * Block the specified request body. * Exceptional allow on specific URL. * Block the specified URL. -* Block the specified request args. +* Block the specified query string. * Block the specified UserAgent. * Block the specified Cookie. * Exceptional allow on specific Referer. diff --git a/docs/zh-cn/advance/changes.md b/docs/zh-cn/advance/changes.md index 25f93973..1151e77b 100644 --- a/docs/zh-cn/advance/changes.md +++ b/docs/zh-cn/advance/changes.md @@ -7,21 +7,30 @@ lang: zh-CN ## [未发布] +### **警告** + +**此版本包含不兼容的更新(breaking changes)。** + ### 新增 * 新增了模式 `CACHE`,启用此模式后会缓存每次检查的结果,提高性能。 -* 新增了配置项 `waf_cache` 用于设置缓存相关的参数。 +* 新增了配置 `waf_cache` 用于设置缓存相关的参数。 +* 新增了配置 `waf_cc_deny`,用于设置 CC 防护相关的参数。 +* 新增了配置 `waf_priority`,用来设置除了 POST 检查以外所有的检查项目的优先级。 ### 移除 +* 废弃了配置 `waf_cc_deny_limit`,使用新的配置 `waf_cc_deny` 替代。 + ### 变动 -* 互换了 CC 防护和 IP 白名单检查的优先级。 +* 互换了 CC 防护和 IP 白名单检查的默认优先级。 ### 修复 * 修复了当 worker 进程数量大于一时的段错误。 + *** ## [4.0.0] - 2021-03-22 GMT+0800 diff --git a/docs/zh-cn/advance/priority.md b/docs/zh-cn/advance/priority.md index ed6408d0..7ee57a38 100644 --- a/docs/zh-cn/advance/priority.md +++ b/docs/zh-cn/advance/priority.md @@ -21,8 +21,15 @@ lang: zh-CN 10. Cookie 黑名单检测 11. Post 请求体黑名单 + +::: tip 修改优先级 + +您可以通过配置文件修改优先级,但是 POST 请求体检测的优先级不允许修改,它的优先级永远是最低的。详见 [waf_priority](syntax.md#waf-priority)。 + +::: + ::: tip 开发版中的变动 -互换了 CC 防护和 IP 白名单检测的优先级。 +互换了 CC 防护和 IP 白名单检测的默认优先级。 ::: diff --git a/docs/zh-cn/advance/syntax.md b/docs/zh-cn/advance/syntax.md index 26b3bb9c..03dd917f 100644 --- a/docs/zh-cn/advance/syntax.md +++ b/docs/zh-cn/advance/syntax.md @@ -7,15 +7,15 @@ lang: zh-CN ## `waf` -* 配置语法: `waf ;` -* 默认配置:`waf off;` +* 配置语法: waf \<*on* | *off*\> +* 默认配置:waf *off* * 配置段: server 是否启用本模块。 ## `waf_rule_path` -* 配置语法: `waf_rule_path ;` +* 配置语法: waf_rule_path <\*dir*\> * 默认配置:—— * 配置段: server @@ -23,7 +23,7 @@ lang: zh-CN ## `waf_mode` -* 配置语法: `waf_mode ...;` +* 配置语法: waf_mode \<*mode_type*\> ... * 默认配置:—— * 配置段: server @@ -90,7 +90,7 @@ waf_mode STD !UA; ## `waf_cc_deny_limit` -* 配置语法: `waf_cc_deny_limit [buffer_size];` +* 配置语法: waf_cc_deny \<*rate*\> \<*duration*\> \[*buffer_size*\]` * 默认配置:—— * 配置段: server @@ -100,18 +100,41 @@ waf_mode STD !UA; * `duration`:表示超出第一个参数 `rate` 的限制后拉黑 IP 多少分钟(大于零的整数). * `buffer_size`:用于设置记录 IP 访问次数的内存的大小,如 `10m`、`10240k`,不得小于 `10m`,如不指定则默认为 `10m`。 +::: tip 开发版中的变动 + +* 配置语法: waf_cc_deny \ \[duration=*1h*\] \[buffer_size=*20m*\] +* 默认配置:—— +* 配置段: server + +设置 CC 防护相关的参数。 + +* `rate`:表示每分钟的最多请求次数,如 `60r/m` 表示每分钟最多请求 60 次。 +* `duration`:表示超出第一个参数 `rate` 的限制后拉黑 IP 带哦就,如 `60s`、`60m`、`60h` 和 `60d`,如不指定则默认为 `1h`。 +* `buffer_size`:用于设置记录 IP 访问次数的内存的大小,如 `20m`、`2048k`,不得小于 `20m`,如不指定则默认为 `20m`。 + + +::: + ## `waf_cache` -* 配置语法: `waf_cache [interval] [percent];` +* 配置语法: waf_cache \ \[interval=*1h*\] \[percent=*50*\] * 默认配置:—— * 配置段: server 设置缓存规则检查结果相关的参数。 * `capacity`:对于一些启用了缓存机制的检测项目,每个检测项目最多缓存多少个检测目标的检测结果。 -* `interval`:用于设置批量淘汰缓存的周期,单位为分钟。如不指定则默认为 `60`,即 60 分钟。 +* `interval`:用于设置批量淘汰缓存的周期,单位为分钟,如 `60s`、`60m`、`60h` 和 `60d`,如不指定则默认为 `1h`。如不指定则默认为 `1h`,即一小时。 * `percent`:每次批量淘汰缓存时淘汰掉多少比例的缓存。需要指定一个大于 0 小于等于 100 的整数。若设置为 50 则代表淘汰掉一半的缓存。如不指定则默认为 `50`。 + +::: warning 警告 + +本配置属于开发版新增的功能,只能在开发版中使用,等稳定后会合并到稳定版中。 + +::: + + ::: tip 启用了缓存机制的检测项目 启用了缓存机制的检测项目指除了 CC 防护、IP 黑白名单检测和 POST 检测之外的所有的检测项。 @@ -124,8 +147,38 @@ waf_mode STD !UA; ::: + +## `waf_priority` + +* 配置语法: waf_priority "*str*" +* 默认配置:waf_priority "W-IP IP CC W-URL URL ARGS UA W-REFERER REFERER COOKIE" +* 配置段: server + +设置各个检测项目的优先级,除了 POST 检测,POST 检测的优先级永远最低。 + +* `W-IP`:IP 白名单检测 +* `IP`:IP 黑名单检测 +* `CC`:CC 防护 +* `W-URL`:URL 白名单检测 +* `URL`:URL 黑名单检测 +* `ARGS`:URL 参数(查询字符串)黑名单检测 +* `UA`:User-Agent 黑名单检测 +* `W-REFERER`:Referer 白名单检测 +* `REFERER`:Referer 黑名单检测 +* `COOKIE`:Cookie 黑名单检测 + + ::: warning 警告 本配置属于开发版新增的功能,只能在开发版中使用,等稳定后会合并到稳定版中。 ::: + +::: warning 警告 + +`str` 必须使用单引号或者双引号包裹,且 `str` 必须包含全部的检测项目。 + +::: + + + diff --git a/docs/zh-cn/guide/configuration.md b/docs/zh-cn/guide/configuration.md index ecde587f..5bb5475a 100644 --- a/docs/zh-cn/guide/configuration.md +++ b/docs/zh-cn/guide/configuration.md @@ -24,17 +24,21 @@ http { ... # on 表示启用,off 表示关闭。 waf on; + # 规则文件所在目录的绝对路径,必须以 / 结尾。 waf_rule_path /usr/local/src/ngx_waf/rules/; + # 防火墙工作模式,STD 表示标准模式。 waf_mode STD; - # CC 防御参数,1000 每分钟请求次数上限,60 表示超出上限后封禁对应 ip 60 分钟。 - waf_cc_deny_limit 1000 60; + + # CC 防御参数,1000 每分钟请求次数上限,超出上限后封禁对应 ip 60 分钟。 + waf_cc_deny rate=1000r/m duration=60m; + # 下面的配置仅开发版可用。 - # 最多缓存多少个检测目标的检测结果,对除了 IP 黑白名单检测、CC 防护和 POST 检测以外的所有检测生效。 - waf_cache 50; + # 最多缓存 50 个检测目标的检测结果,对除了 IP 黑白名单检测、CC 防护和 POST 检测以外的所有检测生效。 + waf_cache capacity=50; ... } ... diff --git a/docs/zh-cn/guide/overview.md b/docs/zh-cn/guide/overview.md index 754b8056..b50d9444 100644 --- a/docs/zh-cn/guide/overview.md +++ b/docs/zh-cn/guide/overview.md @@ -20,7 +20,7 @@ lang: zh-CN * IP 黑白名单,同时支持类似 `192.168.0.0/16` 和 `fe80::/10`,即支持点分十进制和冒号十六进制表示法和网段划分。 * POST 黑名单。 * URL 黑白名单 -* GET 参数黑名单 +* 查询字符串(Query String)黑名单。 * UserAgent 黑名单。 * Cookie 黑名单。 * Referer 黑白名单。 diff --git a/inc/ngx_http_waf_module_check.h b/inc/ngx_http_waf_module_check.h index 78229f43..2bd241b9 100644 --- a/inc/ngx_http_waf_module_check.h +++ b/inc/ngx_http_waf_module_check.h @@ -30,12 +30,6 @@ extern ngx_module_t ngx_http_waf_module; /**< 模块详情 */ * @{ */ -/** - * @typedef ngx_http_waf_check - * @brief 请求检查函数的函数指针 - * @param[out] out_http_status 当触发规则时需要返回的 HTTP 状态码。 -*/ -typedef ngx_int_t (*ngx_http_waf_check)(ngx_http_request_t* r, ngx_int_t* out_http_status); /** * @brief 检查客户端 IP 地址是否在白名单中。 @@ -139,7 +133,7 @@ static ngx_int_t ngx_http_waf_handler_check_black_cookie(ngx_http_request_t* r, /** * @brief 检查请求体内容是否存在于黑名单中,存在则拦截,反之放行。 */ -static void check_post(ngx_http_request_t* r); +static void ngx_http_waf_handler_check_black_post(ngx_http_request_t* r); /** * @} @@ -158,16 +152,16 @@ static ngx_int_t ngx_http_waf_handler_check_white_ip(ngx_http_request_t* r, ngx_ ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_IP) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_IP) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -177,24 +171,24 @@ static ngx_int_t ngx_http_waf_handler_check_white_ip(ngx_http_request_t* r, ngx_ struct sockaddr_in* sin = (struct sockaddr_in*)r->connection->sockaddr; inx_addr_t inx_addr; ngx_memcpy(&(inx_addr.ipv4), &(sin->sin_addr), sizeof(struct in_addr)); - if (ip_trie_find(&srv_conf->white_ipv4, &inx_addr, &ip_trie_node) == SUCCESS) { - ctx->blocked = FALSE; + if (ip_trie_find(&srv_conf->white_ipv4, &inx_addr, &ip_trie_node) == NGX_HTTP_WAF_SUCCESS) { + ctx->blocked = NGX_HTTP_WAF_FALSE; strcpy((char*)ctx->rule_type, "WHITE-IPV4"); strcpy((char*)ctx->rule_deatils, (char*)ip_trie_node->data); *out_http_status = NGX_DECLINED; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; } } else if (r->connection->sockaddr->sa_family == AF_INET6) { struct sockaddr_in6* sin6 = (struct sockaddr_in6*)r->connection->sockaddr; inx_addr_t inx_addr; ngx_memcpy(&(inx_addr.ipv6), &(sin6->sin6_addr), sizeof(struct in6_addr)); - if (ip_trie_find(&srv_conf->white_ipv6, &inx_addr, &ip_trie_node) == SUCCESS) { - ctx->blocked = FALSE; + if (ip_trie_find(&srv_conf->white_ipv6, &inx_addr, &ip_trie_node) == NGX_HTTP_WAF_SUCCESS) { + ctx->blocked = NGX_HTTP_WAF_FALSE; strcpy((char*)ctx->rule_type, "WHITE-IPV4"); strcpy((char*)ctx->rule_deatils, (char*)ip_trie_node->data); *out_http_status = NGX_DECLINED; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; } } @@ -220,16 +214,16 @@ static ngx_int_t ngx_http_waf_handler_check_black_ip(ngx_http_request_t* r, ngx_ ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_IP) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_IP) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -240,23 +234,23 @@ static ngx_int_t ngx_http_waf_handler_check_black_ip(ngx_http_request_t* r, ngx_ inx_addr_t inx_addr; ngx_memcpy(&(inx_addr.ipv4), &(sin->sin_addr), sizeof(struct in_addr)); - if (ip_trie_find(&srv_conf->black_ipv4, &inx_addr, &ip_trie_node) == SUCCESS) { - ctx->blocked = TRUE; + if (ip_trie_find(&srv_conf->black_ipv4, &inx_addr, &ip_trie_node) == NGX_HTTP_WAF_SUCCESS) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-IPV4"); strcpy((char*)ctx->rule_deatils, (char*)ip_trie_node->data); *out_http_status = NGX_HTTP_FORBIDDEN; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; } } else if (r->connection->sockaddr->sa_family == AF_INET6) { struct sockaddr_in6* sin6 = (struct sockaddr_in6*)r->connection->sockaddr; inx_addr_t inx_addr; ngx_memcpy(&(inx_addr.ipv6), &(sin6->sin6_addr), sizeof(struct in6_addr)); - if (ip_trie_find(&srv_conf->black_ipv6, &inx_addr, &ip_trie_node) == SUCCESS) { - ctx->blocked = TRUE; + if (ip_trie_find(&srv_conf->black_ipv6, &inx_addr, &ip_trie_node) == NGX_HTTP_WAF_SUCCESS) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-IPV6"); strcpy((char*)ctx->rule_deatils, (char*)ip_trie_node->data); *out_http_status = NGX_HTTP_FORBIDDEN; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; } } @@ -282,19 +276,19 @@ static ngx_int_t ngx_http_waf_handler_check_cc(ngx_http_request_t* r, ngx_int_t* ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; ngx_int_t ip_type = r->connection->sockaddr->sa_family; time_t now = time(NULL); - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_CC) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_CC) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this detection is disabled in the configuration, no detection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else if (srv_conf->waf_cc_deny_limit == NGX_CONF_UNSET || srv_conf->waf_cc_deny_duration == NGX_CONF_UNSET) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this detection is disabled in the configuration, no detection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Detection has begun."); @@ -310,7 +304,7 @@ static ngx_int_t ngx_http_waf_handler_check_cc(ngx_http_request_t* r, ngx_int_t* ngx_memcpy(&(inx_addr.ipv6), &(s_addr_in6->sin6_addr), sizeof(struct in6_addr)); } - double diff_minutes = 0.0; + double diff_second = 0.0; ngx_int_t limit = srv_conf->waf_cc_deny_limit; ngx_int_t duration = srv_conf->waf_cc_deny_duration; ip_trie_node_t* node = NULL; @@ -325,42 +319,42 @@ static ngx_int_t ngx_http_waf_handler_check_cc(ngx_http_request_t* r, ngx_int_t* if (ip_type == AF_INET) { - if (ip_trie_find(srv_conf->ipv4_access_statistics, &inx_addr, &node) == SUCCESS) { + if (ip_trie_find(srv_conf->ipv4_access_statistics, &inx_addr, &node) == NGX_HTTP_WAF_SUCCESS) { ngx_memcpy(&statis, node->data, sizeof(ip_statis_t)); - diff_minutes = difftime(now, statis.start_time) / 60; + diff_second = difftime(now, statis.start_time); } else { switch (ip_trie_add(srv_conf->ipv4_access_statistics, &inx_addr, 32, &statis, sizeof(ip_statis_t))) { - case SUCCESS: + case NGX_HTTP_WAF_SUCCESS: ip_trie_find(srv_conf->ipv4_access_statistics, &inx_addr, &node); + ngx_memcpy(&statis, node->data, sizeof(ip_statis_t)); break; - case MALLOC_ERROR: - ngx_post_event(&srv_conf->event_clear_ip_access_statistics, &ngx_posted_events); - *(srv_conf->last_clear_ip_access_statistics) = time(NULL); + case NGX_HTTP_WAF_MALLOC_ERROR: + *(srv_conf->last_clear_ip_access_statistics) = 0; ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: No shared memory, memory collection event has been triggered."); break; - case FAIL: + case NGX_HTTP_WAF_FAIL: ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Failed to add ipv6 statistics."); break; } } } else if (ip_type == AF_INET6) { - if (ip_trie_find(srv_conf->ipv6_access_statistics, &inx_addr, &node) == SUCCESS) { + if (ip_trie_find(srv_conf->ipv6_access_statistics, &inx_addr, &node) == NGX_HTTP_WAF_SUCCESS) { ngx_memcpy(&statis, node->data, sizeof(ip_statis_t)); - diff_minutes = difftime(now, statis.start_time) / 60; + diff_second = difftime(now, statis.start_time); } else { switch (ip_trie_add(srv_conf->ipv6_access_statistics, &inx_addr, 128, &statis, sizeof(ip_statis_t))) { - case SUCCESS: - ip_trie_find(srv_conf->ipv6_access_statistics, &inx_addr, &node); + case NGX_HTTP_WAF_SUCCESS: + ip_trie_find(srv_conf->ipv6_access_statistics, &inx_addr, &node); + ngx_memcpy(&statis, node->data, sizeof(ip_statis_t)); break; - case MALLOC_ERROR: - ngx_post_event(&srv_conf->event_clear_ip_access_statistics, &ngx_posted_events); - *(srv_conf->last_clear_ip_access_statistics) = time(NULL); + case NGX_HTTP_WAF_MALLOC_ERROR: + *(srv_conf->last_clear_ip_access_statistics) = 0; ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: No shared memory, memory collection event has been triggered."); break; - case FAIL: + case NGX_HTTP_WAF_FAIL: ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Failed to add ipv6 statistics."); break; @@ -369,26 +363,26 @@ static ngx_int_t ngx_http_waf_handler_check_cc(ngx_http_request_t* r, ngx_int_t* } /* 如果是在一分钟内开始统计的 */ - if (diff_minutes < 1) { + if (diff_second < 60) { /* 如果访问次数超出上限 */ if (statis.count > limit) { - ctx->blocked = TRUE; + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "CC-DNEY"); strcpy((char*)ctx->rule_deatils, ""); *out_http_status = NGX_HTTP_SERVICE_UNAVAILABLE; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; } else { ++(statis.count); ngx_memcpy(node->data, &statis, sizeof(ip_statis_t)); } } else { /* 如果一分钟前访问次数就超出上限 && 仍然在拉黑时间内 */ - if (statis.count > limit && diff_minutes <= duration) { - ctx->blocked = TRUE; + if (statis.count > limit && diff_second <= duration) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "CC-DNEY"); strcpy((char*)ctx->rule_deatils, ""); *out_http_status = NGX_HTTP_SERVICE_UNAVAILABLE; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; } else { /* 重置访问次数和记录时间 */ statis.count = 1; @@ -424,16 +418,16 @@ static ngx_int_t ngx_http_waf_handler_check_white_url(ngx_http_request_t* r, ngx ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_URL) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_URL) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this detection is disabled in the configuration, no detection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -445,11 +439,11 @@ static ngx_int_t ngx_http_waf_handler_check_white_url(ngx_http_request_t* r, ngx if (p_uri->data == NULL || p_uri->len == 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the URL is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { u_char* rule_details = NULL; - ngx_int_t cache_hit = FAIL; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + ngx_int_t cache_hit = NGX_HTTP_WAF_FAIL; + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { cache_hit = lru_cache_manager_find(&srv_conf->white_url_inspection_cache, p_uri->data, @@ -458,18 +452,18 @@ static ngx_int_t ngx_http_waf_handler_check_white_url(ngx_http_request_t* r, ngx &rule_details); } - if (cache_hit != SUCCESS) { + if (cache_hit != NGX_HTTP_WAF_SUCCESS) { for (size_t i = 0; i < srv_conf->white_url->nelts; i++, p++) { ngx_int_t rc = ngx_regex_exec(p->regex, p_uri, NULL, 0); if (rc >= 0) { - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; rule_details = p->name; break; } } } - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { lru_cache_manager_add(&srv_conf->white_url_inspection_cache, p_uri->data, @@ -478,8 +472,8 @@ static ngx_int_t ngx_http_waf_handler_check_white_url(ngx_http_request_t* r, ngx rule_details); } - if (ret_value == MATCHED) { - ctx->blocked = FALSE; + if (ret_value == NGX_HTTP_WAF_MATCHED) { + ctx->blocked = NGX_HTTP_WAF_FALSE; strcpy((char*)ctx->rule_type, "WHITE-URL"); strcpy((char*)ctx->rule_deatils, (char*)rule_details); *out_http_status = NGX_DECLINED; @@ -508,16 +502,16 @@ static ngx_int_t ngx_http_waf_handler_check_black_url(ngx_http_request_t* r, ngx ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_URL) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_URL) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -528,11 +522,11 @@ static ngx_int_t ngx_http_waf_handler_check_black_url(ngx_http_request_t* r, ngx if (p_uri->data == NULL || p_uri->len == 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the URL is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { u_char* rule_details = NULL; - ngx_int_t cache_hit = FAIL; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + ngx_int_t cache_hit = NGX_HTTP_WAF_FAIL; + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { cache_hit = lru_cache_manager_find(&srv_conf->black_url_inspection_cache, p_uri->data, @@ -541,18 +535,18 @@ static ngx_int_t ngx_http_waf_handler_check_black_url(ngx_http_request_t* r, ngx &rule_details); } - if (cache_hit != SUCCESS) { + if (cache_hit != NGX_HTTP_WAF_SUCCESS) { for (size_t i = 0; i < srv_conf->black_url->nelts; i++, p++) { ngx_int_t rc = ngx_regex_exec(p->regex, p_uri, NULL, 0); if (rc >= 0) { - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; rule_details = p->name; break; } } } - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { lru_cache_manager_add(&srv_conf->black_url_inspection_cache, p_uri->data, @@ -561,8 +555,8 @@ static ngx_int_t ngx_http_waf_handler_check_black_url(ngx_http_request_t* r, ngx rule_details); } - if (ret_value == MATCHED) { - ctx->blocked = TRUE; + if (ret_value == NGX_HTTP_WAF_MATCHED) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-URL"); strcpy((char*)ctx->rule_deatils, (char*)rule_details); *out_http_status = NGX_HTTP_FORBIDDEN; @@ -591,20 +585,20 @@ static ngx_int_t ngx_http_waf_handler_check_black_args(ngx_http_request_t* r, ng ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_ARGS) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_ARGS) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else if (r->args.len == 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the ARGS is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -616,11 +610,11 @@ static ngx_int_t ngx_http_waf_handler_check_black_args(ngx_http_request_t* r, ng if (p_args->data == NULL || p_args->len == 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the ARGS is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { u_char* rule_details = NULL; - ngx_int_t cache_hit = FAIL; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + ngx_int_t cache_hit = NGX_HTTP_WAF_FAIL; + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { cache_hit = lru_cache_manager_find(&srv_conf->black_args_inspection_cache, p_args->data, @@ -629,18 +623,18 @@ static ngx_int_t ngx_http_waf_handler_check_black_args(ngx_http_request_t* r, ng &rule_details); } - if (cache_hit != SUCCESS) { + if (cache_hit != NGX_HTTP_WAF_SUCCESS) { for (size_t i = 0; i < srv_conf->black_args->nelts; i++, p++) { ngx_int_t rc = ngx_regex_exec(p->regex, p_args, NULL, 0); if (rc >= 0) { - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; rule_details = p->name; break; } } } - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { lru_cache_manager_add(&srv_conf->black_args_inspection_cache, p_args->data, @@ -649,8 +643,8 @@ static ngx_int_t ngx_http_waf_handler_check_black_args(ngx_http_request_t* r, ng rule_details); } - if (ret_value == MATCHED) { - ctx->blocked = TRUE; + if (ret_value == NGX_HTTP_WAF_MATCHED) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-ARGS"); strcpy((char*)ctx->rule_deatils, (char*)rule_details); *out_http_status = NGX_HTTP_FORBIDDEN; @@ -679,20 +673,20 @@ static ngx_int_t ngx_http_waf_handler_check_black_user_agent(ngx_http_request_t* ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_UA) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_UA) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else if (r->headers_in.user_agent == NULL) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the User-Agent is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -704,11 +698,11 @@ static ngx_int_t ngx_http_waf_handler_check_black_user_agent(ngx_http_request_t* if (p_ua->data == NULL || p_ua->len == 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the User-Agent is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { u_char* rule_details = NULL; - ngx_int_t cache_hit = FAIL; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + ngx_int_t cache_hit = NGX_HTTP_WAF_FAIL; + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { cache_hit = lru_cache_manager_find(&srv_conf->black_ua_inspection_cache, p_ua->data, @@ -717,18 +711,18 @@ static ngx_int_t ngx_http_waf_handler_check_black_user_agent(ngx_http_request_t* &rule_details); } - if (cache_hit != SUCCESS) { + if (cache_hit != NGX_HTTP_WAF_SUCCESS) { for (size_t i = 0; i < srv_conf->black_ua->nelts; i++, p++) { ngx_int_t rc = ngx_regex_exec(p->regex, p_ua, NULL, 0); if (rc >= 0) { - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; rule_details = p->name; break; } } } - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { lru_cache_manager_add(&srv_conf->black_ua_inspection_cache, p_ua->data, @@ -737,8 +731,8 @@ static ngx_int_t ngx_http_waf_handler_check_black_user_agent(ngx_http_request_t* rule_details); } - if (ret_value == MATCHED) { - ctx->blocked = TRUE; + if (ret_value == NGX_HTTP_WAF_MATCHED) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-USER-AGENT"); strcpy((char*)ctx->rule_deatils, (char*)rule_details); *out_http_status = NGX_HTTP_FORBIDDEN; @@ -767,20 +761,20 @@ static ngx_int_t ngx_http_waf_handler_check_white_referer(ngx_http_request_t* r, ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_REFERER) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_REFERER) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else if (r->headers_in.referer == NULL) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the Referer is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -792,11 +786,11 @@ static ngx_int_t ngx_http_waf_handler_check_white_referer(ngx_http_request_t* r, if (p_referer->data == NULL || p_referer->len == 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the Referer is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { u_char* rule_details = NULL; - ngx_int_t cache_hit = FAIL; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + ngx_int_t cache_hit = NGX_HTTP_WAF_FAIL; + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { cache_hit = lru_cache_manager_find(&srv_conf->white_referer_inspection_cache, p_referer->data, @@ -805,18 +799,18 @@ static ngx_int_t ngx_http_waf_handler_check_white_referer(ngx_http_request_t* r, &rule_details); } - if (cache_hit != SUCCESS) { + if (cache_hit != NGX_HTTP_WAF_SUCCESS) { for (size_t i = 0; i < srv_conf->white_referer->nelts; i++, p++) { ngx_int_t rc = ngx_regex_exec(p->regex, p_referer, NULL, 0); if (rc >= 0) { - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; rule_details = p->name; break; } } } - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { lru_cache_manager_add(&srv_conf->white_referer_inspection_cache, p_referer->data, @@ -825,8 +819,8 @@ static ngx_int_t ngx_http_waf_handler_check_white_referer(ngx_http_request_t* r, rule_details); } - if (ret_value == MATCHED) { - ctx->blocked = TRUE; + if (ret_value == NGX_HTTP_WAF_MATCHED) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "WHITE-REFERER"); strcpy((char*)ctx->rule_deatils, (char*)rule_details); *out_http_status = NGX_DECLINED; @@ -855,20 +849,20 @@ static ngx_int_t ngx_http_waf_handler_check_black_referer(ngx_http_request_t* r, ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_REFERER) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_REFERER) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else if (r->headers_in.referer == NULL) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the Referer is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -880,11 +874,11 @@ static ngx_int_t ngx_http_waf_handler_check_black_referer(ngx_http_request_t* r, if (p_referer->data == NULL || p_referer->len == 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The Inspection is skipped because the Referer is empty."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else { u_char* rule_details = NULL; - ngx_int_t cache_hit = FAIL; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + ngx_int_t cache_hit = NGX_HTTP_WAF_FAIL; + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { cache_hit = lru_cache_manager_find(&srv_conf->black_referer_inspection_cache, p_referer->data, @@ -893,18 +887,18 @@ static ngx_int_t ngx_http_waf_handler_check_black_referer(ngx_http_request_t* r, &rule_details); } - if (cache_hit != SUCCESS) { + if (cache_hit != NGX_HTTP_WAF_SUCCESS) { for (size_t i = 0; i < srv_conf->black_referer->nelts; i++, p++) { ngx_int_t rc = ngx_regex_exec(p->regex, p_referer, NULL, 0); if (rc >= 0) { - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; rule_details = p->name; break; } } } - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { lru_cache_manager_add(&srv_conf->black_referer_inspection_cache, p_referer->data, @@ -913,8 +907,8 @@ static ngx_int_t ngx_http_waf_handler_check_black_referer(ngx_http_request_t* r, rule_details); } - if (ret_value == MATCHED) { - ctx->blocked = TRUE; + if (ret_value == NGX_HTTP_WAF_MATCHED) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-REFERER"); strcpy((char*)ctx->rule_deatils, (char*)rule_details); *out_http_status = NGX_HTTP_FORBIDDEN; @@ -943,16 +937,16 @@ static ngx_int_t ngx_http_waf_handler_check_black_cookie(ngx_http_request_t* r, ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: The configuration of the module has been obtained."); - ngx_int_t ret_value = NOT_MATCHED; + ngx_int_t ret_value = NGX_HTTP_WAF_NOT_MATCHED; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_COOKIE) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_COOKIE) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Inspection is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; - } else if (CHECK_FLAG(srv_conf->waf_mode, r->method) == FALSE) { + ret_value = NGX_HTTP_WAF_NOT_MATCHED; + } else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, r->method) == NGX_HTTP_WAF_FALSE) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Because this Http.Method is disabled in the configuration, no Inspection is performed."); - ret_value = NOT_MATCHED; + ret_value = NGX_HTTP_WAF_NOT_MATCHED; } else if (r->headers_in.cookies.nelts != 0) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -981,9 +975,9 @@ static ngx_int_t ngx_http_waf_handler_check_black_cookie(ngx_http_request_t* r, ngx_memcpy(temp.data, (**ppcookie).key.data, (**ppcookie).key.len); ngx_memcpy(temp.data + (**ppcookie).key.len, (**ppcookie).value.data, (**ppcookie).value.len); - ngx_int_t cache_hit = FAIL; + ngx_int_t cache_hit = NGX_HTTP_WAF_FAIL; u_char* rule_detail = NULL; - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { cache_hit = lru_cache_manager_find(&srv_conf->black_cookie_inspection_cache, temp.data, @@ -992,12 +986,12 @@ static ngx_int_t ngx_http_waf_handler_check_black_cookie(ngx_http_request_t* r, &rule_detail); } - if (cache_hit != SUCCESS && ngx_regex_exec(p->regex, &temp, NULL, 0) >= 0) { + if (cache_hit != NGX_HTTP_WAF_SUCCESS && ngx_regex_exec(p->regex, &temp, NULL, 0) >= 0) { rule_detail = p->name; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; } - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_CACHE) == TRUE + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_CACHE) == NGX_HTTP_WAF_TRUE && srv_conf->waf_inspection_capacity != NGX_CONF_UNSET) { lru_cache_manager_add(&srv_conf->black_cookie_inspection_cache, temp.data, @@ -1008,16 +1002,16 @@ static ngx_int_t ngx_http_waf_handler_check_black_cookie(ngx_http_request_t* r, ngx_pfree(r->pool, temp.data); - if (ret_value == MATCHED) { - ctx->blocked = TRUE; + if (ret_value == NGX_HTTP_WAF_MATCHED) { + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-COOKIE"); strcpy((char*)ctx->rule_deatils, (char*)rule_detail); *out_http_status = NGX_HTTP_FORBIDDEN; - ret_value = MATCHED; + ret_value = NGX_HTTP_WAF_MATCHED; break; } } - if (ret_value == MATCHED) { + if (ret_value == NGX_HTTP_WAF_MATCHED) { break; } } @@ -1032,7 +1026,7 @@ static ngx_int_t ngx_http_waf_handler_check_black_cookie(ngx_http_request_t* r, } -static void check_post(ngx_http_request_t* r) { +static void ngx_http_waf_handler_check_black_post(ngx_http_request_t* r) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Start inspecting the Post-Body blacklist."); @@ -1048,7 +1042,7 @@ static void check_post(ngx_http_request_t* r) { ngx_buf_t* body_buf = NULL; ngx_str_t body_str; - ctx->read_body_done = TRUE; + ctx->read_body_done = NGX_HTTP_WAF_TRUE; ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection has begun."); @@ -1077,7 +1071,7 @@ static void check_post(ngx_http_request_t* r) { for (i = 0; i < srv_conf->black_post->nelts; i++, p++) { rc = ngx_regex_exec(p->regex, &body_str, NULL, 0); if (rc >= 0) { - ctx->blocked = TRUE; + ctx->blocked = NGX_HTTP_WAF_TRUE; strcpy((char*)ctx->rule_type, "BLACK-POST"); strcpy((char*)ctx->rule_deatils, (char*)p->name); ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_waf: [%s][%s]", ctx->rule_type, ctx->rule_deatils); @@ -1086,7 +1080,7 @@ static void check_post(ngx_http_request_t* r) { } } - if (ctx->blocked != TRUE) { + if (ctx->blocked != NGX_HTTP_WAF_TRUE) { break; } @@ -1096,7 +1090,7 @@ static void check_post(ngx_http_request_t* r) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Inspection is over."); - if (ctx->blocked != TRUE) { + if (ctx->blocked != NGX_HTTP_WAF_TRUE) { ngx_http_finalize_request(r, NGX_DONE); ngx_http_core_run_phases(r); } diff --git a/inc/ngx_http_waf_module_config.h b/inc/ngx_http_waf_module_config.h index 988f7e9d..bc1d09b8 100644 --- a/inc/ngx_http_waf_module_config.h +++ b/inc/ngx_http_waf_module_config.h @@ -10,6 +10,7 @@ #endif #include +#include #include #include #include @@ -34,6 +35,7 @@ static ngx_int_t ngx_http_waf_handler_access_phase(ngx_http_request_t* r); * @{ */ + /** * @brief 读取配置项 waf_mult_mount,该项表示是否将检测过程挂载到两个阶段以应对 rewrite 导致的 URL 和 ARGS 前后不一致的情况。 * @warning 此配置项已经废弃,保留此函数只为了提示用户这一信息,后续版本会删除。 @@ -56,14 +58,19 @@ static char* ngx_http_waf_rule_path_conf(ngx_conf_t* cf, ngx_command_t* cmd, voi static char* ngx_http_waf_mode_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); /** - * @brief 读取配置项 waf_cc_deny_limit,该项表示最高的访问频次以及超出后的拉黑时间。 + * @brief 读取配置项 waf_cc_deny,该项表示最高的访问频次以及超出后的拉黑时间。 */ -static char* ngx_http_waf_cc_deny_limit_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); +static char* ngx_http_waf_cc_deny_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); /** - * @brief 读取配置项 waf_cache_size,该项表示最高的访问频次以及超出后的拉黑时间。 + * @brief 读取配置项 waf_cache,该项表示最高的访问频次以及超出后的拉黑时间。 */ -static char* ngx_http_waf_cache_size_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); +static char* ngx_http_waf_cache_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); + +/** + * @brief 读取配置项 waf_priority,该项用来设置检查项目的优先级。 +*/ +static char* ngx_http_waf_priority_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); /** * @brief 当读取 waf_blocked 变量时的回调函数,这个变量当请求被拦截的时候是 "true",反之是 "false"。 @@ -96,15 +103,14 @@ static void* ngx_http_waf_create_srv_conf(ngx_conf_t* cf); static ngx_int_t ngx_http_waf_init_after_load_config(ngx_conf_t* cf); +/** + * @brief 用于 CC 防护的共享内存的初始时的回调函数 + * @param[in] zone 正在初始化的共享内存 + * @param[in] data ngx_http_waf_srv_conf_t +*/ static ngx_int_t ngx_http_waf_shm_zone_cc_deny_init(ngx_shm_zone_t *zone, void *data); -static void ngx_http_waf_event_clear_ip_access_statistics_handler(ngx_event_t* event); - - -static void ngx_http_waf_event_eliminate_inspection_cache_handler(ngx_event_t* event); - - /** * @brief 读取指定文件的内容到容器中。 * @param[in] file_name 要读取的配置文件完整路径。 @@ -114,7 +120,7 @@ static void ngx_http_waf_event_eliminate_inspection_cache_handler(ngx_event_t* e * @li 当 mode = 1 时会将读取到的文本转化为 ipv4_t 再存储。容器类型为 ip_trie_t。 * @li 当 mode = 2 时会将读取到的文本转化为 ipv6_t 再存储。容器类型为 ip_trie_t。 * @return 读取操作的结果。 - * @retval SUCCESS 读取成功。 + * @retval NGX_HTTP_WAF_SUCCESS 读取成功。 * @retval FAIL 读取中发生错误。 */ static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void* container, ngx_int_t mode); @@ -123,12 +129,13 @@ static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void * @} */ + static char* ngx_http_waf_mult_mount_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { /* TODO: 此配置于 v4.0.0 开始废弃,合并到配置 waf_mode 内。 暂时保留此配置用来提示这一不向下兼容的更改,可能会在后续某个版本中删除提示。 */ ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_ENOMOREFILES, - "ngx_waf: \"waf_mult_mount\" is a deprecated directive since v4.0.0. Its functionality has been merged into the \"waf_mode\" directive. For more information please visit https://docs.addesp.com/ngx_waf/advance/syntax.html or https://add-sp.github.io/ngx_waf/advance/syntax.html or https://ngx-waf.pages.dev/advance/syntax.html ."); + "ngx_waf: \"waf_mult_mount\" is a deprecated directive since v4.0.0. Its functionality has been merged into the \"waf_mode\" directive. For more information please visit https://docs.addesp.com/ngx_waf/advance/syntax.html or https://add-sp.github.io/ngx_waf/advance/syntax.html or https://ngx-waf.pages.dev/advance/syntax.html"); return NGX_CONF_ERROR; } @@ -144,25 +151,25 @@ static char* ngx_http_waf_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { static char* ngx_http_waf_rule_path_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { ngx_http_waf_srv_conf_t* srv_conf = conf; if (ngx_conf_set_str_slot(cf, cmd, conf) != NGX_CONF_OK) { - ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "ngx_waf: %s", "The path of the config file is not specified"); + ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "ngx_waf: %s", "the path of the rule files is not specified"); return NGX_CONF_ERROR; } - char* full_path = ngx_palloc(cf->pool, sizeof(char) * RULE_MAX_LEN); + char* full_path = ngx_palloc(cf->pool, sizeof(char) * NGX_HTTP_WAF_RULE_MAX_LEN); char* end = to_c_str((u_char*)full_path, srv_conf->waf_rule_path); - CHECK_AND_LOAD_CONF(cf, full_path, end, IPV4_FILE, &srv_conf->black_ipv4, 1); - CHECK_AND_LOAD_CONF(cf, full_path, end, IPV6_FILE, &srv_conf->black_ipv6, 2); - CHECK_AND_LOAD_CONF(cf, full_path, end, URL_FILE, srv_conf->black_url, 0); - CHECK_AND_LOAD_CONF(cf, full_path, end, ARGS_FILE, srv_conf->black_args, 0); - CHECK_AND_LOAD_CONF(cf, full_path, end, UA_FILE, srv_conf->black_ua, 0); - CHECK_AND_LOAD_CONF(cf, full_path, end, REFERER_FILE, srv_conf->black_referer, 0); - CHECK_AND_LOAD_CONF(cf, full_path, end, COOKIE_FILE, srv_conf->black_cookie, 0); - CHECK_AND_LOAD_CONF(cf, full_path, end, POST_FILE, srv_conf->black_post, 0); - CHECK_AND_LOAD_CONF(cf, full_path, end, WHITE_IPV4_FILE, &srv_conf->white_ipv4, 1); - CHECK_AND_LOAD_CONF(cf, full_path, end, WHITE_IPV6_FILE, &srv_conf->white_ipv6, 2); - CHECK_AND_LOAD_CONF(cf, full_path, end, WHITE_URL_FILE, srv_conf->white_url, 0); - CHECK_AND_LOAD_CONF(cf, full_path, end, WHITE_REFERER_FILE, srv_conf->white_referer, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_IPV4_FILE, &srv_conf->black_ipv4, 1); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_IPV6_FILE, &srv_conf->black_ipv6, 2); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_URL_FILE, srv_conf->black_url, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_ARGS_FILE, srv_conf->black_args, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_UA_FILE, srv_conf->black_ua, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_REFERER_FILE, srv_conf->black_referer, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_COOKIE_FILE, srv_conf->black_cookie, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_POST_FILE, srv_conf->black_post, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_WHITE_IPV4_FILE, &srv_conf->white_ipv4, 1); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_WHITE_IPV6_FILE, &srv_conf->white_ipv6, 2); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_WHITE_URL_FILE, srv_conf->white_url, 0); + NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, full_path, end, NGX_HTTP_WAF_WHITE_REFERER_FILE, srv_conf->white_referer, 0); ngx_pfree(cf->pool, full_path); return NGX_CONF_OK; @@ -177,277 +184,277 @@ static char* ngx_http_waf_mode_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* co for (i = 1; i < cf->args->nelts && modes != NULL; i++) { if (ngx_strncasecmp(modes[i].data, (u_char*)"GET", ngx_min(modes[i].len, sizeof("GET") - 1)) == 0 && modes[i].len == sizeof("GET") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_GET; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_GET; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!GET", ngx_min(modes[i].len, sizeof("!GET") - 1)) == 0 && modes[i].len == sizeof("!GET") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_HEAD; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_HEAD; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"HEAD", ngx_min(modes[i].len, sizeof("HEAD") - 1)) == 0 && modes[i].len == sizeof("HEAD") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_HEAD; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_HEAD; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!HEAD", ngx_min(modes[i].len, sizeof("!HEAD") - 1)) == 0 && modes[i].len == sizeof("!HEAD") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_HEAD; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_HEAD; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"POST", ngx_min(modes[i].len, sizeof("POST") - 1)) == 0 && modes[i].len == sizeof("POST") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_POST; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_POST; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!POST", ngx_min(modes[i].len, sizeof("!POST") - 1)) == 0 && modes[i].len == sizeof("!POST") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_POST; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_POST; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"PUT", ngx_min(modes[i].len, sizeof("PUT") - 1)) == 0 && modes[i].len == sizeof("PUT") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_PUT; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_PUT; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!PUT", ngx_min(modes[i].len, sizeof("!PUT") - 1)) == 0 && modes[i].len == sizeof("!PUT") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_PUT; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_PUT; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"DELETE", ngx_min(modes[i].len, sizeof("DELETE") - 1)) == 0 && modes[i].len == sizeof("DELETE") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_DELETE; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_DELETE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!DELETE", ngx_min(modes[i].len, sizeof("!DELETE") - 1)) == 0 && modes[i].len == sizeof("!DELETE") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_DELETE; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_DELETE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"MKCOL", ngx_min(modes[i].len, sizeof("MKCOL") - 1)) == 0 && modes[i].len == sizeof("MKCOL") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_MKCOL; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_MKCOL; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!MKCOL", ngx_min(modes[i].len, sizeof("!MKCOL") - 1)) == 0 && modes[i].len == sizeof("!MKCOL") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_MKCOL; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_MKCOL; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"COPY", ngx_min(modes[i].len, sizeof("COPY") - 1)) == 0 && modes[i].len == sizeof("COPY") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_COPY; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_COPY; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!COPY", ngx_min(modes[i].len, sizeof("!COPY") - 1)) == 0 && modes[i].len == sizeof("!COPY") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_COPY; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_COPY; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"MOVE", ngx_min(modes[i].len, sizeof("MOVE") - 1)) == 0 && modes[i].len == sizeof("MOVE") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_MOVE; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_MOVE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!MOVE", ngx_min(modes[i].len, sizeof("!MOVE") - 1)) == 0 && modes[i].len == sizeof("!MOVE") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_MOVE; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_MOVE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"OPTIONS", ngx_min(modes[i].len, sizeof("OPTIONS") - 1)) == 0 && modes[i].len == sizeof("OPTIONS") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_OPTIONS; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_OPTIONS; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!OPTIONS", ngx_min(modes[i].len, sizeof("!OPTIONS") - 1)) == 0 && modes[i].len == sizeof("!OPTIONS") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_OPTIONS; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_OPTIONS; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"PROPFIND", ngx_min(modes[i].len, sizeof("PROPFIND") - 1)) == 0 && modes[i].len == sizeof("PROPFIND") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_PROPFIND; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_PROPFIND; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!PROPFIND", ngx_min(modes[i].len, sizeof("!PROPFIND") - 1)) == 0 && modes[i].len == sizeof("!PROPFIND") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_PROPFIND; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_PROPFIND; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"PROPPATCH", ngx_min(modes[i].len, sizeof("PROPPATCH") - 1)) == 0 && modes[i].len == sizeof("PROPPATCH") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_PROPPATCH; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_PROPPATCH; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!PROPPATCH", ngx_min(modes[i].len, sizeof("!PROPPATCH") - 1)) == 0 && modes[i].len == sizeof("!PROPPATCH") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_PROPPATCH; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_PROPPATCH; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"LOCK", ngx_min(modes[i].len, sizeof("LOCK") - 1)) == 0 && modes[i].len == sizeof("LOCK") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_LOCK; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_LOCK; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!LOCK", ngx_min(modes[i].len, sizeof("!LOCK") - 1)) == 0 && modes[i].len == sizeof("!LOCK") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_LOCK; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_LOCK; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"UNLOCK", ngx_min(modes[i].len, sizeof("UNLOCK") - 1)) == 0 && modes[i].len == sizeof("UNLOCK") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_UNLOCK; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_UNLOCK; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!UNLOCK", ngx_min(modes[i].len, sizeof("!UNLOCK") - 1)) == 0 && modes[i].len == sizeof("!UNLOCK") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_UNLOCK; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_UNLOCK; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"PATCH", ngx_min(modes[i].len, sizeof("PATCH") - 1)) == 0 && modes[i].len == sizeof("PATCH") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_PATCH; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_PATCH; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!PATCH", ngx_min(modes[i].len, sizeof("!PATCH") - 1)) == 0 && modes[i].len == sizeof("!PATCH") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_PATCH; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_PATCH; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"TRACE", ngx_min(modes[i].len, sizeof("TRACE") - 1)) == 0 && modes[i].len == sizeof("TRACE") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_TRACE; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_TRACE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!TRACE", ngx_min(modes[i].len, sizeof("!TRACE") - 1)) == 0 && modes[i].len == sizeof("!TRACE") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_TRACE; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_TRACE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"IP", ngx_min(modes[i].len, sizeof("IP") - 1)) == 0 && modes[i].len == sizeof("IP") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_IP; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_IP; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!IP", ngx_min(modes[i].len, sizeof("!IP") - 1)) == 0 && modes[i].len == sizeof("!IP") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_IP; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_IP; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"URL", ngx_min(modes[i].len, sizeof("URL") - 1)) == 0 && modes[i].len == sizeof("URL") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_URL; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_URL; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!URL", ngx_min(modes[i].len, sizeof("!URL") - 1)) == 0 && modes[i].len == sizeof("!URL") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_URL; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_URL; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"RBODY", ngx_min(modes[i].len, sizeof("RBODY") - 1)) == 0 && modes[i].len == sizeof("RBODY") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_RB; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_RB; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!RBODY", ngx_min(modes[i].len, sizeof("!RBODY") - 1)) == 0 && modes[i].len == sizeof("!RBODY") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_RB; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_RB; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"ARGS", ngx_min(modes[i].len, sizeof("ARGS") - 1)) == 0 && modes[i].len == sizeof("ARGS") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_ARGS; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_ARGS; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!ARGS", ngx_min(modes[i].len, sizeof("!ARGS") - 1)) == 0 && modes[i].len == sizeof("!ARGS") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_ARGS; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_ARGS; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"UA", ngx_min(modes[i].len, sizeof("UA") - 1)) == 0 && modes[i].len == sizeof("UA") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_UA; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_UA; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!UA", ngx_min(modes[i].len, sizeof("!UA") - 1)) == 0 && modes[i].len == sizeof("!UA") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_UA; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_UA; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"COOKIE", ngx_min(modes[i].len, sizeof("COOKIE") - 1)) == 0 && modes[i].len == sizeof("COOKIE") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_COOKIE; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_COOKIE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!COOKIE", ngx_min(modes[i].len, sizeof("!COOKIE") - 1)) == 0 && modes[i].len == sizeof("!COOKIE") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_COOKIE; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_COOKIE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"REFERER", ngx_min(modes[i].len, sizeof("REFERER") - 1)) == 0 && modes[i].len == sizeof("REFERER") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_REFERER; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_REFERER; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!REFERER", ngx_min(modes[i].len, sizeof("!REFERER") - 1)) == 0 && modes[i].len == sizeof("!REFERER") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_REFERER; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_REFERER; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"CC", ngx_min(modes[i].len, sizeof("CC") - 1)) == 0 && modes[i].len == sizeof("CC") - 1) { - srv_conf->waf_mode |= MODE_INSPECT_CC; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_INSPECT_CC; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!CC", ngx_min(modes[i].len, sizeof("!CC") - 1)) == 0 && modes[i].len == sizeof("!CC") - 1) { - srv_conf->waf_mode &= ~MODE_INSPECT_CC; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_INSPECT_CC; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"STD", ngx_min(modes[i].len, sizeof("STD") - 1)) == 0 && modes[i].len == sizeof("STD") - 1) { - srv_conf->waf_mode |= MODE_STD; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_STD; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!STD", ngx_min(modes[i].len, sizeof("!STD") - 1)) == 0 && modes[i].len == sizeof("!STD") - 1) { - srv_conf->waf_mode &= ~MODE_STD; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_STD; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"STATIC", ngx_min(modes[i].len, sizeof("STATIC") - 1)) == 0 && modes[i].len == sizeof("STATIC") - 1) { - srv_conf->waf_mode |= MODE_STATIC; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_STATIC; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!STATIC", ngx_min(modes[i].len, sizeof("!STATIC") - 1)) == 0 && modes[i].len == sizeof("!STATIC") - 1) { - srv_conf->waf_mode &= ~MODE_STATIC; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_STATIC; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"DYNAMIC", ngx_min(modes[i].len, sizeof("DYNAMIC") - 1)) == 0 && modes[i].len == sizeof("DYNAMIC") - 1) { - srv_conf->waf_mode |= MODE_DYNAMIC; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_DYNAMIC; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!DYNAMIC", ngx_min(modes[i].len, sizeof("!DYNAMIC") - 1)) == 0 && modes[i].len == sizeof("!DYNAMIC") - 1) { - srv_conf->waf_mode &= ~MODE_DYNAMIC; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_DYNAMIC; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"FULL", ngx_min(modes[i].len, sizeof("FULL") - 1)) == 0 && modes[i].len == sizeof("FULL") - 1) { - srv_conf->waf_mode |= MODE_FULL; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_FULL; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!FULL", ngx_min(modes[i].len, sizeof("!FULL") - 1)) == 0 && modes[i].len == sizeof("!FULL") - 1) { - srv_conf->waf_mode &= ~MODE_FULL; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_FULL; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"COMPAT", ngx_min(modes[i].len, sizeof("COMPAT") - 1)) == 0 && modes[i].len == sizeof("COMPAT") - 1) { - srv_conf->waf_mode |= MODE_EXTRA_COMPAT; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_EXTRA_COMPAT; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!COMPAT", ngx_min(modes[i].len, sizeof("!COMPAT") - 1)) == 0 && modes[i].len == sizeof("!COMPAT") - 1) { - srv_conf->waf_mode &= ~MODE_EXTRA_COMPAT; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_EXTRA_COMPAT; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"STRICT", ngx_min(modes[i].len, sizeof("STRICT") - 1)) == 0 && modes[i].len == sizeof("STRICT") - 1) { - srv_conf->waf_mode |= MODE_EXTRA_STRICT; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_EXTRA_STRICT; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!STRICT", ngx_min(modes[i].len, sizeof("!STRICT") - 1)) == 0 && modes[i].len == sizeof("!STRICT") - 1) { - srv_conf->waf_mode &= ~MODE_EXTRA_STRICT; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_EXTRA_STRICT; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"CACHE", ngx_min(modes[i].len, sizeof("CACHE") - 1)) == 0 && modes[i].len == sizeof("CACHE") - 1) { - srv_conf->waf_mode |= MODE_EXTRA_CACHE; + srv_conf->waf_mode |= NGX_HTTP_WAF_MODE_EXTRA_CACHE; } else if (ngx_strncasecmp(modes[i].data, (u_char*)"!CACHE", ngx_min(modes[i].len, sizeof("!CACHE") - 1)) == 0 && modes[i].len == sizeof("!CACHE") - 1) { - srv_conf->waf_mode &= ~MODE_EXTRA_CACHE; + srv_conf->waf_mode &= ~NGX_HTTP_WAF_MODE_EXTRA_CACHE; } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: Invalid value. Please visit https://docs.addesp.com/ngx_waf/advance/syntax.html or https://add-sp.github.io/ngx_waf/advance/syntax.html or https://ngx-waf.pages.dev/advance/syntax.html ."); + "ngx_waf: invalid value. Please visit https://docs.addesp.com/ngx_waf/advance/syntax.html or https://add-sp.github.io/ngx_waf/advance/syntax.html or https://ngx-waf.pages.dev/advance/syntax.html"); return NGX_CONF_ERROR; } } @@ -456,50 +463,86 @@ static char* ngx_http_waf_mode_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* co } -static char* ngx_http_waf_cc_deny_limit_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { +static char* ngx_http_waf_cc_deny_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { static ngx_uint_t shm_id = 1; ngx_http_waf_srv_conf_t* srv_conf = conf; ngx_str_t* p_str = cf->args->elts; - u_char error_str[256]; - srv_conf->waf_cc_deny_limit = ngx_atoi(p_str[1].data, p_str[1].len); - if (srv_conf->waf_cc_deny_limit == NGX_ERROR || srv_conf->waf_cc_deny_limit <= 0) { - to_c_str(error_str, p_str[1]); - ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: Cannot convert \"%s\" to a non-zero positive integer", error_str); - return NGX_CONF_ERROR; - } + /* 默认封禁 60 分钟 */ + srv_conf->waf_cc_deny_duration = 1 * 60 * 60; + /* 设置默认的共享内存大小 */ + srv_conf->waf_cc_deny_shm_zone_size = NGX_HTTP_WAF_SHARE_MEMORY_CC_DENY_MIN_SIZE; - srv_conf->waf_cc_deny_duration = ngx_atoi(p_str[2].data, (p_str + 2)->len); - if (srv_conf->waf_cc_deny_duration == NGX_ERROR || srv_conf->waf_cc_deny_duration <= 0) { - to_c_str(error_str, p_str[2]); - ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: Cannot convert \"%s\" to a non-zero positive integer", error_str); - return NGX_CONF_ERROR; - } + for (size_t i = 1; i < cf->args->nelts; i++) { + UT_array* array = NULL; + if (ngx_str_split(p_str + i, '=', 256, &array) != NGX_HTTP_WAF_SUCCESS) { + goto error; + } - - /* 如果有第三个参数 */ - if (cf->args->nelts == 4) { - srv_conf->waf_cc_deny_shm_zone_size = ngx_parse_size(p_str + 3); - if (srv_conf->waf_cc_deny_duration == NGX_ERROR || srv_conf->waf_cc_deny_duration <= 0) { - to_c_str(error_str, p_str[3]); - ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: Invalid memory size %s", error_str); - return NGX_CONF_ERROR; + if (utarray_len(array) != 2) { + goto error; } - if (srv_conf->waf_cc_deny_shm_zone_size < SHARE_MEMORY_CC_DENY_MIN_SIZE) - { - srv_conf->waf_cc_deny_shm_zone_size = SHARE_MEMORY_CC_DENY_MIN_SIZE; - ngx_conf_log_error(NGX_LOG_WARN, cf, NGX_ENOMOREFILES, - "ngx_waf: The specified memory space is too small and is automatically set to the default size: %d KB.", - SHARE_MEMORY_CC_DENY_MIN_SIZE / 1024); + u_char** p = NULL; + p = (u_char**)utarray_next(array, p); + + if (ngx_strcmp("rate", *p) == 0) { + p = (u_char**)utarray_next(array, p); + + UT_array* temp = NULL; + if (str_split(*p, '/', 256, &temp) != NGX_HTTP_WAF_SUCCESS) { + goto error; + } + + if (utarray_len(temp) != 2) { + goto error; + } + + u_char** q = NULL; + q = (u_char**)utarray_next(temp, q); + size_t len = ngx_strlen(*q); + srv_conf->waf_cc_deny_limit = ngx_atoi(*q, len - 1); + if (srv_conf->waf_cc_deny_limit == NGX_ERROR || srv_conf->waf_cc_deny_limit <= 0) { + goto error; + } + if ((*q)[len - 1] != 'r') { + goto error; + } + + q = (u_char**)utarray_next(temp, q); + if (**q != 'm' || ngx_strlen(*q) != 1) { + goto error; + } + + utarray_free(temp); + + } else if (ngx_strcmp("duration", *p) == 0) { + p = (u_char**)utarray_next(array, p); + srv_conf->waf_cc_deny_duration = parse_time(*p); + if (srv_conf->waf_cc_deny_duration == NGX_ERROR) { + goto error; + } + + } else if (ngx_strcmp("size", *p) == 0) { + p = (u_char**)utarray_next(array, p); + srv_conf->waf_cc_deny_shm_zone_size = parse_size(*p); + if (srv_conf->waf_cc_deny_shm_zone_size == NGX_ERROR) { + goto error; + } + srv_conf->waf_cc_deny_shm_zone_size = ngx_max(NGX_HTTP_WAF_SHARE_MEMORY_CC_DENY_MIN_SIZE, + srv_conf->waf_cc_deny_shm_zone_size); + } else { + goto error; } - } else { - srv_conf->waf_cc_deny_shm_zone_size = SHARE_MEMORY_CC_DENY_MIN_SIZE; + + utarray_free(array); + } + + if (srv_conf->waf_cc_deny_limit == NGX_CONF_UNSET) { + goto error; } + u_char* str = ngx_pcalloc(srv_conf->ngx_pool, sizeof(u_char) * 1025); ngx_memcpy(str, cf->conf_file->file.name.data, cf->conf_file->file.name.len); ngx_uint_t id = (ngx_uint_t)shm_id++; @@ -509,7 +552,7 @@ static char* ngx_http_waf_cc_deny_limit_conf(ngx_conf_t* cf, ngx_command_t* cmd, id /= 10; } str[index] = '\0'; - strcat((char*)str, SHARE_MEMORY_CC_DNEY_NAME); + strcat((char*)str, NGX_HTTP_WAF_SHARE_MEMORY_CC_DNEY_NAME); ngx_str_t name; name.data = str; #ifdef __STDC_LIB_EXT1__ @@ -524,7 +567,7 @@ static char* ngx_http_waf_cc_deny_limit_conf(ngx_conf_t* cf, ngx_command_t* cmd, if (srv_conf->shm_zone_cc_deny == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_ENOMOREFILES, - "ngx_waf: Failed to add shared memory."); + "ngx_waf: failed to add shared memory"); return NGX_CONF_ERROR; } @@ -532,106 +575,206 @@ static char* ngx_http_waf_cc_deny_limit_conf(ngx_conf_t* cf, ngx_command_t* cmd, srv_conf->shm_zone_cc_deny->data = srv_conf; return NGX_CONF_OK; + + error: + ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, + "ngx_waf: invalid value"); + return NGX_CONF_ERROR; } -static char* ngx_http_waf_cache_size_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { +static char* ngx_http_waf_cache_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { ngx_http_waf_srv_conf_t* srv_conf = conf; ngx_str_t* p_str = cf->args->elts; - u_char error_str[256]; - srv_conf->waf_inspection_capacity = ngx_atoi(p_str[1].data, p_str[1].len); - if (srv_conf->waf_inspection_capacity == NGX_ERROR - || srv_conf->waf_inspection_capacity <= 0) { - to_c_str(error_str, p_str[1]); - ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: Unable to convert [%s] to a positive integer.", error_str); - return NGX_CONF_ERROR; - } - - if (srv_conf->waf_inspection_capacity < CACHE_ITEM_MIN_NUM) - { - srv_conf->waf_inspection_capacity = CACHE_ITEM_MIN_NUM; - ngx_conf_log_error(NGX_LOG_WARN, cf, NGX_ENOMOREFILES, - "ngx_waf: The maximum number of cache items is too small and is automatically set to the default value: %d.", - CACHE_ITEM_MIN_NUM); - } + /* 默认每隔 60 分钟批量清理一次缓存 */ + srv_conf->waf_eliminate_inspection_cache_interval = 1 * 60 * 60; + /* 默认每次清理一般的缓存 */ + srv_conf->waf_eliminate_inspection_cache_percent = 50; - /* 如果有第二个参数 */ - if (cf->args->nelts == 3) { - srv_conf->waf_eliminate_inspection_cache_interval = ngx_atoi(p_str[2].data, p_str[2].len); - if (srv_conf->waf_eliminate_inspection_cache_interval == NGX_ERROR - || srv_conf->waf_eliminate_inspection_cache_interval <= 0) { - to_c_str(error_str, p_str[2]); - ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: Unable to convert [%s] to a positive integer", error_str); - return NGX_CONF_ERROR; + for (size_t i = 1; i < cf->args->nelts; i++) { + UT_array* array = NULL; + if (ngx_str_split(p_str + i, '=', 256, &array) != NGX_HTTP_WAF_SUCCESS) { + goto error; } - } else { - srv_conf->waf_eliminate_inspection_cache_interval = 60; - } - /* 如果有第三个参数 */ - if (cf->args->nelts == 4) { - srv_conf->waf_eliminate_inspection_cache_percent = ngx_atoi(p_str[3].data, p_str[3].len); - if (srv_conf->waf_eliminate_inspection_cache_percent == NGX_ERROR) { - to_c_str(error_str, p_str[3]); - ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: Unable to convert [%s] to a integer", error_str); - return NGX_CONF_ERROR; + if (utarray_len(array) != 2) { + goto error; } - if (srv_conf->waf_eliminate_inspection_cache_percent <= 0 - || srv_conf->waf_eliminate_inspection_cache_percent > 100) { - to_c_str(error_str, p_str[3]); - ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, - "ngx_waf: [%s] must be greater than 0 and less than or equal to 100.", error_str); - return NGX_CONF_ERROR; + + u_char** p = NULL; + p = (u_char**)utarray_next(array, p); + + if (ngx_strcmp("capacity", *p) == 0) { + p = (u_char**)utarray_next(array, p); + srv_conf->waf_inspection_capacity = ngx_atoi(*p, ngx_strlen(*p)); + if (srv_conf->waf_inspection_capacity == NGX_ERROR + || srv_conf->waf_inspection_capacity <= 0) { + goto error; + } + + } else if (ngx_strcmp("interval", *p) == 0) { + p = (u_char**)utarray_next(array, p); + srv_conf->waf_eliminate_inspection_cache_interval = parse_time(*p); + if (srv_conf->waf_eliminate_inspection_cache_interval == NGX_ERROR) { + goto error; + } + + } else if (ngx_strcmp("percent", *p) == 0) { + p = (u_char**)utarray_next(array, p); + srv_conf->waf_eliminate_inspection_cache_percent = ngx_atoi(*p, ngx_strlen(*p)); + if (srv_conf->waf_eliminate_inspection_cache_percent == NGX_ERROR + || srv_conf->waf_eliminate_inspection_cache_percent <= 0 + || srv_conf->waf_eliminate_inspection_cache_percent > 100) { + goto error; + } + } else { + goto error; } - } else { - srv_conf->waf_eliminate_inspection_cache_percent = 50; + + utarray_free(array); + } + + if (srv_conf->waf_inspection_capacity == NGX_CONF_UNSET) { + goto error; } - if (lru_cache_manager_init(&(srv_conf->black_url_inspection_cache), srv_conf->waf_inspection_capacity, std, NULL) != SUCCESS) { + if (lru_cache_manager_init(&(srv_conf->black_url_inspection_cache), + srv_conf->waf_inspection_capacity, std, NULL) != NGX_HTTP_WAF_SUCCESS) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Failed to initialize black_url_inspection_cache."); return NGX_CONF_ERROR; } - if (lru_cache_manager_init(&(srv_conf->black_args_inspection_cache), srv_conf->waf_inspection_capacity, std, NULL) != SUCCESS) { + if (lru_cache_manager_init(&(srv_conf->black_args_inspection_cache), + srv_conf->waf_inspection_capacity, std, NULL) != NGX_HTTP_WAF_SUCCESS) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Failed to initialize black_args_inspection_cache."); return NGX_CONF_ERROR; } - if (lru_cache_manager_init(&(srv_conf->black_ua_inspection_cache), srv_conf->waf_inspection_capacity, std, NULL) != SUCCESS) { + if (lru_cache_manager_init(&(srv_conf->black_ua_inspection_cache), + srv_conf->waf_inspection_capacity, std, NULL) != NGX_HTTP_WAF_SUCCESS) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Failed to initialize black_ua_inspection_cache."); return NGX_CONF_ERROR; } - if (lru_cache_manager_init(&(srv_conf->black_referer_inspection_cache), srv_conf->waf_inspection_capacity, std, NULL) != SUCCESS) { + if (lru_cache_manager_init(&(srv_conf->black_referer_inspection_cache), + srv_conf->waf_inspection_capacity, std, NULL) != NGX_HTTP_WAF_SUCCESS) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Failed to initialize black_referer_inspection_cache."); return NGX_CONF_ERROR; } - if (lru_cache_manager_init(&(srv_conf->black_cookie_inspection_cache), srv_conf->waf_inspection_capacity, std, NULL) != SUCCESS) { + if (lru_cache_manager_init(&(srv_conf->black_cookie_inspection_cache), + srv_conf->waf_inspection_capacity, std, NULL) != NGX_HTTP_WAF_SUCCESS) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Failed to initialize black_cookie_inspection_cache."); return NGX_CONF_ERROR; } - if (lru_cache_manager_init(&(srv_conf->white_url_inspection_cache), srv_conf->waf_inspection_capacity, std, NULL) != SUCCESS) { + if (lru_cache_manager_init(&(srv_conf->white_url_inspection_cache), + srv_conf->waf_inspection_capacity, std, NULL) != NGX_HTTP_WAF_SUCCESS) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Failed to initialize white_url_inspection_cache."); return NGX_CONF_ERROR; } - if (lru_cache_manager_init(&(srv_conf->white_referer_inspection_cache), srv_conf->waf_inspection_capacity, std, NULL) != SUCCESS) { + if (lru_cache_manager_init(&(srv_conf->white_referer_inspection_cache), + srv_conf->waf_inspection_capacity, std, NULL) != NGX_HTTP_WAF_SUCCESS) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Failed to initialize white_referer_inspection_cache."); return NGX_CONF_ERROR; } return NGX_CONF_OK; + + error: + ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, + "ngx_waf: invalid value"); + return NGX_CONF_ERROR; +} + + +static char* ngx_http_waf_priority_conf(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { + ngx_http_waf_srv_conf_t* srv_conf = conf; + ngx_str_t* p_str = cf->args->elts; + // u_char error_str[256]; + + UT_array* array = NULL; + if (ngx_str_split(p_str + 1, ' ', 20, &array) != NGX_HTTP_WAF_SUCCESS) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, + "ngx_waf: invalid value"); + return NGX_CONF_ERROR; + } + + + if (utarray_len(array) != 10) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, + "ngx_waf: you must specify the priority of all inspections except for POST inspections"); + return NGX_CONF_ERROR; + } + + + u_char** p = NULL; + size_t proc_index = 0, proc_no_cc_index = 0; + while ((p = (u_char**)utarray_next(array, p))) { + if (strcasecmp("CC", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_cc; + + } else if (strcasecmp("W-IP", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_white_ip; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_white_ip; + } + + else if (strcasecmp("IP", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_black_ip; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_black_ip; + } + + else if (strcasecmp("W-URL", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_white_url; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_white_url; + } + + else if (strcasecmp("URL", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_black_url; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_black_url; + } + + else if (strcasecmp("ARGS", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_black_args; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_black_args; + } + + else if (strcasecmp("UA", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_black_user_agent; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_black_user_agent; + } + + else if (strcasecmp("W-REFERER", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_white_referer; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_white_referer; + } + + else if (strcasecmp("REFERER", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_black_referer; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_black_referer; + } + + else if (strcasecmp("COOKIE", (char*)*p) == 0) { + srv_conf->check_proc[proc_index++] = ngx_http_waf_handler_check_black_cookie; + srv_conf->check_proc_no_cc[proc_no_cc_index++] = ngx_http_waf_handler_check_black_cookie; + } + + else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_EINVAL, + "ngx_waf: ngx_waf: invalid value [%s]", *p); + return NGX_CONF_ERROR; + } + } + + utarray_free(array); + + return NGX_CONF_OK; } static void* ngx_http_waf_create_srv_conf(ngx_conf_t* cf) { - // static ngx_uint_t shm_id = 1; ngx_http_waf_srv_conf_t* srv_conf = NULL; srv_conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_waf_srv_conf_t)); if (srv_conf == NULL) { @@ -639,14 +782,7 @@ static void* ngx_http_waf_create_srv_conf(ngx_conf_t* cf) { } ngx_str_null(&srv_conf->waf_rule_path); - /* 条件为真时说明编译时 nginx 的版本小于等于 stable。反之则为 Mainline 版本。 */ - #if (nginx_version <= 1018000) - srv_conf->debug_log = ngx_log_init(NULL); - #else - srv_conf->debug_log = ngx_log_init(NULL, NULL); - #endif - srv_conf->debug_log->log_level = NGX_LOG_DEBUG_CORE; - srv_conf->ngx_pool = ngx_create_pool(sizeof(ngx_pool_t) + INITIAL_SIZE, cf->log); + srv_conf->ngx_pool = ngx_create_pool(sizeof(ngx_pool_t) + NGX_HTTP_WAF_INITIAL_SIZE, cf->log); srv_conf->alloc_times = 0; srv_conf->waf = NGX_CONF_UNSET; srv_conf->waf_mode = 0; @@ -669,25 +805,40 @@ static void* ngx_http_waf_create_srv_conf(ngx_conf_t* cf) { srv_conf->ipv6_access_statistics = NULL; srv_conf->last_clear_ip_access_statistics = NULL; - ngx_memzero(&(srv_conf->event_clear_ip_access_statistics), sizeof(ngx_event_t)); - srv_conf->event_clear_ip_access_statistics.data = srv_conf; - srv_conf->event_clear_ip_access_statistics.log = srv_conf->debug_log; - srv_conf->event_clear_ip_access_statistics.handler = ngx_http_waf_event_clear_ip_access_statistics_handler; - - ngx_memzero(&(srv_conf->event_eliminate_inspection_cache), sizeof(ngx_event_t)); - srv_conf->event_eliminate_inspection_cache.data = srv_conf; - srv_conf->event_eliminate_inspection_cache.log = srv_conf->debug_log; - srv_conf->event_eliminate_inspection_cache.handler = ngx_http_waf_event_eliminate_inspection_cache_handler; - if (srv_conf->debug_log == NULL - || srv_conf->ngx_pool == NULL + ngx_memzero(srv_conf->check_proc, sizeof(srv_conf->check_proc)); + srv_conf->check_proc[0] = ngx_http_waf_handler_check_white_ip; + srv_conf->check_proc[1] = ngx_http_waf_handler_check_black_ip; + srv_conf->check_proc[2] = ngx_http_waf_handler_check_cc; + srv_conf->check_proc[3] = ngx_http_waf_handler_check_white_url; + srv_conf->check_proc[4] = ngx_http_waf_handler_check_black_url; + srv_conf->check_proc[5] = ngx_http_waf_handler_check_black_args; + srv_conf->check_proc[6] = ngx_http_waf_handler_check_black_user_agent; + srv_conf->check_proc[7] = ngx_http_waf_handler_check_white_referer; + srv_conf->check_proc[8] = ngx_http_waf_handler_check_black_referer; + srv_conf->check_proc[9] = ngx_http_waf_handler_check_black_cookie; + + + ngx_memzero(srv_conf->check_proc_no_cc, sizeof(srv_conf->check_proc_no_cc)); + srv_conf->check_proc_no_cc[0] = ngx_http_waf_handler_check_white_ip; + srv_conf->check_proc_no_cc[1] = ngx_http_waf_handler_check_black_ip; + srv_conf->check_proc_no_cc[2] = ngx_http_waf_handler_check_white_url; + srv_conf->check_proc_no_cc[3] = ngx_http_waf_handler_check_black_url; + srv_conf->check_proc_no_cc[4] = ngx_http_waf_handler_check_black_args; + srv_conf->check_proc_no_cc[5] = ngx_http_waf_handler_check_black_user_agent; + srv_conf->check_proc_no_cc[6] = ngx_http_waf_handler_check_white_referer; + srv_conf->check_proc_no_cc[7] = ngx_http_waf_handler_check_black_referer; + srv_conf->check_proc_no_cc[8] = ngx_http_waf_handler_check_black_cookie; + + + if (srv_conf->ngx_pool == NULL || srv_conf->black_url == NULL || srv_conf->black_args == NULL || srv_conf->black_ua == NULL || srv_conf->black_referer == NULL || srv_conf->white_url == NULL || srv_conf->white_referer == NULL) { - ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: Initialization failed"); + ngx_log_error(NGX_LOG_ERR, cf->log, 0, "ngx_waf: initialization failed"); return NULL; } @@ -708,7 +859,7 @@ static ngx_int_t ngx_http_waf_blocked_get_handler(ngx_http_request_t* r, ngx_htt v->data = NULL; } else { - if (ctx->blocked == TRUE) { + if (ctx->blocked == NGX_HTTP_WAF_TRUE) { v->len = 4; strcpy((char*)v->data, "true"); } @@ -734,7 +885,7 @@ static ngx_int_t ngx_http_waf_rule_type_get_handler(ngx_http_request_t* r, ngx_h v->data = NULL; } else { - if (ctx->blocked == TRUE) { + if (ctx->blocked == NGX_HTTP_WAF_TRUE) { #ifdef __STDC_LIB_EXT1__ v->len = strnlen_s((char*)ctx->rule_type, sizeof(ctx->rule_type)); #else @@ -770,7 +921,7 @@ static ngx_int_t ngx_http_waf_rule_deatils_handler(ngx_http_request_t* r, ngx_ht v->data = NULL; } else { - if (ctx->blocked == TRUE) { + if (ctx->blocked == NGX_HTTP_WAF_TRUE) { #ifdef __STDC_LIB_EXT1__ v->len = strnlen_s((char*)ctx->rule_deatils, sizeof(ctx->rule_deatils)); #else @@ -836,7 +987,7 @@ static ngx_int_t ngx_http_waf_shm_zone_cc_deny_init(ngx_shm_zone_t *zone, void * return NGX_ERROR; } if (ip_trie_init(srv_conf->ipv4_access_statistics, - slab_pool, shpool, AF_INET) != SUCCESS) { + slab_pool, shpool, AF_INET) != NGX_HTTP_WAF_SUCCESS) { return NGX_ERROR; } @@ -845,7 +996,7 @@ static ngx_int_t ngx_http_waf_shm_zone_cc_deny_init(ngx_shm_zone_t *zone, void * return NGX_ERROR; } if (ip_trie_init(srv_conf->ipv6_access_statistics, - slab_pool, shpool, AF_INET6) != SUCCESS) { + slab_pool, shpool, AF_INET6) != NGX_HTTP_WAF_SUCCESS) { return NGX_ERROR; } @@ -859,93 +1010,15 @@ static ngx_int_t ngx_http_waf_shm_zone_cc_deny_init(ngx_shm_zone_t *zone, void * } -static void ngx_http_waf_event_clear_ip_access_statistics_handler(ngx_event_t* event) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: The token bucket clearing process has been started."); - - ngx_http_waf_srv_conf_t* srv_conf = (ngx_http_waf_srv_conf_t*)event->data; - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: The configuration of the module has been obtained."); - - - ngx_slab_pool_t *shpool = (ngx_slab_pool_t *)srv_conf->shm_zone_cc_deny->shm.addr; - - ngx_shmtx_lock(&shpool->mutex); - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Shared memory is locked."); - - ip_trie_clear(srv_conf->ipv4_access_statistics); - ip_trie_clear(srv_conf->ipv6_access_statistics); - - ngx_shmtx_unlock(&shpool->mutex); - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Shared memory is unlocked."); - - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: The token bucket clearing process is all but complete."); -} - - -static void ngx_http_waf_event_eliminate_inspection_cache_handler(ngx_event_t* event) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: The batch cache elimination process has been activated."); - - ngx_http_waf_srv_conf_t* srv_conf = (ngx_http_waf_srv_conf_t*)event->data; - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: The configuration of the module has been obtained."); - - double percent = srv_conf->waf_eliminate_inspection_cache_percent / 100.0; - - - if (lru_cache_manager_eliminate_percent(&srv_conf->black_url_inspection_cache, percent) != SUCCESS) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Unable to clear cache from black_url_inspection_cache."); - } - - if (lru_cache_manager_eliminate_percent(&srv_conf->black_args_inspection_cache, percent) != SUCCESS) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Unable to clear cache from black_args_inspection_cache."); - } - - if (lru_cache_manager_eliminate_percent(&srv_conf->black_ua_inspection_cache, percent) != SUCCESS) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Unable to clear cache from black_ua_inspection_cache."); - } - - if (lru_cache_manager_eliminate_percent(&srv_conf->black_referer_inspection_cache, percent) != SUCCESS) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Unable to clear cache from black_referer_inspection_cache."); - } - - if (lru_cache_manager_eliminate_percent(&srv_conf->black_cookie_inspection_cache, percent) != SUCCESS) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Unable to clear cache from black_cookie_inspection_cache."); - } - - if (lru_cache_manager_eliminate_percent(&srv_conf->white_url_inspection_cache, percent) != SUCCESS) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Unable to clear cache from white_url_inspection_cache."); - } - - if (lru_cache_manager_eliminate_percent(&srv_conf->white_referer_inspection_cache, percent) != SUCCESS) { - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: Unable to clear cache from white_referer_inspection_cache."); - } - - ngx_log_debug(NGX_LOG_DEBUG_CORE, event->log, 0, - "ngx_waf_debug: The batch cache elimination process is all but complete."); -} - - static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void* container, ngx_int_t mode) { FILE* fp = fopen(file_name, "r"); ngx_int_t line_number = 0; ngx_str_t line; - char* str = ngx_palloc(cf->pool, sizeof(char) * RULE_MAX_LEN); + char* str = ngx_palloc(cf->pool, sizeof(char) * NGX_HTTP_WAF_RULE_MAX_LEN); if (fp == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } - while (fgets(str, RULE_MAX_LEN - 16, fp) != NULL) { + while (fgets(str, NGX_HTTP_WAF_RULE_MAX_LEN - 16, fp) != NULL) { ngx_regex_compile_t regex_compile; u_char errstr[NGX_MAX_CONF_ERRSTR]; ngx_regex_elt_t* ngx_regex_elt; @@ -956,7 +1029,7 @@ static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void ++line_number; line.data = (u_char*)str; #ifdef __STDC_LIB_EXT1__ - line.len = strnlen_s((char*)str. sizeof(char) * RULE_MAX_LEN); + line.len = strnlen_s((char*)str. sizeof(char) * NGX_HTTP_WAF_RULE_MAX_LEN); #else line.len = strlen((char*)str); #endif @@ -993,26 +1066,26 @@ static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void regex_compile.err.len = NGX_MAX_CONF_ERRSTR; regex_compile.err.data = errstr; if (ngx_regex_compile(®ex_compile) != NGX_OK) { - char temp[RULE_MAX_LEN] = { 0 }; + char temp[NGX_HTTP_WAF_RULE_MAX_LEN] = { 0 }; to_c_str((u_char*)temp, line); ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: In %s:%d, [%s] is not a valid regex string.", file_name, line_number, temp); - return FAIL; + return NGX_HTTP_WAF_FAIL; } ngx_regex_elt = ngx_array_push((ngx_array_t*)container); - ngx_regex_elt->name = ngx_palloc(cf->pool, sizeof(u_char) * RULE_MAX_LEN); + ngx_regex_elt->name = ngx_palloc(cf->pool, sizeof(u_char) * NGX_HTTP_WAF_RULE_MAX_LEN); to_c_str(ngx_regex_elt->name, line); ngx_regex_elt->regex = regex_compile.regex; break; case 1: - if (parse_ipv4(line, &ipv4) != SUCCESS) { + if (parse_ipv4(line, &ipv4) != NGX_HTTP_WAF_SUCCESS) { ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: In %s:%d, [%s] is not a valid IPV4 string.", file_name, line_number, ipv4.text); - return FAIL; + return NGX_HTTP_WAF_FAIL; } inx_addr.ipv4.s_addr = ipv4.prefix; - if (ip_trie_add((ip_trie_t*)container, &inx_addr, ipv4.suffix_num, ipv4.text, 32) != SUCCESS) { - if (ip_trie_find((ip_trie_t*)container, &inx_addr, &ip_trie_node) == SUCCESS) { + if (ip_trie_add((ip_trie_t*)container, &inx_addr, ipv4.suffix_num, ipv4.text, 32) != NGX_HTTP_WAF_SUCCESS) { + if (ip_trie_find((ip_trie_t*)container, &inx_addr, &ip_trie_node) == NGX_HTTP_WAF_SUCCESS) { ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: In %s:%d, the two address blocks [%s] and [%s] have overlapping parts.", file_name, line_number, ipv4.text, ip_trie_node->data); @@ -1020,20 +1093,20 @@ static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: In %s:%d, [%s] cannot be stored because the memory allocation failed.", file_name, line_number, ipv4.text); - return FAIL; + return NGX_HTTP_WAF_FAIL; } } break; case 2: - if (parse_ipv6(line, &ipv6) != SUCCESS) { + if (parse_ipv6(line, &ipv6) != NGX_HTTP_WAF_SUCCESS) { ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: In %s:%d, [%s] is not a valid IPV6 string.", file_name, line_number, ipv6.text); - return FAIL; + return NGX_HTTP_WAF_FAIL; } ngx_memcpy(inx_addr.ipv6.s6_addr, ipv6.prefix, 16); - if (ip_trie_add((ip_trie_t*)container, &inx_addr, ipv6.suffix_num, ipv6.text, 64) != SUCCESS) { - if (ip_trie_find((ip_trie_t*)container, &inx_addr, &ip_trie_node) == SUCCESS) { + if (ip_trie_add((ip_trie_t*)container, &inx_addr, ipv6.suffix_num, ipv6.text, 64) != NGX_HTTP_WAF_SUCCESS) { + if (ip_trie_find((ip_trie_t*)container, &inx_addr, &ip_trie_node) == NGX_HTTP_WAF_SUCCESS) { ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: In %s:%d, the two address blocks [%s] and [%s] have overlapping parts.", file_name, line_number, ipv6.text, ip_trie_node->data); @@ -1041,7 +1114,7 @@ static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: In %s:%d, [%s] cannot be stored because the memory allocation failed.", file_name, line_number, ipv6.text); - return FAIL; + return NGX_HTTP_WAF_FAIL; } } break; @@ -1049,7 +1122,7 @@ static ngx_int_t load_into_container(ngx_conf_t* cf, const char* file_name, void } fclose(fp); ngx_pfree(cf->pool, str); - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } #endif // !NGX_HTTP_WAF_MODULE_CONFIG_H diff --git a/inc/ngx_http_waf_module_core.h b/inc/ngx_http_waf_module_core.h index 976ecc89..fd6a5995 100644 --- a/inc/ngx_http_waf_module_core.h +++ b/inc/ngx_http_waf_module_core.h @@ -33,16 +33,25 @@ */ static ngx_int_t ngx_http_waf_handler_server_rewrite_phase(ngx_http_request_t* r); + /** * @brief NGX_HTTP_ACCESS_PHASE 阶段的处理函数 */ static ngx_int_t ngx_http_waf_handler_access_phase(ngx_http_request_t* r); + /** * @brief 启动内存整理事件 */ static void ngx_http_waf_trigger_mem_collation_event(ngx_http_request_t* r); + +static void ngx_http_waf_clear_ip_access_statistics(ngx_http_request_t* r); + + +static void ngx_http_waf_eliminate_inspection_cache(ngx_http_request_t* r); + + /** * @brief 执行全部的检查项目 * @param r 本次要处理的请求 diff --git a/inc/ngx_http_waf_module_ip_trie.h b/inc/ngx_http_waf_module_ip_trie.h index e1f4be91..f63baa42 100644 --- a/inc/ngx_http_waf_module_ip_trie.h +++ b/inc/ngx_http_waf_module_ip_trie.h @@ -21,21 +21,18 @@ * @param[out] trie 要初始化的前缀树。 * @param[in] memory_pool 初始化、添加、删除节点所用的内存池。 * @param[in] ip_type 存储的 IP 地址类型。 - * @return 返回 SUCCESS 表示初始化成功,反之为 FAIL。 - * @retval SUCCESS 初始化成功。 - * @retval FAIL 初始化失败。 + * @return 返回 NGX_HTTP_WAF_SUCCESS 表示初始化成功,反之为 NGX_HTTP_WAF_FAIL。 */ static ngx_int_t ip_trie_init(ip_trie_t* trie, mem_pool_type_e pool_type, void* native_pool, int ip_type); + /** * @brief 插入一个 IP 地址。 * @param[in] trie 要操作的前缀树。 * @param[in] inx_addr IP 地址。 * @param[in] suffix_num IP 网段长度。 * @param[in] text IP 的字符串形式。 - * @return 返回 SUCCESS 表示成功,反之为 FAIL。 - * @retval SUCCESS 成功。 - * @retval FAIL 失败。 + * @return 返回 NGX_HTTP_WAF_SUCCESS 表示成功,反之为 NGX_HTTP_WAF_FAIL。 */ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suffix_num, void* data, size_t data_byte_length); @@ -44,9 +41,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf * @param[in] trie 要操作的前缀树。 * @param[in] inx_addr IP 地址。 * @param[out] ip_trie_node 找到之后此指针将指向对应的节点。 - * @return 返回 SUCCESS 表示找到,反之为 FAIL。 - * @retval SUCCESS 找到。 - * @retval FAIL 没找到。 + * @return 返回 NGX_HTTP_WAF_SUCCESS 表示找到,反之为 FAIL。 */ static ngx_int_t ip_trie_find(ip_trie_t* trie, inx_addr_t* inx_addr, ip_trie_node_t** ip_trie_node); @@ -54,7 +49,7 @@ static ngx_int_t ip_trie_find(ip_trie_t* trie, inx_addr_t* inx_addr, ip_trie_nod * @brief 删除一个 IP 地址。 * @param[in] trie 要操作的前缀树。 * @param[in] inx_addr IP 地址。 - * @return 成功返回 SUCCESS,反之则不是 + * @return 成功返回 NGX_HTTP_WAF_SUCCESS,反之则不是 * @warning 不会释放节点所在占用的内存,但是会释放节点的 data 域所指向的内存。 */ // static ngx_int_t ip_trie_delete(ip_trie_t* trie, inx_addr_t* inx_addr); @@ -62,7 +57,7 @@ static ngx_int_t ip_trie_find(ip_trie_t* trie, inx_addr_t* inx_addr, ip_trie_nod /** * @brief 清空整个树,除根节点以外的全部节点的内存和 data 域指向的内存。 * @param[in] trie 要操作的前缀树。 - * @return 成功返回 SUCCESS,反之则不是 + * @return 成功返回 NGX_HTTP_WAF_SUCCESS,反之则不是 */ static ngx_int_t ip_trie_clear(ip_trie_t* trie); @@ -81,12 +76,12 @@ static void _ip_trie_traversal(ip_trie_node_t* node, singly_linked_list_t** head static ngx_int_t ip_trie_init(ip_trie_t* trie, mem_pool_type_e pool_type, void* native_pool, int ip_type) { if (trie == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } - if (mem_pool_init(&trie->pool, pool_type, native_pool) != SUCCESS) { - return FAIL; + if (mem_pool_init(&trie->pool, pool_type, native_pool) != NGX_HTTP_WAF_SUCCESS) { + return NGX_HTTP_WAF_FAIL; } trie->ip_type = ip_type; @@ -94,35 +89,35 @@ static ngx_int_t ip_trie_init(ip_trie_t* trie, mem_pool_type_e pool_type, void* trie->size = 0; if (trie->root == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suffix_num, void* data, size_t data_byte_length) { if (trie == NULL || inx_addr == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } ip_trie_node_t* new_node = NULL; - if (ip_trie_find(trie, inx_addr, &new_node) == SUCCESS) { - return FAIL; + if (ip_trie_find(trie, inx_addr, &new_node) == NGX_HTTP_WAF_SUCCESS) { + return NGX_HTTP_WAF_FAIL; } new_node = (ip_trie_node_t*)mem_pool_calloc(&trie->pool, sizeof(ip_trie_node_t)); if (new_node == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } new_node->data = mem_pool_calloc(&trie->pool, data_byte_length); if (new_node->data == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } - new_node->is_ip = TRUE; + new_node->is_ip = NGX_HTTP_WAF_TRUE; ngx_memcpy(new_node->data, data, data_byte_length); ip_trie_node_t* prev_node = trie->root; @@ -142,7 +137,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf if (cur_node == NULL) { cur_node = (ip_trie_node_t*)mem_pool_calloc(&trie->pool, sizeof(ip_trie_node_t)); if (cur_node == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } if (prev_bit == 0) { prev_node->left = cur_node; @@ -151,7 +146,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf } } prev_node = cur_node; - if (CHECK_BIT(u8_addr[uint8_index], 7 - (bit_index % 8)) != TRUE) { + if (NGX_HTTP_WAF_CHECK_BIT(u8_addr[uint8_index], 7 - (bit_index % 8)) != NGX_HTTP_WAF_TRUE) { prev_bit = 0; cur_node = cur_node->left; } else { @@ -163,7 +158,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf if (cur_node == NULL) { cur_node = (ip_trie_node_t*)mem_pool_calloc(&trie->pool, sizeof(ip_trie_node_t)); if (cur_node == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } if (prev_bit == 0) { prev_node->left = cur_node; @@ -172,7 +167,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf } } uint8_index = bit_index / 8; - if (CHECK_BIT(u8_addr[uint8_index], 7 - (bit_index % 8)) != TRUE) { + if (NGX_HTTP_WAF_CHECK_BIT(u8_addr[uint8_index], 7 - (bit_index % 8)) != NGX_HTTP_WAF_TRUE) { cur_node->left = new_node; } else { cur_node->right = new_node; @@ -184,7 +179,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf if (cur_node == NULL) { cur_node = (ip_trie_node_t*)mem_pool_calloc(&trie->pool, sizeof(ip_trie_node_t)); if (cur_node == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } if (prev_bit == 0) { prev_node->left = cur_node; @@ -193,7 +188,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf } } prev_node = cur_node; - if (CHECK_BIT(inx_addr->ipv6.s6_addr[uint8_index], 7 - (bit_index % 8)) != TRUE) { + if (NGX_HTTP_WAF_CHECK_BIT(inx_addr->ipv6.s6_addr[uint8_index], 7 - (bit_index % 8)) != NGX_HTTP_WAF_TRUE) { cur_node = cur_node->left; prev_bit = 0; } else { @@ -205,7 +200,7 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf if (cur_node == NULL) { cur_node = (ip_trie_node_t*)mem_pool_calloc(&trie->pool, sizeof(ip_trie_node_t)); if (cur_node == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } if (prev_bit == 0) { prev_node->left = cur_node; @@ -214,26 +209,26 @@ static ngx_int_t ip_trie_add(ip_trie_t* trie, inx_addr_t* inx_addr, uint32_t suf } } uint8_index = bit_index / 8; - if (CHECK_BIT(inx_addr->ipv6.s6_addr[uint8_index], 7 - (bit_index % 8)) != TRUE) { + if (NGX_HTTP_WAF_CHECK_BIT(inx_addr->ipv6.s6_addr[uint8_index], 7 - (bit_index % 8)) != NGX_HTTP_WAF_TRUE) { cur_node->left = new_node; } else { cur_node->right = new_node; } } - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } static ngx_int_t ip_trie_find(ip_trie_t* trie, inx_addr_t* inx_addr, ip_trie_node_t** ip_trie_node) { if (trie == NULL || inx_addr == NULL || ip_trie_node ==NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } *ip_trie_node = NULL; ip_trie_node_t* cur_node = trie->root; - ngx_int_t is_found = FAIL; + ngx_int_t is_found = NGX_HTTP_WAF_FAIL; uint32_t bit_index = 0; if (trie->ip_type == AF_INET) { @@ -243,9 +238,9 @@ static ngx_int_t ip_trie_find(ip_trie_t* trie, inx_addr_t* inx_addr, ip_trie_nod u8_addr[2] = (uint8_t)((inx_addr->ipv4.s_addr & 0x00ff0000) >> 16); u8_addr[3] = (uint8_t)((inx_addr->ipv4.s_addr & 0xff000000) >> 24); - while (bit_index < 32 && cur_node != NULL && cur_node->is_ip != TRUE) { + while (bit_index < 32 && cur_node != NULL && cur_node->is_ip != NGX_HTTP_WAF_TRUE) { int uint8_index = bit_index / 8; - if (CHECK_BIT(u8_addr[uint8_index], 7 - (bit_index % 8)) != TRUE) { + if (NGX_HTTP_WAF_CHECK_BIT(u8_addr[uint8_index], 7 - (bit_index % 8)) != NGX_HTTP_WAF_TRUE) { cur_node = cur_node->left; } else { cur_node = cur_node->right; @@ -254,9 +249,9 @@ static ngx_int_t ip_trie_find(ip_trie_t* trie, inx_addr_t* inx_addr, ip_trie_nod } } else if (trie->ip_type == AF_INET6) { - while (bit_index < 128 && cur_node != NULL && cur_node->is_ip != TRUE) { + while (bit_index < 128 && cur_node != NULL && cur_node->is_ip != NGX_HTTP_WAF_TRUE) { int uint8_index = bit_index / 8; - if (CHECK_BIT(inx_addr->ipv6.s6_addr[uint8_index], 7 - (bit_index % 8)) != TRUE) { + if (NGX_HTTP_WAF_CHECK_BIT(inx_addr->ipv6.s6_addr[uint8_index], 7 - (bit_index % 8)) != NGX_HTTP_WAF_TRUE) { cur_node = cur_node->left; } else { cur_node = cur_node->right; @@ -265,8 +260,8 @@ static ngx_int_t ip_trie_find(ip_trie_t* trie, inx_addr_t* inx_addr, ip_trie_nod } } - if (cur_node != NULL && cur_node->is_ip == TRUE) { - is_found = SUCCESS; + if (cur_node != NULL && cur_node->is_ip == NGX_HTTP_WAF_TRUE) { + is_found = NGX_HTTP_WAF_SUCCESS; *ip_trie_node = cur_node; } @@ -323,7 +318,7 @@ static ngx_int_t ip_trie_clear(ip_trie_t* trie) { trie->root->left = NULL; trie->root->right = NULL; - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } diff --git a/inc/ngx_http_waf_module_lru_cache.h b/inc/ngx_http_waf_module_lru_cache.h index cb8bf9a5..7db76f33 100644 --- a/inc/ngx_http_waf_module_lru_cache.h +++ b/inc/ngx_http_waf_module_lru_cache.h @@ -15,13 +15,14 @@ * @param[out] manager 要初始化的 LRU 缓存管理器 * @param[in] pool_type 所使用的内存池的类型 * @param[in] native_pool 要使用的内存池的指针 - * @return 如果成功则返回 SUCCESS,反之则不是。 + * @return 如果成功则返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 */ static ngx_int_t lru_cache_manager_init(lru_cache_manager_t* manager, ngx_uint_t capacity, mem_pool_type_e pool_type, void* native_pool); + /** * @brief 添加一个缓存项 * @param[in] manager 要操作的 LRU 缓存管理器 @@ -29,7 +30,7 @@ static ngx_int_t lru_cache_manager_init(lru_cache_manager_t* manager, * @param[in] key_byte_length 关键字占用的字节数 * @param[in] match_status 要缓存的规则匹配结果 * @param[in] rule_detail 要缓存的被匹配的规则的细节 - * @return 如果成功则返回 SUCCESS,反之则不是。 + * @return 如果成功则返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 * @note 如果内存不足会按照 LRU 策略自动淘汰其它缓存项。 * @note 如果关键字已经存在则什么都不做,返回 SUCCESS。 */ @@ -39,6 +40,7 @@ static ngx_int_t lru_cache_manager_add( lru_cache_manager_t* manager, ngx_int_t match_status, u_char* rule_detail); + /** * @brief 查询缓存项 * @param[in] manager 要操作的 LRU 缓存管理器 @@ -46,7 +48,7 @@ static ngx_int_t lru_cache_manager_add( lru_cache_manager_t* manager, * @param[in] key_byte_length 关键字占用的字节数 * @param[in] out_match_status 被缓存的规则匹配结果 * @param[in] out_rule_detail 被缓存的被匹配的规则的细节 - * @return 如果缓存项存在则返回 SUCCESS,反之则不是。 + * @return 如果缓存项存在则返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 */ static ngx_int_t lru_cache_manager_find(lru_cache_manager_t* manager, u_char* key, @@ -60,24 +62,26 @@ static ngx_int_t lru_cache_manager_find(lru_cache_manager_t* manager, * @param[in] manager 要操作的 LRU 缓存管理器 * @param[in] u_char 用于查询缓存的关键字指针 * @param[in] key_byte_length 关键字占用的字节数 - * @return 如果缓存项存在则返回 SUCCESS,反之则不是。 + * @return 如果缓存项存在则返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 */ static ngx_int_t lru_cache_manager_remove( lru_cache_manager_t* manager, u_char* key, ngx_uint_t key_byte_length); + /** * @brief 按照 LRU 策略淘汰掉一个缓存项 * @param[in] manager 要操作的 LRU 缓存管理器 - * @return 如果淘汰成功则返回 SUCCESS,反之则不是。 + * @return 如果淘汰成功则返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 */ static ngx_int_t lru_cache_manager_eliminate(lru_cache_manager_t* manager); + /** * @brief 按照 LRU 策略淘汰掉一定百分比的缓存项 * @param[in] manager 要操作的 LRU 缓存管理器 * @param[in] percent 要淘汰掉的缓存项所占总量的百分比 - * @return 如果淘汰成功则返回 SUCCESS,反之则不是。 + * @return 如果淘汰成功则返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 * @warning 此函数无论成功与否都会清零 eliminate_times 字段。 */ static ngx_int_t lru_cache_manager_eliminate_percent(lru_cache_manager_t* manager, double percent); @@ -92,11 +96,11 @@ static ngx_int_t lru_cache_manager_init(lru_cache_manager_t* manager, mem_pool_type_e pool_type, void* native_pool) { if (manager == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } - if (mem_pool_init(&(manager->pool), pool_type, native_pool) != SUCCESS) { - return FAIL; + if (mem_pool_init(&(manager->pool), pool_type, native_pool) != NGX_HTTP_WAF_SUCCESS) { + return NGX_HTTP_WAF_FAIL; } manager->last_eliminate = time(NULL); @@ -105,7 +109,7 @@ static ngx_int_t lru_cache_manager_init(lru_cache_manager_t* manager, manager->hash_head = NULL; manager->chain_head = NULL; - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } static ngx_int_t lru_cache_manager_add( lru_cache_manager_t* manager, @@ -114,58 +118,60 @@ static ngx_int_t lru_cache_manager_add( lru_cache_manager_t* manager, ngx_int_t match_status, u_char* rule_detail) { if (manager == NULL || key == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } lru_cache_item_t* hash_item = NULL; HASH_FIND(hh, manager->hash_head, key, key_byte_length, hash_item); if (hash_item != NULL) { - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } hash_item = NULL; lru_cache_item_t* chain_item = NULL; while (manager->size + 1 > manager->capacity) { - if (lru_cache_manager_eliminate(manager) != SUCCESS) { - return FAIL; + if (lru_cache_manager_eliminate(manager) != NGX_HTTP_WAF_SUCCESS) { + return NGX_HTTP_WAF_FAIL; } } do { chain_item = (lru_cache_item_t*)mem_pool_calloc(&(manager->pool), sizeof(lru_cache_item_t)); - if (chain_item == NULL && lru_cache_manager_eliminate(manager) == FAIL) { - return FAIL; + if (chain_item == NULL && lru_cache_manager_eliminate(manager) == NGX_HTTP_WAF_FAIL) { + return NGX_HTTP_WAF_FAIL; } } while (chain_item == NULL); do { hash_item = (lru_cache_item_t*)mem_pool_calloc(&(manager->pool), sizeof(lru_cache_item_t)); - if (hash_item == NULL && lru_cache_manager_eliminate(manager) == FAIL) { - return FAIL; + if (hash_item == NULL && lru_cache_manager_eliminate(manager) == NGX_HTTP_WAF_FAIL) { + return NGX_HTTP_WAF_FAIL; } } while (hash_item == NULL); u_char* key_copy = NULL; do { key_copy = (u_char*)mem_pool_calloc(&(manager->pool), key_byte_length); - if (key_copy == NULL && lru_cache_manager_eliminate(manager) == FAIL) { - return FAIL; + if (key_copy == NULL && lru_cache_manager_eliminate(manager) == NGX_HTTP_WAF_FAIL) { + return NGX_HTTP_WAF_FAIL; } } while (key_copy == NULL); ngx_memcpy(key_copy, key, key_byte_length); chain_item->key = key_copy; + chain_item->key_byte_length = key_byte_length; chain_item->value.value.match_status = match_status; chain_item->value.value.rule_detail = rule_detail; hash_item->key = key_copy; + hash_item->key_byte_length = key_byte_length; hash_item->value.chain_item = chain_item; CDL_PREPEND(manager->chain_head, chain_item); HASH_ADD_KEYPTR(hh, manager->hash_head, key_copy, key_byte_length, hash_item); ++(manager->size); - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } @@ -175,13 +181,13 @@ static ngx_int_t lru_cache_manager_find(lru_cache_manager_t* manager, ngx_int_t* out_match_status, u_char** out_rule_detail) { if (manager == NULL || key == NULL || out_match_status == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } lru_cache_item_t* hash_item = NULL; HASH_FIND(hh, manager->hash_head, key, key_byte_length, hash_item); if (hash_item == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } lru_cache_item_t* chain_item = hash_item->value.chain_item; @@ -191,7 +197,7 @@ static ngx_int_t lru_cache_manager_find(lru_cache_manager_t* manager, CDL_DELETE(manager->chain_head, chain_item); CDL_PREPEND(manager->chain_head, chain_item); - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } @@ -200,33 +206,33 @@ static ngx_int_t lru_cache_manager_remove( lru_cache_manager_t* manager, u_char* key, ngx_uint_t key_byte_length) { if (manager == NULL || key == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } lru_cache_item_t* hash_item = NULL; HASH_FIND(hh, manager->hash_head, key, key_byte_length, hash_item); if (hash_item == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } HASH_DELETE(hh, manager->hash_head, hash_item); lru_cache_item_t* chain_item = hash_item->value.chain_item; CDL_DELETE(manager->chain_head, chain_item); - if ( mem_pool_free(&(manager->pool), chain_item->key) != SUCCESS - || mem_pool_free(&(manager->pool), hash_item) != SUCCESS - || mem_pool_free(&(manager->pool), chain_item) != SUCCESS) { - return FAIL; + if ( mem_pool_free(&(manager->pool), chain_item->key) != NGX_HTTP_WAF_SUCCESS + || mem_pool_free(&(manager->pool), hash_item) != NGX_HTTP_WAF_SUCCESS + || mem_pool_free(&(manager->pool), chain_item) != NGX_HTTP_WAF_SUCCESS) { + return NGX_HTTP_WAF_FAIL; } --(manager->size); - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } static ngx_int_t lru_cache_manager_eliminate(lru_cache_manager_t* manager) { if (manager == NULL || manager->chain_head == NULL || manager->hash_head == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } lru_cache_item_t* chain_tail = manager->chain_head->prev; @@ -239,19 +245,19 @@ static ngx_int_t lru_cache_manager_eliminate(lru_cache_manager_t* manager) { static ngx_int_t lru_cache_manager_eliminate_percent(lru_cache_manager_t* manager, double percent) { if (manager == NULL || percent > 1.0) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } ngx_uint_t target_size = (ngx_uint_t)((double)(manager->size) * (1.0 - percent)); while (manager->size > target_size) { ngx_int_t ret = lru_cache_manager_eliminate(manager); - if (ret != SUCCESS) { + if (ret != NGX_HTTP_WAF_SUCCESS) { return ret; } } - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } // static void lru_cache_manager_clear(lru_cache_manager_t* manager) { diff --git a/inc/ngx_http_waf_module_macro.h b/inc/ngx_http_waf_module_macro.h index 5da03d9d..4512512d 100644 --- a/inc/ngx_http_waf_module_macro.h +++ b/inc/ngx_http_waf_module_macro.h @@ -7,322 +7,306 @@ #define NGX_HTTP_WAF_MODULE_MACRO_H /* 对应配置文件的文件名 */ -#define IPV4_FILE ("ipv4") -#define IPV6_FILE ("ipv6") -#define URL_FILE ("url") -#define ARGS_FILE ("args") -#define UA_FILE ("user-agent") -#define REFERER_FILE ("referer") -#define COOKIE_FILE ("cookie") -#define POST_FILE ("post") -#define WHITE_IPV4_FILE ("white-ipv4") -#define WHITE_IPV6_FILE ("white-ipv6") -#define WHITE_URL_FILE ("white-url") -#define WHITE_REFERER_FILE ("white-referer") +#define NGX_HTTP_WAF_IPV4_FILE ("ipv4") +#define NGX_HTTP_WAF_IPV6_FILE ("ipv6") +#define NGX_HTTP_WAF_URL_FILE ("url") +#define NGX_HTTP_WAF_ARGS_FILE ("args") +#define NGX_HTTP_WAF_UA_FILE ("user-agent") +#define NGX_HTTP_WAF_REFERER_FILE ("referer") +#define NGX_HTTP_WAF_COOKIE_FILE ("cookie") +#define NGX_HTTP_WAF_POST_FILE ("post") +#define NGX_HTTP_WAF_WHITE_IPV4_FILE ("white-ipv4") +#define NGX_HTTP_WAF_WHITE_IPV6_FILE ("white-ipv6") +#define NGX_HTTP_WAF_WHITE_URL_FILE ("white-url") +#define NGX_HTTP_WAF_WHITE_REFERER_FILE ("white-referer") -#ifndef FALSE -#define FALSE (0) -#endif +#define NGX_HTTP_WAF_FALSE (0) -#ifndef FAIL -#define FAIL (0) -#endif +#define NGX_HTTP_WAF_FAIL (0) -#ifndef NOT_MATCHED -#define NOT_MATCHED (0) -#endif +#define NGX_HTTP_WAF_NOT_MATCHED (0) -#ifndef TRUE -#define TRUE (1) -#endif +#define NGX_HTTP_WAF_TRUE (1) -#ifndef SUCCESS -#define SUCCESS (1) -#endif +#define NGX_HTTP_WAF_SUCCESS (1) -#ifndef MATCHED -#define MATCHED (1) -#endif +#define NGX_HTTP_WAF_MATCHED (1) -#ifndef PROCESSING -#define PROCESSING (2) -#endif +#define NGX_HTTP_WAF_PROCESSING (2) -#ifndef MALLOC_ERROR -#define MALLOC_ERROR (3) -#endif +#define NGX_HTTP_WAF_MALLOC_ERROR (3) /** - * @def RULE_MAX_LEN + * @def NGX_HTTP_WAF_RULE_MAX_LEN * @brief 每条规则的占用的最大字节数。 */ -#define RULE_MAX_LEN (256 * 4 * 8) +#define NGX_HTTP_WAF_RULE_MAX_LEN (256 * 4 * 8) /** - * @def INITIAL_SIZE + * @def NGX_HTTP_WAF_INITIAL_SIZE * @brief 初始化配置块内存池时的初始内存池大小。 */ -#define INITIAL_SIZE (1024 * 1024 * 5) +#define NGX_HTTP_WAF_INITIAL_SIZE (1024 * 1024 * 5) -#define MAX_ALLOC_TIMES (100000) +#define NGX_HTTP_WAF_MAX_ALLOC_TIMES (100000) /** - * @def SHARE_MEMORY_NAME + * @def NGX_HTTP_WAF_SHARE_MEMORY_NAME * @brief 用于 CC 防护的共享内存的名称 */ -#define SHARE_MEMORY_CC_DNEY_NAME ("__ADD-SP_NGX_WAF_CC_DENY_SHM__") +#define NGX_HTTP_WAF_SHARE_MEMORY_CC_DNEY_NAME ("__ADD-SP_NGX_WAF_CC_DENY_SHM__") /** - * @def SHATE_MEMORY_CC_DENY_MIN_SIZE + * @def NGX_HTTP_WAF_SHATE_MEMORY_CC_DENY_MIN_SIZE * @brief 用于 CC 防护的共享内存的最小大小(字节) */ -#define SHARE_MEMORY_CC_DENY_MIN_SIZE (1024 * 1024 * 20) +#define NGX_HTTP_WAF_SHARE_MEMORY_CC_DENY_MIN_SIZE (1024 * 1024 * 20) /** * @def CACHE_ITEM_MIN_SIZE * @brief 用于设置缓存项数的上限 */ -#define CACHE_ITEM_MIN_NUM (50) +#define NGX_HTTP_WAF_CACHE_ITEM_MIN_NUM (50) /** - * @def MODE_INSPECT_GET + * @def NGX_HTTP_WAF_MODE_INSPECT_GET * @brief 对 GET 请求进行检查 */ -#define MODE_INSPECT_GET NGX_HTTP_GET +#define NGX_HTTP_WAF_MODE_INSPECT_GET NGX_HTTP_GET /** - * @def MODE_INSPECT_HEAD + * @def NGX_HTTP_WAF_MODE_INSPECT_HEAD * @brief 对 HEAD 请求进行检查 */ -#define MODE_INSPECT_HEAD NGX_HTTP_HEAD +#define NGX_HTTP_WAF_MODE_INSPECT_HEAD NGX_HTTP_HEAD /** - * @def MODE_INSPECT_POST + * @def NGX_HTTP_WAF_MODE_INSPECT_POST * @brief 对 POST 请求进行检查 */ -#define MODE_INSPECT_POST NGX_HTTP_POST +#define NGX_HTTP_WAF_MODE_INSPECT_POST NGX_HTTP_POST /** - * @def MODE_INSPECT_PUT + * @def NGX_HTTP_WAF_MODE_INSPECT_PUT * @brief 对 PUT 请求进行检查 */ -#define MODE_INSPECT_PUT NGX_HTTP_PUT +#define NGX_HTTP_WAF_MODE_INSPECT_PUT NGX_HTTP_PUT /** - * @def MODE_INSPECT_DELETE + * @def NGX_HTTP_WAF_MODE_INSPECT_DELETE * @brief 对 DELETE 请求进行检查 */ -#define MODE_INSPECT_DELETE NGX_HTTP_DELETE +#define NGX_HTTP_WAF_MODE_INSPECT_DELETE NGX_HTTP_DELETE /** - * @def MODE_INSPECT_MKCOL + * @def NGX_HTTP_WAF_MODE_INSPECT_MKCOL * @brief 对 MKCOL 请求进行检查 */ -#define MODE_INSPECT_MKCOL NGX_HTTP_MKCOL +#define NGX_HTTP_WAF_MODE_INSPECT_MKCOL NGX_HTTP_MKCOL /** - * @def MODE_INSPECT_COPY + * @def NGX_HTTP_WAF_MODE_INSPECT_COPY * @brief 对 COPY 请求进行检查 */ -#define MODE_INSPECT_COPY NGX_HTTP_COPY +#define NGX_HTTP_WAF_MODE_INSPECT_COPY NGX_HTTP_COPY /** - * @def MODE_INSPECT_MOVE + * @def NGX_HTTP_WAF_MODE_INSPECT_MOVE * @brief 对 MOVE 请求进行检查 */ -#define MODE_INSPECT_MOVE NGX_HTTP_MOVE +#define NGX_HTTP_WAF_MODE_INSPECT_MOVE NGX_HTTP_MOVE /** - * @def MODE_INSPECT_OPTIONS + * @def NGX_HTTP_WAF_MODE_INSPECT_OPTIONS * @brief 对 OPTIONS 请求进行检查 */ -#define MODE_INSPECT_OPTIONS NGX_HTTP_OPTIONS +#define NGX_HTTP_WAF_MODE_INSPECT_OPTIONS NGX_HTTP_OPTIONS /** - * @def MODE_INSPECT_PROPFIND + * @def NGX_HTTP_WAF_MODE_INSPECT_PROPFIND * @brief 对 PROPFIND 请求进行检查 */ -#define MODE_INSPECT_PROPFIND NGX_HTTP_PROPFIND +#define NGX_HTTP_WAF_MODE_INSPECT_PROPFIND NGX_HTTP_PROPFIND /** - * @def MODE_INSPECT_PROPPATCH + * @def NGX_HTTP_WAF_MODE_INSPECT_PROPPATCH * @brief 对 PROPPATCH 请求进行检查 */ -#define MODE_INSPECT_PROPPATCH NGX_HTTP_PROPPATCH +#define NGX_HTTP_WAF_MODE_INSPECT_PROPPATCH NGX_HTTP_PROPPATCH /** - * @def MODE_INSPECT_LOCK + * @def NGX_HTTP_WAF_MODE_INSPECT_LOCK * @brief 对 LOCK 请求进行检查 */ -#define MODE_INSPECT_LOCK NGX_HTTP_LOCK +#define NGX_HTTP_WAF_MODE_INSPECT_LOCK NGX_HTTP_LOCK /** - * @def MODE_INSPECT_UNLOCK + * @def NGX_HTTP_WAF_MODE_INSPECT_UNLOCK * @brief 对 UNLOCK 请求进行检查 */ -#define MODE_INSPECT_UNLOCK NGX_HTTP_UNLOCK +#define NGX_HTTP_WAF_MODE_INSPECT_UNLOCK NGX_HTTP_UNLOCK /** - * @def MODE_INSPECT_PATCH + * @def NGX_HTTP_WAF_MODE_INSPECT_PATCH * @brief 对 PATCH 请求进行检查 */ -#define MODE_INSPECT_PATCH NGX_HTTP_PATCH +#define NGX_HTTP_WAF_MODE_INSPECT_PATCH NGX_HTTP_PATCH /** - * @def MODE_INSPECT_TRACE + * @def NGX_HTTP_WAF_MODE_INSPECT_TRACE * @brief 对 TRACE 请求进行检查 */ -#define MODE_INSPECT_TRACE NGX_HTTP_TRACE +#define NGX_HTTP_WAF_MODE_INSPECT_TRACE NGX_HTTP_TRACE /** - * @def MODE_INSPECT_IP + * @def NGX_HTTP_WAF_MODE_INSPECT_IP * @brief 启用 IP 检查规则 */ -#define MODE_INSPECT_IP (MODE_INSPECT_TRACE << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_IP (NGX_HTTP_WAF_MODE_INSPECT_TRACE << 1) /** - * @def MODE_INSPECT_URL + * @def NGX_HTTP_WAF_MODE_INSPECT_URL * @brief 启用 URL 检查规则 */ -#define MODE_INSPECT_URL (MODE_INSPECT_IP << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_URL (NGX_HTTP_WAF_MODE_INSPECT_IP << 1) /** - * @def MODE_INSPECT_RB + * @def NGX_HTTP_WAF_MODE_INSPECT_RB * @brief 启用 Request Body 检查规则 */ -#define MODE_INSPECT_RB (MODE_INSPECT_URL << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_RB (NGX_HTTP_WAF_MODE_INSPECT_URL << 1) /** - * @def MODE_INSPECT_ARGS + * @def NGX_HTTP_WAF_MODE_INSPECT_ARGS * @brief 启用 ARGS(GET 请求参数) 检查规则 */ -#define MODE_INSPECT_ARGS (MODE_INSPECT_RB << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_ARGS (NGX_HTTP_WAF_MODE_INSPECT_RB << 1) /** - * @def MODE_INSPECT_UA + * @def NGX_HTTP_WAF_MODE_INSPECT_UA * @brief 启用 UserAgent 检查规则 */ -#define MODE_INSPECT_UA (MODE_INSPECT_ARGS << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_UA (NGX_HTTP_WAF_MODE_INSPECT_ARGS << 1) /** - * @def MODE_INSPECT_COOKIE + * @def NGX_HTTP_WAF_MODE_INSPECT_COOKIE * @brief 启用 COOKIE 检查规则 */ -#define MODE_INSPECT_COOKIE (MODE_INSPECT_UA << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_COOKIE (NGX_HTTP_WAF_MODE_INSPECT_UA << 1) /** - * @def MODE_INSPECT_REFERER + * @def NGX_HTTP_WAF_MODE_INSPECT_REFERER * @brief 启用 Referer 检查规则 */ -#define MODE_INSPECT_REFERER (MODE_INSPECT_COOKIE << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_REFERER (NGX_HTTP_WAF_MODE_INSPECT_COOKIE << 1) /** - * @def MODE_INSPECT_CC + * @def NGX_HTTP_WAF_MODE_INSPECT_CC * @brief 启用 CC 防御 */ -#define MODE_INSPECT_CC (MODE_INSPECT_REFERER << 1) +#define NGX_HTTP_WAF_MODE_INSPECT_CC (NGX_HTTP_WAF_MODE_INSPECT_REFERER << 1) /** - * @def MODE_EXTRA_COMPAT + * @def NGX_HTTP_WAF_MODE_EXTRA_COMPAT * @brief 兼容模式,启用一些兼容性功能。 */ -#define MODE_EXTRA_COMPAT (MODE_INSPECT_CC << 1) +#define NGX_HTTP_WAF_MODE_EXTRA_COMPAT (NGX_HTTP_WAF_MODE_INSPECT_CC << 1) /** - * @def MODE_EXTRA_STRICT + * @def NGX_HTTP_WAF_MODE_EXTRA_STRICT * @brief 严格模式,牺牲一些性能进行更多的检查,但是花费的时间不会发生数量级上的变化。 */ -#define MODE_EXTRA_STRICT (MODE_EXTRA_COMPAT << 1) +#define NGX_HTTP_WAF_MODE_EXTRA_STRICT (NGX_HTTP_WAF_MODE_EXTRA_COMPAT << 1) /** - * @def MODE_EXTRA_CACHE + * @def NGX_HTTP_WAF_MODE_EXTRA_CACHE * @brief 启用缓存,但是不缓存 POST 检查。 */ -#define MODE_EXTRA_CACHE (MODE_EXTRA_STRICT << 1) +#define NGX_HTTP_WAF_MODE_EXTRA_CACHE (NGX_HTTP_WAF_MODE_EXTRA_STRICT << 1) /** * @def MODE_STD * @brief 标准工作模式 */ -#define MODE_STD (MODE_INSPECT_IP \ - | MODE_INSPECT_URL \ - | MODE_INSPECT_RB \ - | MODE_INSPECT_ARGS \ - | MODE_INSPECT_UA \ - | MODE_INSPECT_HEAD \ - | MODE_INSPECT_GET \ - | MODE_INSPECT_POST \ - | MODE_INSPECT_CC \ - | MODE_EXTRA_COMPAT \ - | MODE_EXTRA_CACHE) +#define NGX_HTTP_WAF_MODE_STD (NGX_HTTP_WAF_MODE_INSPECT_IP \ + | NGX_HTTP_WAF_MODE_INSPECT_URL \ + | NGX_HTTP_WAF_MODE_INSPECT_RB \ + | NGX_HTTP_WAF_MODE_INSPECT_ARGS \ + | NGX_HTTP_WAF_MODE_INSPECT_UA \ + | NGX_HTTP_WAF_MODE_INSPECT_HEAD \ + | NGX_HTTP_WAF_MODE_INSPECT_GET \ + | NGX_HTTP_WAF_MODE_INSPECT_POST \ + | NGX_HTTP_WAF_MODE_INSPECT_CC \ + | NGX_HTTP_WAF_MODE_EXTRA_COMPAT \ + | NGX_HTTP_WAF_MODE_EXTRA_CACHE) /** * @def MODE_STATIC * @brief 适用于静态站点的工作模式 */ -#define MODE_STATIC (MODE_INSPECT_IP \ - | MODE_INSPECT_URL \ - | MODE_INSPECT_UA \ - | MODE_INSPECT_GET \ - | MODE_INSPECT_HEAD \ - | MODE_INSPECT_CC \ - | MODE_EXTRA_CACHE) +#define NGX_HTTP_WAF_MODE_STATIC (NGX_HTTP_WAF_MODE_INSPECT_IP \ + | NGX_HTTP_WAF_MODE_INSPECT_URL \ + | NGX_HTTP_WAF_MODE_INSPECT_UA \ + | NGX_HTTP_WAF_MODE_INSPECT_GET \ + | NGX_HTTP_WAF_MODE_INSPECT_HEAD \ + | NGX_HTTP_WAF_MODE_INSPECT_CC \ + | NGX_HTTP_WAF_MODE_EXTRA_CACHE) /** * @def MODE_DYNAMIC * @brief 适用于动态站点的工作模式 */ -#define MODE_DYNAMIC (MODE_INSPECT_IP \ - | MODE_INSPECT_URL \ - | MODE_INSPECT_RB \ - | MODE_INSPECT_ARGS \ - | MODE_INSPECT_UA \ - | MODE_INSPECT_COOKIE \ - | MODE_INSPECT_HEAD \ - | MODE_INSPECT_GET \ - | MODE_INSPECT_POST \ - | MODE_INSPECT_CC \ - | MODE_EXTRA_COMPAT \ - | MODE_EXTRA_CACHE) +#define NGX_HTTP_WAF_MODE_DYNAMIC (NGX_HTTP_WAF_MODE_INSPECT_IP \ + | NGX_HTTP_WAF_MODE_INSPECT_URL \ + | NGX_HTTP_WAF_MODE_INSPECT_RB \ + | NGX_HTTP_WAF_MODE_INSPECT_ARGS \ + | NGX_HTTP_WAF_MODE_INSPECT_UA \ + | NGX_HTTP_WAF_MODE_INSPECT_COOKIE \ + | NGX_HTTP_WAF_MODE_INSPECT_HEAD \ + | NGX_HTTP_WAF_MODE_INSPECT_GET \ + | NGX_HTTP_WAF_MODE_INSPECT_POST \ + | NGX_HTTP_WAF_MODE_INSPECT_CC \ + | NGX_HTTP_WAF_MODE_EXTRA_COMPAT \ + | NGX_HTTP_WAF_MODE_EXTRA_CACHE) /** * @def MODE_FULL * @brief 启用所有的模式 */ -#define MODE_FULL (MODE_INSPECT_IP \ - | MODE_INSPECT_URL \ - | MODE_INSPECT_RB \ - | MODE_INSPECT_ARGS \ - | MODE_INSPECT_UA \ - | MODE_INSPECT_COOKIE \ - | MODE_INSPECT_REFERER \ - | MODE_INSPECT_GET \ - | MODE_INSPECT_POST \ - | MODE_INSPECT_HEAD \ - | MODE_INSPECT_PUT \ - | MODE_INSPECT_DELETE \ - | MODE_INSPECT_MKCOL \ - | MODE_INSPECT_COPY \ - | MODE_INSPECT_PROPFIND \ - | MODE_INSPECT_PROPPATCH \ - | MODE_INSPECT_LOCK \ - | MODE_INSPECT_UNLOCK \ - | MODE_INSPECT_PATCH \ - | MODE_INSPECT_TRACE \ - | MODE_INSPECT_CC \ - | MODE_EXTRA_COMPAT \ - | MODE_EXTRA_STRICT \ - | MODE_EXTRA_CACHE) +#define NGX_HTTP_WAF_MODE_FULL (NGX_HTTP_WAF_MODE_INSPECT_IP \ + | NGX_HTTP_WAF_MODE_INSPECT_URL \ + | NGX_HTTP_WAF_MODE_INSPECT_RB \ + | NGX_HTTP_WAF_MODE_INSPECT_ARGS \ + | NGX_HTTP_WAF_MODE_INSPECT_UA \ + | NGX_HTTP_WAF_MODE_INSPECT_COOKIE \ + | NGX_HTTP_WAF_MODE_INSPECT_REFERER \ + | NGX_HTTP_WAF_MODE_INSPECT_GET \ + | NGX_HTTP_WAF_MODE_INSPECT_POST \ + | NGX_HTTP_WAF_MODE_INSPECT_HEAD \ + | NGX_HTTP_WAF_MODE_INSPECT_PUT \ + | NGX_HTTP_WAF_MODE_INSPECT_DELETE \ + | NGX_HTTP_WAF_MODE_INSPECT_MKCOL \ + | NGX_HTTP_WAF_MODE_INSPECT_COPY \ + | NGX_HTTP_WAF_MODE_INSPECT_PROPFIND \ + | NGX_HTTP_WAF_MODE_INSPECT_PROPPATCH \ + | NGX_HTTP_WAF_MODE_INSPECT_LOCK \ + | NGX_HTTP_WAF_MODE_INSPECT_UNLOCK \ + | NGX_HTTP_WAF_MODE_INSPECT_PATCH \ + | NGX_HTTP_WAF_MODE_INSPECT_TRACE \ + | NGX_HTTP_WAF_MODE_INSPECT_CC \ + | NGX_HTTP_WAF_MODE_EXTRA_COMPAT \ + | NGX_HTTP_WAF_MODE_EXTRA_STRICT \ + | NGX_HTTP_WAF_MODE_EXTRA_CACHE) /* 检查对应文件是否存在,如果存在则根据 mode 的值将数据处理后存入容器中 */ /** - * @def CHECK_AND_LOAD_CONF(cf, folder, end, filename, container, mode) + * @def NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, folder, end, filename, container, mode) * @brief 检查对应文件是否存在,如果存在则根据 mode 的值将数据处理后存入数组中。 * @param[in] folder 配置文件所在文件夹的绝对路径。 * @param[in] end folder 字符数组的 '\0' 的地址。 @@ -331,13 +315,13 @@ * @param[in] mode 配置读取模式。 * @warning 当文件不存在的时候会直接执行 @code return NGX_CONF_ERROR; @endcode 语句。 */ -#define CHECK_AND_LOAD_CONF(cf, folder, end, filename, container, mode) { \ +#define NGX_HTTP_WAF_CHECK_AND_LOAD_CONF(cf, folder, end, filename, container, mode) { \ strcat((folder), (filename)); \ - if (access((folder), R_OK) != 0) { \ + if (access((folder), R_OK) != 0) { \ ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: %s: %s", (folder), "No such file or directory"); \ return NGX_CONF_ERROR; \ } \ - if (load_into_container((cf), (folder), (container), (mode)) == FAIL) { \ + if (load_into_container((cf), (folder), (container), (mode)) == NGX_HTTP_WAF_FAIL) { \ ngx_conf_log_error(NGX_LOG_ERR, (cf), 0, "ngx_waf: %s: %s", (folder), "Cannot read configuration."); \ return NGX_CONF_ERROR; \ } \ @@ -345,24 +329,24 @@ } /** - * @def CHECK_FLAG(origin, flag) + * @def NGX_HTTP_WAF_CHECK_FLAG(origin, flag) * @brief 检查 flag 是否存在于 origin 中,即位操作。 - * @return 存在则返回 TRUE,反之返回 FALSE。 - * @retval TRUE 存在。 - * @retval FALSE 不存在。 + * @return 存在则返回 NGX_HTTP_WAF_TRUE,反之返回 NGX_HTTP_WAF_FALSE。 + * @retval NGX_HTTP_WAF_TRUE 存在。 + * @retval NGX_HTTP_WAF_FALSE 不存在。 */ -#define CHECK_FLAG(origin, flag) (((origin) & (flag)) == (flag) ? TRUE : FALSE) +#define NGX_HTTP_WAF_CHECK_FLAG(origin, flag) (((origin) & (flag)) == (flag) ? NGX_HTTP_WAF_TRUE : NGX_HTTP_WAF_FALSE) /** - * @def CHECK_BIT(origin, bit_index) + * @def NGX_HTTP_WAF_CHECK_BIT(origin, bit_index) * @brief 检查 origin 的某一位是否为 1。 - * @return 如果为一则返回 TRUE,反之返回 FALSE。 - * @retval TRUE 被测试的位为一。 - * @retval FALSE 被测试的位为零。 + * @return 如果为一则返回 NGX_HTTP_WAF_TRUE,反之返回 NGX_HTTP_WAF_FALSE。 + * @retval NGX_HTTP_WAF_TRUE 被测试的位为一。 + * @retval NGX_HTTP_WAF_FALSE 被测试的位为零。 * @note bit_index 从 0 开始计数,其中 0 代表最低位。 */ -#define CHECK_BIT(origin, bit_index) (CHECK_FLAG((origin), 1 << (bit_index))) +#define NGX_HTTP_WAF_CHECK_BIT(origin, bit_index) (NGX_HTTP_WAF_CHECK_FLAG((origin), 1 << (bit_index))) #endif // !NGX_HTTP_WAF_MODULE_MACRO_H diff --git a/inc/ngx_http_waf_module_mem_pool.h b/inc/ngx_http_waf_module_mem_pool.h index df6990b2..62e9a77d 100644 --- a/inc/ngx_http_waf_module_mem_pool.h +++ b/inc/ngx_http_waf_module_mem_pool.h @@ -16,9 +16,7 @@ * @param[out] pool 要初始化的内存池 * @param[in] type 内存池类型 * @param[in] native_pool 内存池 - * @return 如果成功返回 SUCCESS,反之则不是。 - * @retval SUCCESS 成功 - * @retval 其它 失败 + * @return 如果成功返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 */ static ngx_int_t mem_pool_init(mem_pool_t* pool, mem_pool_type_e type, void* native_pool); @@ -34,13 +32,13 @@ static void* mem_pool_calloc(mem_pool_t* pool, ngx_uint_t byte_size); * @brief 释放一段连续的内存 * @param[in] pool 要操作的内存池 * @param[in] buffer 内存的首地址 - * @return 成功则返回 SUCCESS,反之则不是。 + * @return 成功则返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 */ static ngx_int_t mem_pool_free(mem_pool_t* pool, void* buffer); static ngx_int_t mem_pool_init(mem_pool_t* pool, mem_pool_type_e type, void* native_pool) { if (pool == NULL || (type != std && native_pool == NULL)) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } pool->type = type; @@ -51,7 +49,7 @@ static ngx_int_t mem_pool_init(mem_pool_t* pool, mem_pool_type_e type, void* nat case slab_pool: pool->native_pool.slab_pool = (ngx_slab_pool_t*)native_pool; break; } - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } static void* mem_pool_calloc(mem_pool_t* pool, ngx_uint_t byte_size) { @@ -70,9 +68,9 @@ static ngx_int_t mem_pool_free(mem_pool_t* pool, void* buffer) { case std: free(buffer); break; case gernal_pool: ngx_pfree(pool->native_pool.gernal_pool, buffer); break; case slab_pool: ngx_slab_free_locked(pool->native_pool.slab_pool, buffer); break; - default: return FAIL; + default: return NGX_HTTP_WAF_FAIL; } - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } diff --git a/inc/ngx_http_waf_module_token_bucket_set.h b/inc/ngx_http_waf_module_token_bucket_set.h index df871951..8b282b76 100644 --- a/inc/ngx_http_waf_module_token_bucket_set.h +++ b/inc/ngx_http_waf_module_token_bucket_set.h @@ -24,9 +24,7 @@ * @param[in] memory_pool 内存池 * @param[in] init_count 令牌桶初始令牌数 * @param[in] ban_duration 令牌桶为空后令牌桶的拉黑时间(分钟) - * @return 如果成功返回 SUCCESS,反之则不是。 - * @retval SUCCESS 成功 - * @retval 其它 失败 + * @return 如果成功返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 */ ngx_int_t token_bucket_set_init(token_bucket_set_t* set, mem_pool_type_e pool_type, @@ -41,9 +39,7 @@ ngx_int_t token_bucket_set_init(token_bucket_set_t* set, * @param[in] inx_addr IP 地址。 * @param[in] count 取出的令牌数。 * @param[in] init_count 初始化令牌桶时填充的令牌数量。 - * @return 如果成功返回 SUCCESS,反之则不是。 - * @retval SUCCESS 成功 - * @retval 其它 失败 + * @return 如果成功返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 * @note 时间复杂度 O(1)。 */ ngx_int_t token_bucket_set_take(token_bucket_set_t* set, inx_addr_t* inx_addr, ngx_uint_t count, time_t now); @@ -54,9 +50,7 @@ ngx_int_t token_bucket_set_take(token_bucket_set_t* set, inx_addr_t* inx_addr, n * @param[in] set 要操作的令牌桶集合。 * @param[in] inx_addr IP 地址,如果为 NULL 则为所有令牌桶填充令牌。 * @param[in] count 填充的数量,如果 inx_addr 为 NULL 则会将所有令牌桶的数量设置为 count,而不是增加。 - * @return 如果成功返回 SUCCESS,反之则不是。 - * @retval SUCCESS 成功 - * @retval 其它 失败 + * @return 如果成功返回 NGX_HTTP_WAF_SUCCESS,反之则不是。 * @note 时间复杂度当 inx_addr 不为 NULL 时为 O(1),反之为 O(n)。 */ ngx_int_t token_bucket_set_put(token_bucket_set_t* set, inx_addr_t* inx_addr, ngx_uint_t count, time_t now); @@ -66,8 +60,7 @@ ngx_int_t token_bucket_set_put(token_bucket_set_t* set, inx_addr_t* inx_addr, ng * @brief 清空令牌桶 * @param[in] set 要操作的令牌桶集合。 * @return 如果成功返回 SUCCESS,反之则不是。 - * @retval SUCCESS 成功 - * @retval 其它 失败 + * @retval NGX_HTTP_WAF_SUCCESS 成功 * @note 时间复杂度 O(n) */ ngx_int_t token_bucket_set_clear(token_bucket_set_t* set); @@ -84,11 +77,11 @@ ngx_int_t token_bucket_set_init(token_bucket_set_t* set, ngx_uint_t init_count, ngx_uint_t ban_duration) { if (set == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } - if (mem_pool_init(&set->pool, pool_type, memory_pool) != SUCCESS) { - return FAIL; + if (mem_pool_init(&set->pool, pool_type, memory_pool) != NGX_HTTP_WAF_SUCCESS) { + return NGX_HTTP_WAF_FAIL; } set->bucket_count = 0; @@ -98,7 +91,7 @@ ngx_int_t token_bucket_set_init(token_bucket_set_t* set, set->init_count = init_count; set->ban_duration = ban_duration; - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } ngx_int_t token_bucket_set_take(token_bucket_set_t* set, inx_addr_t* inx_addr, ngx_uint_t count, time_t now) { @@ -108,29 +101,29 @@ ngx_int_t token_bucket_set_take(token_bucket_set_t* set, inx_addr_t* inx_addr, n if (bucket == NULL) { bucket = (token_bucket_t*)mem_pool_calloc(&(set->pool), sizeof(token_bucket_t)); if (bucket == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } else { ngx_memcpy(&(bucket->inx_addr), inx_addr, sizeof(inx_addr_t)); bucket->count = set->init_count; - bucket->is_ban = FALSE; + bucket->is_ban = NGX_HTTP_WAF_FALSE; bucket->last_ban_time = 0; HASH_ADD(hh, set->head, inx_addr, sizeof(inx_addr_t), bucket); } } - if (bucket->is_ban == FALSE) { + if (bucket->is_ban == NGX_HTTP_WAF_FALSE) { if (bucket->count >= count) { bucket->count -= count; } else { - bucket->is_ban = TRUE; + bucket->is_ban = NGX_HTTP_WAF_TRUE; bucket->last_ban_time = now; - return FAIL; + return NGX_HTTP_WAF_FAIL; } } else { - return FAIL; + return NGX_HTTP_WAF_FAIL; } - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } @@ -143,20 +136,20 @@ ngx_int_t token_bucket_set_put(token_bucket_set_t* set, inx_addr_t* inx_addr, ng if (bucket == NULL) { bucket = (token_bucket_t*)mem_pool_calloc(&(set->pool), sizeof(token_bucket_t)); if (bucket == NULL) { - return MALLOC_ERROR; + return NGX_HTTP_WAF_MALLOC_ERROR; } else { ngx_memcpy(&(bucket->inx_addr), inx_addr, sizeof(inx_addr_t)); - bucket->is_ban = FALSE; + bucket->is_ban = NGX_HTTP_WAF_FALSE; bucket->last_ban_time = 0; bucket->count = count; HASH_ADD(hh, set->head, inx_addr, sizeof(inx_addr_t), bucket); } } - if (bucket->is_ban == TRUE) { + if (bucket->is_ban == NGX_HTTP_WAF_TRUE) { double diff_time_minute = difftime(now, bucket->last_ban_time) / 60; if (diff_time_minute > set->ban_duration) { - bucket->is_ban = FALSE; + bucket->is_ban = NGX_HTTP_WAF_FALSE; bucket->count = count; } } else { @@ -165,10 +158,10 @@ ngx_int_t token_bucket_set_put(token_bucket_set_t* set, inx_addr_t* inx_addr, ng } else { for (bucket = set->head; bucket != NULL; bucket = (token_bucket_t*)(bucket->hh.next)) { - if (bucket->is_ban == TRUE) { + if (bucket->is_ban == NGX_HTTP_WAF_TRUE) { double diff_time_minute = difftime(now, bucket->last_ban_time) / 60; if (diff_time_minute > set->ban_duration) { - bucket->is_ban = FALSE; + bucket->is_ban = NGX_HTTP_WAF_FALSE; bucket->count = count; } } else { @@ -177,7 +170,7 @@ ngx_int_t token_bucket_set_put(token_bucket_set_t* set, inx_addr_t* inx_addr, ng } } - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } ngx_int_t token_bucket_set_clear(token_bucket_set_t* set) { @@ -185,13 +178,13 @@ ngx_int_t token_bucket_set_clear(token_bucket_set_t* set) { for (p = set->head; p != NULL; ) { prev = p; p = (token_bucket_t*)(p->hh.next); - if (mem_pool_free(&(set->pool), prev) != SUCCESS) { + if (mem_pool_free(&(set->pool), prev) != NGX_HTTP_WAF_SUCCESS) { set->head = NULL; - return FAIL; + return NGX_HTTP_WAF_FAIL; } } set->head = NULL; - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } #endif diff --git a/inc/ngx_http_waf_module_type.h b/inc/ngx_http_waf_module_type.h index 0c355c01..ee1c9849 100644 --- a/inc/ngx_http_waf_module_type.h +++ b/inc/ngx_http_waf_module_type.h @@ -16,6 +16,15 @@ #ifndef NGX_HTTP_WAF_MODULE_TYPE_H #define NGX_HTTP_WAF_MODULE_TYPE_H + +/** + * @typedef ngx_http_waf_check + * @brief 请求检查函数的函数指针 + * @param[out] out_http_status 当触发规则时需要返回的 HTTP 状态码。 +*/ +typedef ngx_int_t (*ngx_http_waf_check_pt)(ngx_http_request_t* r, ngx_int_t* out_http_status); + + /** * @struct inx_addr_t * @brief 代表 ipv4 或 ipv6 地址。 @@ -93,7 +102,7 @@ typedef struct lru_cache_item_s { * @brief LRU 缓存管理器 */ typedef struct lru_cache_manager_s { - time_t last_eliminate; /**< 淘汰缓存项的次数 */ + time_t last_eliminate; /**< 最后一次批量淘汰缓存的时间 */ mem_pool_t pool; /**< 内存池 */ ngx_uint_t size; /**< 当前缓存的项目数 */ ngx_uint_t capacity; /**< 最多嫩容纳多少个缓存项 */ @@ -162,7 +171,7 @@ typedef struct ip_trie_s { typedef struct ngx_http_waf_ctx_s { ngx_int_t blocked; /**< 是否拦截了本次请求 */ u_char rule_type[128]; /**< 触发的规则类型 */ - u_char rule_deatils[RULE_MAX_LEN]; /**< 触发的规则内容 */ + u_char rule_deatils[NGX_HTTP_WAF_RULE_MAX_LEN]; /**< 触发的规则内容 */ ngx_int_t read_body_done; /**< 是否已经读取完请求体 */ } ngx_http_waf_ctx_t; @@ -172,17 +181,16 @@ typedef struct ngx_http_waf_ctx_s { * @brief 每个 server 块的配置块 */ typedef struct ngx_http_waf_srv_conf_s { - ngx_log_t *debug_log; /**< 记录内存池在进行操作时的错误日志 */ ngx_pool_t *ngx_pool; /**< 模块所使用的内存池 */ ngx_uint_t alloc_times; /**< 当前已经从内存池中申请过多少次内存 */ ngx_int_t waf; /**< 是否启用本模块 */ ngx_str_t waf_rule_path; /**< 配置文件所在目录 */ uint64_t waf_mode; /**< 检测模式 */ ngx_int_t waf_cc_deny_limit; /**< CC 防御的限制频率 */ - ngx_int_t waf_cc_deny_duration; /**< CC 防御的拉黑时长(分钟) */ + ngx_int_t waf_cc_deny_duration; /**< CC 防御的拉黑时长(秒) */ ngx_int_t waf_cc_deny_shm_zone_size; /**< CC 防御所使用的共享内存的大小(字节) */ ngx_int_t waf_inspection_capacity; /**< 用于缓存检查结果的共享内存的大小(字节) */ - ngx_int_t waf_eliminate_inspection_cache_interval; /**< 批量淘汰缓存的周期(分钟) */ + ngx_int_t waf_eliminate_inspection_cache_interval; /**< 批量淘汰缓存的周期(秒) */ ngx_int_t waf_eliminate_inspection_cache_percent; /**< 每次批量淘汰多少百分比的缓存(50 表示 50%) */ ip_trie_t black_ipv4; /**< IPV4 黑名单 */ ip_trie_t black_ipv6; /**< IPV6 黑名单 */ @@ -207,8 +215,8 @@ typedef struct ngx_http_waf_srv_conf_s { lru_cache_manager_t black_cookie_inspection_cache; /**< Cookie 黑名单检查缓存 */ lru_cache_manager_t white_url_inspection_cache; /**< URL 白名单检查缓存 */ lru_cache_manager_t white_referer_inspection_cache; /**< Referer 白名单检查缓存 */ - ngx_event_t event_clear_ip_access_statistics; /**< 令牌桶清空事件 */ - ngx_event_t event_eliminate_inspection_cache; /**< 集中淘汰缓存事件 */ + ngx_http_waf_check_pt check_proc[20]; /**< 各种检测流程的启动函数 */ + ngx_http_waf_check_pt check_proc_no_cc[20]; /**< 各种检测流程的启动函数,但是不包括 CC 检测 */ } ngx_http_waf_srv_conf_t; diff --git a/inc/ngx_http_waf_module_util.h b/inc/ngx_http_waf_module_util.h index 57def5ab..a20380e8 100644 --- a/inc/ngx_http_waf_module_util.h +++ b/inc/ngx_http_waf_module_util.h @@ -6,6 +6,7 @@ #ifndef NGX_HTTP_WAF_MODULE_UTIL_H #define NGX_HTTP_WAF_MODULE_UTIL_H +#include #include #include @@ -26,6 +27,7 @@ */ static ngx_int_t parse_ipv4(ngx_str_t text, ipv4_t* ipv4); + /** * @brief 将一个字符串形式的 IPV6 地址转化为 ipv6_t。 * @param[in] text 要转换的字符串 @@ -36,25 +38,46 @@ static ngx_int_t parse_ipv4(ngx_str_t text, ipv4_t* ipv4); */ static ngx_int_t parse_ipv6(ngx_str_t text, ipv6_t* ipv6); + /** - * @brief 检查两个 IPV4 是否属于同一网段 - * @param[in] ip 整型格式的 IPV4 - * @param[in] ipv4 格式化后的 IPV4 - * @return 如果属于同一网段返回 MATCHED,反之返回 NOT_MATCHED。 - * @retval MATCHED 属于同一网段。 - * @retval NOT_MATCHED 不属于同一网段。 + * @brief 将一个形如 10s 10m 10h 10d 这样的字符串转化为整数,单位是秒。 + * @param[in] str 要解析的字符串 + * @return 失败返回 NGX_ERROR,反之则不是。 */ -// static ngx_int_t ipv4_netcmp(uint32_t ip, const ipv4_t* ipv4); +static ngx_int_t parse_time(u_char* str); + /** - * @brief 检查两个 IPV6 是否属于同一网段 - * @param[in] ip 整型格式的 IPV6 - * @param[in] ipv6 格式化后的 IPV6 - * @return 如果属于同一网段返回 MATCHED,反之返回 NOT_MATCHED。 - * @retval MATCHED 属于同一网段。 - * @retval NOT_MATCHED 不属于同一网段。 + * @brief 将一个形如 10k 10m 10g 这样的字符串转化为整数,单位是字节。 + * @param[in] str 要解析的字符串 + * @return 失败返回 NGX_ERROR,反之则不是。 */ -// static ngx_int_t ipv6_netcmp(uint8_t ip[16], const ipv6_t* ipv6); +static ngx_int_t parse_size(u_char* str); + + +/** + * @brief 字符串分割 + * @param[in] str 要分割的字符串 + * @param[in] sep 分隔符 + * @param[out] max_len 分割后单个字符串的最大长度 + * @param[out] array 存放分割结果的数组 + * @return 成功则返回 SUCCESS,反之则不是。 + * @warning 使用完毕后请自行释放数组所占用内存。 +*/ +static ngx_int_t ngx_str_split(ngx_str_t* str, u_char sep, size_t max_len, UT_array** array); + + +/** + * @brief 字符串分割 + * @param[in] str 要分割的字符串 + * @param[in] sep 分隔符 + * @param[out] max_len 分割后单个字符串的最大长度 + * @param[out] array 存放分割结果的数组 + * @return 成功则返回 SUCCESS,反之则不是。 + * @warning 使用完毕后请自行释放数组所占用内存。 +*/ +static ngx_int_t str_split(u_char* str, u_char sep, size_t max_len, UT_array** array); + /** * @brief 将 ngx_str 转化为 C 风格的字符串 @@ -66,6 +89,7 @@ static ngx_int_t parse_ipv6(ngx_str_t text, ipv6_t* ipv6); */ static char* to_c_str(u_char* destination, ngx_str_t ngx_str); + /** * @} */ @@ -76,7 +100,7 @@ static ngx_int_t parse_ipv4(ngx_str_t text, ipv4_t* ipv4) { uint32_t suffix_num = 0; if (ipv4 == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } ngx_memcpy(ipv4->text, text.data, text.len); @@ -101,11 +125,11 @@ static ngx_int_t parse_ipv4(ngx_str_t text, ipv4_t* ipv4) { prefix_text[prefix_len] = '\0'; } else { - return FAIL; + return NGX_HTTP_WAF_FAIL; } if (inet_pton(AF_INET, prefix_text, &addr4) != 1) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } prefix = addr4.s_addr; @@ -149,16 +173,17 @@ static ngx_int_t parse_ipv4(ngx_str_t text, ipv4_t* ipv4) { ipv4->suffix = suffix; ipv4->suffix_num = suffix_num; - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } + static ngx_int_t parse_ipv6(ngx_str_t text, ipv6_t* ipv6) { uint8_t prefix[16] = { 0 }; uint8_t suffix[16] = { 0 }; uint32_t suffix_num = 0; if (ipv6 == NULL) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } ngx_memcpy(ipv6->text, text.data, text.len); @@ -184,11 +209,11 @@ static ngx_int_t parse_ipv6(ngx_str_t text, ipv6_t* ipv6) { prefix_text[prefix_len] = '\0'; } else { - return FAIL; + return NGX_HTTP_WAF_FAIL; } if (inet_pton(AF_INET6, prefix_text, &addr6) != 1) { - return FAIL; + return NGX_HTTP_WAF_FAIL; } ngx_memcpy(prefix, &addr6.s6_addr, 16); @@ -230,37 +255,131 @@ static ngx_int_t parse_ipv6(ngx_str_t text, ipv6_t* ipv6) { ngx_memcpy(ipv6->suffix, suffix, 16); ipv6->suffix_num = suffix_num; - return SUCCESS; + return NGX_HTTP_WAF_SUCCESS; } -// static ngx_int_t ipv4_netcmp(uint32_t ip, const ipv4_t* ipv4) { -// size_t prefix = ip & ipv4->suffix; -// if (prefix == ipv4->prefix) { -// return MATCHED; -// } +static ngx_int_t parse_time(u_char* str) { + ngx_int_t ret = 0; + size_t len = ngx_strlen(str); + if (len < 2) { + return NGX_ERROR; + } + + ret = ngx_atoi(str, len - 1); + if (ret == NGX_ERROR || ret <= 0) { + return NGX_ERROR; + } + + switch (str[len - 1]) { + case 's': ret *= 1; break; + case 'm': ret *= 1 * 60; break; + case 'h': ret *= 1 * 60 * 60; break; + case 'd': ret *= 1 * 60 * 60 * 24; break; + default: return NGX_ERROR; break; + } + + return ret; +} -// return NOT_MATCHED; -// } -// static ngx_int_t ipv6_netcmp(uint8_t ip[16], const ipv6_t* ipv6) { -// uint8_t temp_ip[16]; +static ngx_int_t parse_size(u_char* str) { + ngx_int_t ret = 0; + size_t len = ngx_strlen(str); + if (len < 2) { + return NGX_ERROR; + } + + ret = ngx_atoi(str, len - 1); + if (ret == NGX_ERROR || ret <= 0) { + return NGX_ERROR; + } -// memcpy(temp_ip, ip, 16); + switch (str[len - 1]) { + case 'k': ret *= 1 * 1024; break; + case 'm': ret *= 1 * 1024 * 1024; break; + case 'g': ret *= 1 * 1024 * 1024 * 1024; break; + default: return NGX_ERROR; break; + } + + return ret; +} -// for (int i = 0; i < 16; i++) { -// temp_ip[i] &= ipv6->suffix[i]; -// } -// if (memcmp(temp_ip, ipv6->prefix, 16) != 0) { -// return NOT_MATCHED; -// } +static ngx_int_t ngx_str_split(ngx_str_t* str, u_char sep, size_t max_len, UT_array** array) { + if (str == NULL || array == NULL) { + return NGX_HTTP_WAF_FAIL; + } + + utarray_new(*array,&ut_str_icd); + u_char* temp_str = malloc(sizeof(u_char) * max_len); + ngx_memzero(temp_str, sizeof(u_char) * max_len); + size_t str_index = 0; + + for (size_t i = 0; i < str->len; i++) { + u_char c = str->data[i]; + if (c != sep) { + if (str_index + 1 >= max_len) { + return NGX_HTTP_WAF_FAIL; + } + temp_str[str_index++] = c; + } else { + temp_str[str_index] = '\0'; + utarray_push_back(*array, &temp_str); + str_index = 0; + } + } + + if (str_index != 0) { + temp_str[str_index] = '\0'; + utarray_push_back(*array, &temp_str); + str_index = 0; + } + + free(temp_str); + + return NGX_HTTP_WAF_SUCCESS; +} + + +static ngx_int_t str_split(u_char* str, u_char sep, size_t max_len, UT_array** array) { + if (str == NULL || array == NULL) { + return NGX_HTTP_WAF_FAIL; + } + + utarray_new(*array,&ut_str_icd); + u_char* temp_str = malloc(sizeof(u_char) * max_len); + ngx_memzero(temp_str, sizeof(u_char) * max_len); + size_t str_index = 0; + + for (size_t i = 0; str[i] != '\0'; i++) { + u_char c = str[i]; + if (c != sep) { + if (str_index + 1 >= max_len) { + return NGX_HTTP_WAF_FAIL; + } + temp_str[str_index++] = c; + } else { + temp_str[str_index] = '\0'; + utarray_push_back(*array, &temp_str); + str_index = 0; + } + } + + if (str_index != 0) { + temp_str[str_index] = '\0'; + utarray_push_back(*array, &temp_str); + str_index = 0; + } + + free(temp_str); + + return NGX_HTTP_WAF_SUCCESS; +} -// return MATCHED; -// } static char* to_c_str(u_char* destination, ngx_str_t ngx_str) { - if (ngx_str.len > RULE_MAX_LEN) { + if (ngx_str.len > NGX_HTTP_WAF_RULE_MAX_LEN) { return NULL; } ngx_memcpy(destination, ngx_str.data, ngx_str.len); diff --git a/src/ngx_http_waf_module_core.c b/src/ngx_http_waf_module_core.c index e4fa84c2..f0da654e 100644 --- a/src/ngx_http_waf_module_core.c +++ b/src/ngx_http_waf_module_core.c @@ -38,9 +38,9 @@ static ngx_command_t ngx_http_waf_commands[] = { NULL }, { - ngx_string("waf_cc_deny_limit"), - NGX_HTTP_SRV_CONF | NGX_CONF_TAKE23, - ngx_http_waf_cc_deny_limit_conf, + ngx_string("waf_cc_deny"), + NGX_HTTP_SRV_CONF | NGX_CONF_TAKE123, + ngx_http_waf_cc_deny_conf, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL @@ -48,7 +48,15 @@ static ngx_command_t ngx_http_waf_commands[] = { { ngx_string("waf_cache"), NGX_HTTP_SRV_CONF | NGX_CONF_TAKE123, - ngx_http_waf_cache_size_conf, + ngx_http_waf_cache_conf, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + NULL + }, + { + ngx_string("waf_priority"), + NGX_HTTP_SRV_CONF | NGX_CONF_TAKE1, + ngx_http_waf_priority_conf, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL @@ -88,9 +96,9 @@ ngx_module_t ngx_http_waf_module = { static ngx_int_t ngx_http_waf_handler_server_rewrite_phase(ngx_http_request_t* r) { ngx_http_waf_srv_conf_t* srv_conf = ngx_http_get_module_srv_conf(r, ngx_http_waf_module); - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_COMPAT) == TRUE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_COMPAT) == NGX_HTTP_WAF_TRUE) { ngx_http_waf_trigger_mem_collation_event(r); - return check_all(r, TRUE); + return check_all(r, NGX_HTTP_WAF_TRUE); } return NGX_DECLINED; } @@ -98,13 +106,12 @@ static ngx_int_t ngx_http_waf_handler_server_rewrite_phase(ngx_http_request_t* r static ngx_int_t ngx_http_waf_handler_access_phase(ngx_http_request_t* r) { ngx_http_waf_srv_conf_t* srv_conf = ngx_http_get_module_srv_conf(r, ngx_http_waf_module); - - if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_COMPAT) == FALSE) { + if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_COMPAT) == NGX_HTTP_WAF_FALSE) { ngx_http_waf_trigger_mem_collation_event(r); - return check_all(r, TRUE); + return check_all(r, NGX_HTTP_WAF_TRUE); } - else if (CHECK_FLAG(srv_conf->waf_mode, MODE_EXTRA_COMPAT | MODE_EXTRA_STRICT) == TRUE) { - return check_all(r, FALSE); + else if (NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_EXTRA_COMPAT | NGX_HTTP_WAF_MODE_EXTRA_STRICT) == NGX_HTTP_WAF_TRUE) { + return check_all(r, NGX_HTTP_WAF_FALSE); } return NGX_DECLINED; } @@ -115,6 +122,7 @@ static void ngx_http_waf_trigger_mem_collation_event(ngx_http_request_t* r) { "ngx_waf_debug: Start the memory collection event trigger process."); ngx_http_waf_srv_conf_t* srv_conf = ngx_http_get_module_srv_conf(r, ngx_http_waf_module); + time_t now = time(NULL); if (srv_conf->waf == 0 || srv_conf->waf == NGX_CONF_UNSET) { return; @@ -125,7 +133,7 @@ static void ngx_http_waf_trigger_mem_collation_event(ngx_http_request_t* r) { return; } - time_t now = time(NULL); + ngx_slab_pool_t *shpool = (ngx_slab_pool_t *)srv_conf->shm_zone_cc_deny->shm.addr; ngx_shmtx_lock(&shpool->mutex); @@ -138,59 +146,59 @@ static void ngx_http_waf_trigger_mem_collation_event(ngx_http_request_t* r) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, "ngx_waf_debug: Shared memory is unlocked."); - if (diff_clear_minute > 60) { - ngx_post_event(&(srv_conf->event_clear_ip_access_statistics), &ngx_posted_events); + if (diff_clear_minute > ngx_max(60, srv_conf->waf_cc_deny_duration / 60 * 3)) { + ngx_http_waf_clear_ip_access_statistics(r); ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: Trigger event - clear ip access statistics."); + "ngx_waf_debug: Trigger process - clear ip access statistics."); } - ngx_int_t is_need_eliminate_cache = FALSE; + ngx_int_t is_need_eliminate_cache = NGX_HTTP_WAF_FALSE; ngx_int_t interval = srv_conf->waf_eliminate_inspection_cache_interval; - if (difftime(now, srv_conf->black_url_inspection_cache.last_eliminate) / 60 > interval) { + if (difftime(now, srv_conf->black_url_inspection_cache.last_eliminate) > interval) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: The cache in black_url_inspection_cache is eliminated too often and will trigger a memory collection event."); - is_need_eliminate_cache = TRUE; + "ngx_waf_debug: The cache in black_url_inspection_cache will trigger memory collection process."); + is_need_eliminate_cache = NGX_HTTP_WAF_TRUE; } - else if (difftime(now, srv_conf->black_args_inspection_cache.last_eliminate) / 60 > interval) { + else if (difftime(now, srv_conf->black_args_inspection_cache.last_eliminate) > interval) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: The cache in black_args_inspection_cache is eliminated too often and will trigger a memory collection event."); - is_need_eliminate_cache = TRUE; + "ngx_waf_debug: The cache in black_args_inspection_cache will trigger memory collection process."); + is_need_eliminate_cache = NGX_HTTP_WAF_TRUE; } - else if (difftime(now, srv_conf->black_ua_inspection_cache.last_eliminate) / 60 > interval) { + else if (difftime(now, srv_conf->black_ua_inspection_cache.last_eliminate) > interval) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: The cache in black_ua_inspection_cache is eliminated too often and will trigger a memory collection event."); - is_need_eliminate_cache = TRUE; + "ngx_waf_debug: The cache in black_ua_inspection_cache will trigger memory collection process."); + is_need_eliminate_cache = NGX_HTTP_WAF_TRUE; } - else if (difftime(now, srv_conf->black_referer_inspection_cache.last_eliminate) / 60 > interval) { + else if (difftime(now, srv_conf->black_referer_inspection_cache.last_eliminate) > interval) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: The cache in black_referer_inspection_cache is eliminated too often and will trigger a memory collection event."); - is_need_eliminate_cache = TRUE; + "ngx_waf_debug: The cache in black_referer_inspection_cache will trigger memory collection process."); + is_need_eliminate_cache = NGX_HTTP_WAF_TRUE; } - else if (difftime(now, srv_conf->black_cookie_inspection_cache.last_eliminate) / 60 > interval) { + else if (difftime(now, srv_conf->black_cookie_inspection_cache.last_eliminate) > interval) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: The cache in black_cookie_inspection_cache is eliminated too often and will trigger a memory collection event."); - is_need_eliminate_cache = TRUE; + "ngx_waf_debug: The cache in black_cookie_inspection_cache will trigger memory collection process."); + is_need_eliminate_cache = NGX_HTTP_WAF_TRUE; } - else if (difftime(now, srv_conf->white_url_inspection_cache.last_eliminate) / 60 > interval) { + else if (difftime(now, srv_conf->white_url_inspection_cache.last_eliminate) > interval) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: The cache in white_url_inspection_cache is eliminated too often and will trigger a memory collection event."); - is_need_eliminate_cache = TRUE; + "ngx_waf_debug: The cache in white_url_inspection_cache will trigger memory collection process."); + is_need_eliminate_cache = NGX_HTTP_WAF_TRUE; } - else if (difftime(now, srv_conf->white_referer_inspection_cache.last_eliminate) / 60 > interval) { + else if (difftime(now, srv_conf->white_referer_inspection_cache.last_eliminate) > interval) { ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: The cache in white_referer_inspection_cache is eliminated too often and will trigger a memory collection event."); - is_need_eliminate_cache = TRUE; + "ngx_waf_debug: The cache in white_referer_inspection_cache will trigger memory collection process."); + is_need_eliminate_cache = NGX_HTTP_WAF_TRUE; } - if (is_need_eliminate_cache == TRUE) { + if (is_need_eliminate_cache == NGX_HTTP_WAF_TRUE) { srv_conf->black_url_inspection_cache.last_eliminate = now; srv_conf->black_args_inspection_cache.last_eliminate = now; srv_conf->black_ua_inspection_cache.last_eliminate = now; @@ -198,9 +206,7 @@ static void ngx_http_waf_trigger_mem_collation_event(ngx_http_request_t* r) { srv_conf->black_cookie_inspection_cache.last_eliminate = now; srv_conf->white_url_inspection_cache.last_eliminate = now; srv_conf->white_referer_inspection_cache.last_eliminate = now; - ngx_post_event(&(srv_conf->event_eliminate_inspection_cache), &ngx_posted_events); - ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, - "ngx_waf_debug: Trigger event - batch cache elimination."); + ngx_http_waf_eliminate_inspection_cache(r); } @@ -209,36 +215,88 @@ static void ngx_http_waf_trigger_mem_collation_event(ngx_http_request_t* r) { } -static ngx_int_t check_all(ngx_http_request_t* r, ngx_int_t is_check_cc) { - static ngx_http_waf_check check_proc[] = { - ngx_http_waf_handler_check_white_ip, - ngx_http_waf_handler_check_cc, - ngx_http_waf_handler_check_black_ip, - ngx_http_waf_handler_check_white_url, - ngx_http_waf_handler_check_black_url, - ngx_http_waf_handler_check_black_args, - ngx_http_waf_handler_check_black_user_agent, - ngx_http_waf_handler_check_white_referer, - ngx_http_waf_handler_check_black_referer, - ngx_http_waf_handler_check_black_cookie, - NULL - }; - static ngx_http_waf_check check_proc_no_cc[] = { - ngx_http_waf_handler_check_white_ip, - ngx_http_waf_handler_check_black_ip, - ngx_http_waf_handler_check_white_url, - ngx_http_waf_handler_check_black_url, - ngx_http_waf_handler_check_black_args, - ngx_http_waf_handler_check_black_user_agent, - ngx_http_waf_handler_check_white_referer, - ngx_http_waf_handler_check_black_referer, - ngx_http_waf_handler_check_black_cookie, - NULL - }; +static void ngx_http_waf_clear_ip_access_statistics(ngx_http_request_t* r) { + ngx_http_waf_srv_conf_t* srv_conf = ngx_http_get_module_srv_conf(r, ngx_http_waf_module); + + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: The token bucket clearing process has been started."); + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: The configuration of the module has been obtained."); + + + ngx_slab_pool_t *shpool = (ngx_slab_pool_t *)srv_conf->shm_zone_cc_deny->shm.addr; + + ngx_shmtx_lock(&shpool->mutex); + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Shared memory is locked."); + + ip_trie_clear(srv_conf->ipv4_access_statistics); + ip_trie_clear(srv_conf->ipv6_access_statistics); + + ngx_shmtx_unlock(&shpool->mutex); + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Shared memory is unlocked."); + + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: The token bucket clearing process is all but complete."); +} + +static void ngx_http_waf_eliminate_inspection_cache(ngx_http_request_t* r) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: The batch cache elimination process has been started."); + + ngx_http_waf_srv_conf_t* srv_conf = ngx_http_get_module_srv_conf(r, ngx_http_waf_module); + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: The configuration of the module has been obtained."); + + double percent = srv_conf->waf_eliminate_inspection_cache_percent / 100.0; + + + if (lru_cache_manager_eliminate_percent(&srv_conf->black_url_inspection_cache, percent) != NGX_HTTP_WAF_SUCCESS) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Unable to clear cache from black_url_inspection_cache."); + } + + if (lru_cache_manager_eliminate_percent(&srv_conf->black_args_inspection_cache, percent) != NGX_HTTP_WAF_SUCCESS) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Unable to clear cache from black_args_inspection_cache."); + } + + if (lru_cache_manager_eliminate_percent(&srv_conf->black_ua_inspection_cache, percent) != NGX_HTTP_WAF_SUCCESS) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Unable to clear cache from black_ua_inspection_cache."); + } + + if (lru_cache_manager_eliminate_percent(&srv_conf->black_referer_inspection_cache, percent) != NGX_HTTP_WAF_SUCCESS) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Unable to clear cache from black_referer_inspection_cache."); + } + + if (lru_cache_manager_eliminate_percent(&srv_conf->black_cookie_inspection_cache, percent) != NGX_HTTP_WAF_SUCCESS) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Unable to clear cache from black_cookie_inspection_cache."); + } + + if (lru_cache_manager_eliminate_percent(&srv_conf->white_url_inspection_cache, percent) != NGX_HTTP_WAF_SUCCESS) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Unable to clear cache from white_url_inspection_cache."); + } + + if (lru_cache_manager_eliminate_percent(&srv_conf->white_referer_inspection_cache, percent) != NGX_HTTP_WAF_SUCCESS) { + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: Unable to clear cache from white_referer_inspection_cache."); + } + + ngx_log_debug(NGX_LOG_DEBUG_CORE, r->connection->log, 0, + "ngx_waf_debug: The batch cache elimination process is all but complete."); +} + + +static ngx_int_t check_all(ngx_http_request_t* r, ngx_int_t is_check_cc) { ngx_http_waf_ctx_t* ctx = ngx_http_get_module_ctx(r, ngx_http_waf_module); ngx_http_waf_srv_conf_t* srv_conf = ngx_http_get_module_srv_conf(r, ngx_http_waf_module); - ngx_int_t is_matched = NOT_MATCHED; + ngx_int_t is_matched = NGX_HTTP_WAF_NOT_MATCHED; ngx_int_t http_status = NGX_DECLINED; if (ctx == NULL) { @@ -250,38 +308,38 @@ static ngx_int_t check_all(ngx_http_request_t* r, ngx_int_t is_check_cc) { return http_status; } else { - ctx->read_body_done = FALSE; - ctx->blocked = FALSE; + ctx->read_body_done = NGX_HTTP_WAF_FALSE; + ctx->blocked = NGX_HTTP_WAF_FALSE; ctx->rule_type[0] = '\0'; ctx->rule_deatils[0] = '\0'; ngx_http_set_ctx(r, ctx, ngx_http_waf_module); } } - if (r->internal != 0 || srv_conf->waf == 0 || srv_conf->waf == NGX_CONF_UNSET) { + if (r->internal != 0 || srv_conf->waf == 0 || srv_conf->waf == NGX_CONF_UNSET || ctx->read_body_done == NGX_HTTP_WAF_TRUE) { http_status = NGX_DECLINED; } else { - ngx_http_waf_check* funcs = NULL; - if (is_check_cc == TRUE) { - funcs = check_proc; + ngx_http_waf_check_pt* funcs = NULL; + if (is_check_cc == NGX_HTTP_WAF_TRUE) { + funcs = srv_conf->check_proc; } else { - funcs = check_proc_no_cc; + funcs = srv_conf->check_proc_no_cc; } for (size_t i = 0; funcs[i] != NULL; i++) { is_matched = funcs[i](r, &http_status); - if (is_matched == MATCHED) { + if (is_matched == NGX_HTTP_WAF_MATCHED) { break; } } /* 如果请求方法为 POST 且 本模块还未读取过请求体 且 配置中未关闭请求体检查 */ if ((r->method & NGX_HTTP_POST) != 0 - && ctx->read_body_done == FALSE - && is_matched != MATCHED - && CHECK_FLAG(srv_conf->waf_mode, MODE_INSPECT_RB) == TRUE) { + && ctx->read_body_done == NGX_HTTP_WAF_FALSE + && is_matched != NGX_HTTP_WAF_MATCHED + && NGX_HTTP_WAF_CHECK_FLAG(srv_conf->waf_mode, NGX_HTTP_WAF_MODE_INSPECT_RB) == NGX_HTTP_WAF_TRUE) { r->request_body_in_persistent_file = 0; r->request_body_in_clean_file = 0; - http_status = ngx_http_read_client_request_body(r, check_post); + http_status = ngx_http_read_client_request_body(r, ngx_http_waf_handler_check_black_post); if (http_status != NGX_ERROR && http_status < NGX_HTTP_SPECIAL_RESPONSE) { http_status = NGX_DONE; } diff --git a/test/nginx-dynamic-module.conf b/test/nginx-dynamic-module.conf index ff85fb82..4b251cbe 100644 --- a/test/nginx-dynamic-module.conf +++ b/test/nginx-dynamic-module.conf @@ -34,8 +34,8 @@ http { waf on; waf_mode FULL; waf_rule_path /usr/local/nginx/conf/rules/; - waf_cc_deny_limit 100 60; - waf_cache 50; + waf_cc_deny rate=100r/m; + waf_cache capacity=50; root /usr/data/www/php; index index.html index.htm index.php; } diff --git a/test/nginx-static-module.conf b/test/nginx-static-module.conf index 1eaa800b..a9a3732e 100644 --- a/test/nginx-static-module.conf +++ b/test/nginx-static-module.conf @@ -33,8 +33,8 @@ http { waf on; waf_mode FULL; waf_rule_path /usr/local/nginx/conf/rules/; - waf_cc_deny_limit 100 60; - waf_cache 50; + waf_cc_deny rate=100r/m; + waf_cache capacity=50; root /usr/data/www/php; index index.html index.htm index.php; }