ZhongKui-WAF
钟馗是中国传统文化中的一个神话人物,被誉为"捉鬼大师",专门驱逐邪恶之物。Zhongkui-WAF
的命名灵感来源于这一神话人物,寓意着该软件能够像钟馗一样,有效地保护Web应用免受各种恶意攻击和威胁。
Zhongkui-WAF
基于lua-nginx-module
,可以多维度检查和拦截恶意网络请求,具有简单易用、高性能、轻量级的特点。它的配置简单,你可以根据实际情况设置不同的安全规则和策略。
主要特性
- 多种工作模式,可随时切换
- 关闭模式:放行所有网络请求
- 保护模式(protection):拦截攻击请求并记录攻击日志
- 监控模式(monitor):记录攻击日志但不拦截攻击请求
- 支持规则自动排序,开启后按规则命中次数降序排序,可提高拦截效率
- 支持ACL自定义规则,灵活配置拦截规则
- 防护站点添加
- IP黑名单、白名单,支持网段配置,"127.0.0.1/24"或"127.0.0.1/255.255.255.0"
- HTTP Method白名单
- URL黑名单、白名单
- URL恶意参数拦截
- 恶意Header拦截
- 请求体检查
- 上传文件类型黑名单,防止webshell上传
- 恶意Cookie拦截
- CC攻击拦截,浏览器验证失败后可以自动限时或永久拉黑IP地址
- Sql注入、XSS、SSRF等攻击拦截
- 可设置仅允许指定国家的IP访问
- 敏感数据(身份证号码、手机号码、银行卡号、密码)脱敏及关键词过滤
- 支持Redis,开启后IP请求频率、IP黑名单等数据将从Redis中读写
- 攻击日志记录,包含IP地址、IP所属地区、攻击时间、防御动作、拦截规则等,支持JSON格式日志
- 流量统计可视化
安装
可以执行安装脚本install.sh
,自动安装OpenResty
、ZhongKui
、libmaxminddb
、luafilesystem
和geoipupdate
。也可以自行逐个安装。
OpenResty
由于Zhongkui-WAF
基于lua-nginx-module
,所以要先安装Nginx
或OpenResty
,强烈推荐使用OpenResty
。
如果你使用Nginx
,则需要安装以下第三方模块:
- 安装
LuaJIT
和lua-nginx-module
模块 - 下载lua-resty-redis库到
path-to-zhongkui-waf/lib/resty
目录 - 安装lua-cjson库
zhongkui-waf
假设OpenResty
安装路径为:/usr/local/openresty
,下载zhongkui-waf
文件并放置在/usr/local/openresty/zhongkui-waf
目录。
修改nginx.conf
,在http
模块下添加zhongkui-waf
相关配置:
include /usr/local/openresty/zhongkui-waf/admin/conf/waf.conf;
include /usr/local/openresty/zhongkui-waf/admin/conf/admin.conf;
include /usr/local/openresty/zhongkui-waf/admin/conf/sites.conf;
可根据访问量大小适当调整waf.conf
文件中配置的字典内存大小。
lua_shared_dict dict_cclimit 10m;
lua_shared_dict dict_accesstoken 5m;
lua_shared_dict dict_blackip 10m;
lua_shared_dict dict_locks 100k;
lua_shared_dict dict_config 100k;
lua_shared_dict dict_config_rules_hits 100k;
lua_shared_dict dict_req_count 5m;
lua_shared_dict dict_req_count_citys 10m;
lua_shared_dict dict_sql_queue 10m;
lua_package_path "/usr/local/openresty/zhongkui-waf/?.lua;/usr/local/openresty/zhongkui-waf/lib/?.lua;/usr/local/openresty/zhongkui-waf/admin/lua/?.lua;;";
init_by_lua_file /usr/local/openresty/zhongkui-waf/init.lua;
init_worker_by_lua_file /usr/local/openresty/zhongkui-waf/init_worker.lua;
access_by_lua_file /usr/local/openresty/zhongkui-waf/waf.lua;
body_filter_by_lua_file /usr/local/openresty/zhongkui-waf/body_filter.lua;
header_filter_by_lua_file /usr/local/openresty/zhongkui-waf/header_filter.lua;
log_by_lua_file /usr/local/openresty/zhongkui-waf/log_and_traffic.lua;
libmaxminddb库
IP地理位置识别需要下载MaxMind的IP地址数据文件及安装该IP数据文件的读取库。
-
从MaxMind官网下载GeoLite2 City数据文件,后续可使用官方工具对该数据文件自动更新。
-
安装
libmaxminddb
库wget -P /usr/local/src https://github.com/maxmind/libmaxminddb/releases/download/1.7.1/libmaxminddb-1.7.1.tar.gz tar -zxvf libmaxminddb-1.7.1.tar.gz cd libmaxminddb-1.7.1 ./configure make && make install echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf ldconfig
Windows系统用户要自行编译,生成
libmaxminddb.dll
文件,具体参考maxmind/libmaxminddb
官方文档using-cmake。
luaossl库
wget -O /usr/local/src/luaossl-rel-20220711.tar.gz https://github.com/wahern/luaossl/archive/refs/tags/rel-20220711.tar.gz
tar -zxf luaossl-rel-20220711.tar.gz
cd ./luaossl-rel-20220711
make all5.1 includedir=/usr/local/openresty/luajit/include/luajit-2.1 && make install5.1
LuaFileSystem库
wget -O /usr/local/src/luafilesystem-master.zip https://github.com/lunarmodules/luafilesystem/archive/refs/heads/master.zip
unzip luafilesystem-master.zip
cd ./luafilesystem-master
make INCS=/usr/local/openresty/luajit/include/luajit-2.1
mv ./src/lfs.so /usr/local/openresty/lualib/lfs.so
安装完成后重启OpenResty
,使用测试命令:
curl http://localhost/?t=../../etc/passwd
看到拦截信息则说明安装成功。
配置
Zhongkui-WAF
内置了管理界面,但你依然可以通过直接修改相应配置文件来进行自定义配置。
Zhongkui-WAF
的基本配置在/conf/zhongkui.conf
文件中,你可以对它进行修改。
IP黑名单列表可以配置在/conf/zhongkui.conf
文件中,也可以配置在path-to-zhongkui-waf/rules/ipBlackList
文件中。
不管是基本配置还是规则文件,修改完后都要执行nginx -s reload
命令来重新载入配置。
path-to-zhongkui-waf/rules
目录下是一系列规则文件,文件内容都是json
格式。你可以新增自己的规则,也可以对每条规则进行单独设置,如打开、关闭或者修改其拦截动作等。
拦截动作有如下几种:
allow
:允许当前请求并记录日志。deny
:拒绝当前请求,返回HTTP状态码403并记录日志。redirect
:拒绝当前请求,返回拦截页面并记录日志。coding
:对匹配到的内容进行过滤,替换为*
。redirect_js
:浏览器验证,JavaScript重定向。redirect_302
:浏览器验证,302重定向。
一些通用配置项:
state
:该规则的开关状态,on
为开启,off
为关闭。description
:对该规则的描述,便于管理。
配置项secret
是Zhongkui-WAF
的私钥,用于浏览器验证请求签名等,应妥善保管,安装后建议修改,格式为任意字符组合,建议较长。
CC攻击防御
CC攻击配置文件位于path-to-zhongkui-waf/rules/cc.json
,可按单URL
和单IP
统计,超过阈值时直接拒绝请求或进行浏览器验证,验证失败后可自动屏蔽IP地址。
配置项说明:
countType
:统计类型,值为"url"或"ip"。pattern
:匹配内容,对统计类型进行匹配的正则表达式,设为""时匹配所有请求。duration
:统计时长,单位为秒。threshold
:阈值,单位为次。action
:CC攻击处置动作,redirect_js
、redirect_302
仅适用于网页或H5,APP或API等环境应设置为deny
。autoIpBlock
:浏览器验证失败后自动屏蔽IP,on
为开启,off
为关闭。拉黑日志保存在./logPath/ipBlock.log
文件中。ipBlockTimeout
:IP禁止访问时间,单位为秒,设为0
则永久禁止并保存在./rules/ipBlackList
文件中。
Bot管理
Bot管理配置文件位于path-to-zhongkui-waf/rules/user-agent.json
。可配置对bot采取阻止、放行、浏览器验证或IP屏蔽等处置动作。
bot黑名单
zhongkui-waf
内置了一些自动扫描工具及恶意爬虫等的User-Agent
,默认会阻止User-Agent
在黑名单中的请求。
bot白名单
开启后,一些常见的搜索引擎爬虫将被放行,目前包括Google、百度、搜狗、Bing、360、Yandex等。
bot陷阱
bot陷阱配置在/conf/zhongkui.conf
文件中,开启后会在上游服务器返回的HTML页面中添加配置的陷阱URL,此URL对普通用户不可见,访问此URL的请求被视为bot。
建议bot陷阱结合robots协议
使用,将陷阱URI配置为禁止所有bot访问,不遵守的bot将访问陷阱URL从而被识别,而遵循robots协议
的友好bot不会被捕获。
可在robots.txt中这样配置:
User-agent: *
Disallow: /zhongkuiwaf/honey/trap
ACL自定义规则
自定义规则配置文件位于path-to-zhongkui-waf/rules/acl.json
,可根据实际需要灵活配置规则组合。
配置项说明:
rule
:规则名称。conditions
:匹配条件,可为多个条件组合,条件间为"且"关系。field
:匹配字段,可为URL
、Cookie
、Header
、Referer
、User-Agent
。pattern
:匹配内容,对字段进行匹配的正则表达式,设为""时表示匹配对应field
不存在的请求。name
:当field为Cookie
或Header
时,可匹配具体的Cookie Name或Header Name。
action
:匹配规则后的处置动作,redirect_js
、redirect_302
仅适用于网页或H5,APP或API等环境应设置为deny
。autoIpBlock
:匹配规则后自动屏蔽IP,on
为开启,off
为关闭。拉黑日志保存在./logPath/ipBlock.log
文件中。ipBlockTimeout
:IP禁止访问时间,单位为秒,设为0
则永久禁止并保存在./rules/ipBlackList
文件中。
示例:拦截URL为/test/12345.html
且无Cookie
的请求:
{
"rules": [
{
"state": "on",
"rule": "no Cookie",
"conditions": [
{
"field": "URL",
"pattern": "/test/\\d+\\.html"
},
{
"field": "Cookie",
"pattern": ""
}
],
"action": "deny",
"autoIpBlock": "off",
"ipBlockTimeout": 60,
"description": "拦截不带Cookie的请求"
}
]
}
拦截Cookie name为JSESSIONID
,值为aaaROKLSA3MYZ9rvxgLHy
的请求:
{
"rules": [
{
"state": "on",
"rule": "Cookie JSESSIONID",
"conditions": [
{
"field": "Cookie",
"name": "JSESSIONID",
"pattern": "aaaROKLSA3MYZ9rvxgLHy"
}
],
"action": "deny",
"autoIpBlock": "off",
"ipBlockTimeout": 60,
"description": "拦截JSESSIONID为aaaROKLSA3MYZ9rvxgLHy的请求"
}
]
}
敏感数据过滤
开启敏感信息过滤后,Zhongkui-WAF
将对响应数据进行过滤。
Zhongkui-WAF
内置了对响应内容中的身份证号码、手机号码、银行卡号、密码信息进行脱敏处理。需注意,内置的敏感信息脱敏功能目前仅支持处理中国境内使用的数据格式(如身份证号、电话号码、银行卡号),暂不支持处理中国境外的相关数据格式。但你可以使用正则表达式配置不同规则,以过滤请求响应内容中任何你想要过滤的数据。
敏感信息过滤配置在sensitive.json
文件中。
例如:
{
"rules": [{
"state": "on",
"action": "coding",
"codingRange": "4,-5",
"rule": "(?:(?:\\+|00)86)?1(?:(?:3[\\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\\d])|(?:9[189]))\\d{8}",
"description": "mobile number"
},
{
"state": "on",
"action": "coding",
"codingRange": "$1",
"rule": "(?:password|passwd)\"\\s*[:=]\\s*\"(\\S+)\"",
"description": "password"
}
],
"words": ["fuck", "bitch", "balabala"]
}
action
是匹配该规则后的响应动作,目前敏感信息过滤只有coding
这一种有效,即对敏感信息脱敏处理。
rule
是要处理的信息的匹配规则,通常是一个正则表达式。
codingRange
是匹配到的字符串中要处理的子字符串范围,有两种形式:
- 直接标明要处理的子字符串的起始位置:
- 如字符串
15800000000
的codingRange
为"4,7"
,则会将从第四个位置开始到第七个位置之间的所有字符进行处理,结果为158****0000
。 - 起始位置也可以是一个负数,如字符串
15800000000
的codingRange
为"4,-5"
,则会将从第四个位置开始到倒数第五个位置之间的所有字符进行处理,结果为158****0000
。
- 如字符串
- 使用
$
字面量加数字,比如:$0
指的是由该模式匹配的整个子串,而$1
指第一个带括号的捕获子串。
words
是一个数组,可以用来配置一些需要过滤掉的关键词。
管理页面
安装配置完成后,浏览器访问http://localhost:1226
,账号admin
,默认密码为zhongkui
。
从v1.2
版本开始,一些数据统计依赖Mysql
数据库,因此需要配置Mysql
数据库并自行创建数据库(zhongkui_waf
),waf启动后,表结构会自动创建。
常见问题
一个常见问题是:用安装脚本安装后无法产生日志,在管理界面修改配置项,无法保存或可以保存但必须手动执行nginx -s reload
才能生效,这些都是因为nginx
默认是用nobody
用户启动的,而nobody
用户没有对日志目录和钟馗目录下的文件读写权限。
请确保Openresty
对zhongkui-waf
目录和OpenResty
日志目录(\logs\hack
)有读、写权限,否则WAF
会无法修改配置文件和生成日志文件。最佳实践是:新建一个nginx
用户,并将这个nginx
用户添加到sudoers,允许其执行nginx
命令,然后将zhongkui-waf
目录所属用户改为nginx
用户,最后修改nginx
配置文件,以nginx
用户启动nginx
。
# 添加nginx用户
sudo useradd nginx
# 使用sudo visudo命令将下面这行规则添加进去,将nginx用户添加到sudoers,仅允许其执行nginx命令
# nginx ALL=NOPASSWD: /usr/local/openresty/nginx/sbin/nginx
# 修改zhongkui-waf和日志目录归属用户
sudo chown -R nginx:nginx /usr/local/openresty/zhongkui-waf
sudo chown -R nginx:nginx /usr/local/openresty/nginx/logs/hack
修改nginx.conf
:
user nginx;
交流群
欢迎大家进群交流,如果遇到bug或有新的需求,请优先提交Issues。
QQ群:903430639
捐赠
如果你觉得这个项目还不错,点击这里或扫描下方二维码为作者买杯咖啡吧!
版权和许可
ZhongKui-WAF 基于 Apache License, Version 2 授权。
版权所有 2023 bukale bukale2022@163.com
根据 Apache License, Version 2.0(以下简称"许可证")获得许可; 除非遵守许可证,否则您不得使用此文件。 您可以在以下位置获取许可证副本:
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则根据许可证分发的软件是基于"按原样"分发的, 不附带任何明示或暗示的担保或条件。 有关许可证下的特定语言管理权限和限制,请参阅许可证。