config = conf\redis.lua

opts = conf\opts.lua

Init阶段

调用waf.lua 的init函数,从本地配置文件读取规则,具体实现在\resty\waf\readrule.lua init_rules_from_localhost 函数中:

init_rules_from_localhost 函数实现:

       1\) 设置waf运行的模式,来自conf\redis.lua 的 default\\_mode 配置, 初始化时 为 SIMULATE 表示只记录 不阻断

       2\) 从 rules\default.json中 读取默认规则集合,主要包括access、header\_filter、body\_filter 三个阶段规则

       3\)  然后计算每个规则的偏移 \_calculate\_offset , 默认偏移都为1 ,如果需要两个规则配合使用的chain,则偏移会发生变化

       4\) 将规则保存到共享内存default 中

       注意: init阶段不允许出现网络请求,因此初始化不能从redis读取规则

Access阶段

调用waf:new() 函数进行初始化:

     1\) 获得共享内存中的运行模式,若为空 则将运行模式设置为 INACTIVE

     2\) config.waf\_status == 'on' 运行模式才生效,否则关闭模式

     3\) 若 config.servers 有值,则表示此nginx下,仅有特定域名启用waf功能

     4\) 将每个请求域名进行保存,\_servers将会记录所有保存过的域名

调用 waf:exec()函数实现主要功能:

1\) 判断当前阶段是否有效,只接收 access header\_filter、body\_filter

2\) access阶段,请求头包含x-opsec-key,并且值为设置值,则表示是命令请求

   2.1\) command:{"action":"reload\_rules"}   调用readrule.get\_waf\_rules\_from\_redis 从redis读取规则

  2.2\) command: {"action": "get\_info"}   获得当前运行模式,和所有server列表

  2.3\) command:{"action":"set\_mode","mode":"ACTIVE"} 设置模式,取值范围 INACTIVE, ACTIVE ,SIMULATE

 2.4\) command:{"action":"delete\_rules"}  删除所有规则,并且设置模式为INACTIVE

 2.5\) command:{"action":"list\_rules"}  列举当前所有规则

 2.6\) 结束本阶段请求

3) 若运行模式为 INACTIVE 则直接返回

4) 初始化运行环境变量

5) 从resty.waf.collections 读取每个阶段需要的变量

6) 判断是否为多次调用,在body_filter可能会多次调用,通过设置标志位 ctx.short_circuit

7) 根据规则 进行安全检测 _process_rule

   7.1\) 根据规则action  addheader 添加请求头,规则类型如下:
{"vars":[{"header":"server","value":"website80.com"},{"header":"x-powered-by","value":"website80.com"}], "pattern":"", "operator":"", "actions": {"addheader": "yes"}, "msg":"", "id":2005}
     7.2\)  根据规则var.parse配置,获得特定检测项

     7.3\) 获得transform旋转后内容

     7.4\) 根据规则进行解析匹配 

     7.5\)  无条件匹配,检测 var.unconditional

     7.6\)  规则匹配 取反操作op\_negated

     7.7\)  匹配成功后,记录log

     7.8\)  执行对应action

Log阶段

    write\_log\_events 将记录的变量信息,根据配置写入到目标位置 文件、socket、kafka等

results matching ""

    No results matching ""