摘要:
本文介绍了WAF(Web Application Firewall)中的ModSecurity,它是一个用于过滤和拦截HTTP流量的WAF,通常部署在反向代理服务器中。ModSecurity通过一组规则集进行工作,并允许用户指定需要过滤的请求特征以及服务器应该采取的操作。文章提供了编译ModSecurity的步骤,包括从GitHub克隆源码并解决编译过程中的依赖问题。接下来,文章介绍了如何将ModSecurity与Nginx服务器连接起来,通过编译ModSecurity-nginx和Nginx,并配置Nginx以使用ModSecurity。最后,文章演示了如何启动ModSecurity并配置WAF过滤规则,包括指定规则集和使用自定义规则集。通过这些步骤,读者可以了解如何使用ModSecurity构建和配置WAF以保护Web应用程序。
WAF - ModSecurity
ModSecurity是一个WAF(Web Application Firewall),可以过滤并拦截Http流量,通常被部署在反向代理服务器中。
WAF通常根据一组规则集(Core Rule Set)进行工作,用户可以指定需要过滤的请求特征,并给出服务器所需进行的操作。
环境说明
编译ModSecurity
从Github克隆源码:https://github.com/SpiderLabs/ModSecurity
1 | ./build.sh |
利用make
进行编译,该项目的makefile通过./configure
自动生成。在编译过程中涉及一些依赖:
- pcre:正则表达式库
- YAJL:Json解析库
- LMDB:Key-Value数据库
- GeoIP:IP与地理位置映射管理
- libmaxminddb:地理位置数据库
可以去对应网站下载源码手动编译,也可以利用包管理器安装相关依赖。解决依赖问题后即可安装LibModSecurity。
1 | ❯ tree |
编译Nginx、ModSecurity-nginx
ModSecutiry可以部署于多种不同的Web服务器,Nginx,Apache等等,为了能用于不同的服务器,ModSecurity提供了一系列的连接器,将其与对应的服务器连接起来。
ModSecurity-nginx是连接ModSecurity和Nginx的桥梁,为了使ModSecurity能部署于Nginx,需要将ModSecurity-nginx与Nginx一起编译,并连接上一步安装的ModSecurity链接库。
这里有一个小坑,我最初在本地是使用 Homebrew 安装的 Nginx,但是没有找到如何为其添加外部模块的方法,最后不得不手动编译Nginx
1 | ./configure --add-module=/path/to/ModSecurity-nginx |
在编译Nginx时遇到问题,总是提示无法找到ModSecurity链接库,按照网上的做法设置环境变量:
1 | # modsecurity |
后仍然报错。通过检查编译脚本发现,脚本会在检查完Nginx本身的条件之后检查第三方模块的条件,而报错的原因在于ngx_found
这个变量没有被正确赋值:
1 | modsecurity-nginx/config |
这个变量定义自nginx-1.24.0/auto/feature
,进一步检查脚本发现,测试的原理是拼贴出一段C代码,并按照读取到的环境变量进行编译,如果能够编译成功则说明库正确安装。
1 | nginx-1.24.0/auto/feature |
其中的变量$ngx_feature_incs
就是引入头文件ngx_feature_incs="#include <modsecurity/modsecurity.h>"
$ngx_feature_test
是简单的一句输出ngx_feature_test='printf("hello");'
问题出现在上面的C代码用到了printf
但是并没有引入头文件stdio.h
,导致无法通过编译。但是脚本认为没有通过编译就是因为没有正确安装ModSecurity。只要添加一句#include<stdio.h>
,即可成功完成编译。
启动ModSecurity并配置WAF过滤规则
在Nginx的配置文件中开启modsecurty并指定其采用的规则集
1 | # nginx.conf |
规则集简单起见直接使用owasp-modsecurity-crs
,在下载规则集后,将其导入到我们的自定义规则集modsec_includes.conf
当中:
1 | include modsecurity.conf |
配置好规则之后重启Nginx,用curl
发送请求,即可在log中看到。
为了测试modsecurity的拦截效果,试着自定义规则集中添加一条规则:
1 | SecRule ARGS:testparam "@contains test" "id:1234,deny,status:403" |
这条规则说明当请求中包含参数 testparam 同时其值为 test 时,拦截请求并返回 403。
作者: TieStone