1. 目的
为了保护Web服务安全稳定,部署Web应用防火墙(Web Application Firewall, WAF),通过对HTTP(S)请求进行检测,识别并阻断SQL注入、跨站脚本攻击(Cross Site Scripting, XSS)、网页木马上传、命令/代码注入、文件包含、敏感文件访问、第三方应用漏洞攻击、CC(挑战黑洞)攻击、恶意爬虫扫描、跨站请求伪造等攻击。
2. 架构
(架构图)
3. 实现功能
- 支持IP白名单和黑名单功能,直接将黑名单的IP访问拒绝。
- 支持URL白名单,将不需要过滤的URL进行定义。
- 支持User-Agent的过滤,匹配自定义规则中的条目,然后进行处理(返回403)。
- 支持CC攻击防护,单个URL指定时间的访问次数,超过设定值,直接返回403。
- 支持Cookie过滤,匹配自定义规则中的条目,然后进行处理(返回403)。
- 支持URL过滤,匹配自定义规则中的条目,如果用户请求的URL包含这些,返回403。
- 支持URL参数过滤,原理同上。
- 支持日志记录,将所有拒绝的操作,记录到日志中去。
- 日志记录为JSON格式,便于日志分析,例如使用ELKStack进行攻击日志收集、存储、搜索和展示。
4. 构建WAF的方案
- 开源框架openresty+nginx 实现web应用防火墙(WAF)
- nginx lua lua-nginx-module构建web应用防火墙(WAF)
- ModSecurity
- HiHTTPS
- OpenWAF
- FreeWAF
- ESAPI WAF
- Java WAF
- Naxsi
- X-WAF
- VeryNginx
5. 安装openresty
5.1. 安装依赖
5.2. 下载openresty
下载地址:
5.3. 解压openresty
5.4. 编译安装openresty
参数说明:
--with-http_stub_status_module
nginx监控模块--with-http_ssl_module
nginx ssl模块
6. 安装WAF
6.1. 下载WAF
6.2. 配置WAF
在nginx.conf
的http
字段内添加以下内容:
根据日志记录位置,创建日志目录:
注意:日志目录权限与nginx启动权限相同
WAF上生产之前,建议不要直接上生产,而是先记录日志,不做任何动作。确定WAF不产生误杀。
学习access.lua
的配置
顺序:先检查白名单,通过即不检测;再检查黑名单,不通过即拒绝,检查UA,UA不通过即拒绝;检查cookie;URL检查;URL参数检查,post检查;
6.3. 启动WAF
6.4. 配置说明
7. 安装包
- Luajit: http://luajit.org/
- Nginx: http://nginx.org/download/
- ngx_devel_kit: https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
- lua-nginx-module: https://github.com/openresty/lua-nginx-module/releases
8. 安装依赖
9. 解压NDK和lua-nginx-module
10. 安装LuaJIT
10.1. 下载LuaJIT
10.2. 编译并安装LuaJIT
10.3. 配置环境变量
10.4. 加载环境变量
11. 安装lua-cjson
11.1. 下载lua-cjson
https://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz
11.2. 解压
11.3. 配置lua-cjson
选择其中一个修改Makefile文件
11.4. 安装lua-cjson
报luaL_setfuncs
错解决:
将static
去掉static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup)
12. 重新编译nginx
12.1. 升级或新安装
使用新版本升级
12.2. 编译nginx
编译完成了,执行make
,记住,这里不要执行make install
,不然会把以前安装的会覆盖的
参数说明:
--with-http_stub_status_module
nginx监控模块--with-http_ssl_module
nginx ssl模块--ngx_http_sub_module
模块是一个过滤器,通过将一个指定的字符串替换为另一个字符串来修改响应--with-http_gzip_static_module
启动预压缩功能
12.3. 创建连接
12.4. 验证nginx
编译完成后,会新生成一个nginx执行文件,在nginx-1.16.1/objs
目录下,测试一下对应的依赖有没有装上
12.5. 备份nginx
复制nginx命令覆盖以前的nginx
复制前,最好把之前的nginx备份一下,以防不测
12.6. 覆盖nginx
新的覆盖,覆盖之前,最好停掉nginx
修改nginx配置在http块下设置
12.7. 测试nginx
先测试nginx有没有被玩坏,先检查一下
接下来部署WAF方法和上面一样
13. 测试WAF功能
13.1. 模拟sql注入即url攻击
日志显示如下,记录了
日志记录了UA、匹配规则、请求URL、客户端IP、本地时间、攻击方法、请求数据和服务器名称。
13.2. 使用ab压测工具模拟防cc攻击
13.3. 模拟ip黑名单
将请求ip放入ip黑名单中
13.4. 模拟ip白名单
将请求ip放入ip白名单中,此时将不对此ip进行任何防护措施,所以sql注入时应该返回404
13.5. 模拟URL参数检测
浏览器输入http://10.8.17.32/?id=select * from name where name="jack"
详细规定在arg.rule
中有规定,对请求进行了规范
14. 防cc攻击利器之httpgrard
14.1. httpgrard介绍
HttpGuard是基于openresty,以lua脚本语言开发的防cc攻击软件。而openresty是集成了高性能web服务器Nginx,以及一系列的Nginx模块,这其中最重要的,也是我们主要用到的nginx lua模块。HttpGuard基于nginx lua开发,继承了nginx高并发,高性能的特点,可以以非常小的性能损耗来防范大规模的cc攻击。
14.2. httpgrard防cc特效
- 限制访客在一定时间内的请求次数
- 向访客发送302转向响应头来识别恶意用户,并阻止其再次访问
- 向访客发送带有跳转功能的js代码来识别恶意用户,并阻止其再次访问
- 向访客发送cookie来识别恶意用户,并阻止其再次访问
- 支持向访客发送带有验证码的页面,来进一步识别,以免误伤
- 支持直接断开恶意访客的连接
- 支持结合iptables来阻止恶意访客再次连接
- 支持白名单功能
- 支持根据统计特定端口的连接数来自动开启或关闭防cc模式
详见github地址 https://github.com/centos-bz/HttpGuard
15. WAF上线
初期上线只记录日志,不开启WAF,防止误杀。
WAF规则管理使用saltstack工具。
要知道并不是有了WAF就安全,安全在很大一部分是人为因素。
16. FAQ
16.1. FAQ1
运行报错:
一旦使用了lua-nginx-module就表示使用了openresty,这个resty.core是openresty的核心模块,对其下的很多函数进行了优化等。之前的一些版本默认是不编译进去的,所以需要你手动安装
下面是解决该问题的完整步骤:
- 下载lua-resty-core
- 进入lua-resty-core目录
- 使用luajit编译
注意将/path/to/luajit/lib和/path/to/luajit/include/luajit-2.1替换为实际的luajit库和头文件路径。
- 编辑nginx.conf,在http块中添加
将/path/to/lua-resty-core/lib/替换为实际的lua-resty-core安装路径。
- 重新加载nginx配置
这样应该就可以解决lua_load_resty_core失败的问题了。如果还是不行,可以检查一下luajit的路径是否正确,lua-resty-core是否安装成功等。