0x01 前言
verynginx是一款基于lua_nginx_module开发的一款开源的nginx拓展。它可以实现防火墙、统计、等功能,最重要的是它提供了非常简单的操作界面。
我一直使用naxsi(安装naxsi为nginx提供WAF服务)作为nginx的waf,在最近一个月测试verynginx后发现,它也可以实现naxsi的功能,而且使用起来更为方便。但目前我还没有使用verynginx替代naxsi的计划。
0x02 安装
因为verynginx是基于lua开发的,所以我建议使用OpenResty(编译安装基于 Nginx 与 Lua 的高性能 Web 平台-OpenResty)替代原始的nginx版本。在这里我不在叙述编译安装OpenResty的过程,如有需要,请点击上面的链接。
如果你不需要自定义OpenResty,也可以使用verynginx中的安装脚本进行安装。
首先到该项目的GitHub页中下载源代码:
#先建立一个临时文件夹 [root@web-t1 ~]# mkdir codex/verynginx/ #进入该文件夹 [root@web-t1 ~]# cd codex/verynginx/ #从GitHub中下载文件 [root@web-t1 verynginx]# wget https://github.com/alexazhou/VeryNginx/archive/master.zip #解压 [root@web-t1 verynginx]# unzip master.zip
在解压出来的目录中有以下文件:
#进入解压出来的文件夹 [root@web-t1 verynginx]# cd VeryNginx-master/ #包含的文件如下 [root@web-t1 VeryNginx-master]# ll total 40 drwxr-xr-x 2 root root 23 Mar 13 23:13 Docker -rw-r--r-- 1 root root 4669 Mar 13 23:13 install.py -rw-r--r-- 1 root root 7651 Mar 13 23:13 LICENSE.txt -rw-r--r-- 1 root root 1169 Mar 13 23:13 nginx.conf -rw-r--r-- 1 root root 7941 Mar 13 23:13 readme.md -rw-r--r-- 1 root root 8321 Mar 13 23:13 readme_zh.md drwxr-xr-x 3 root root 77 Mar 13 23:13 test drwxr-xr-x 7 root root 84 Mar 13 23:13 verynginx
我们使用install.py这个python文件进行安装:
[root@web-t1 VeryNginx-master]# python install.py usage: install.py <cmd> <args> ... install cmds and args: install all : install verynginx and openresty(default) openresty : install openresty verynginx : install verynginx update verynginx : update the installed verynginx
如果你想使用自行编译的nginx或OpenResty,那么只需要install verynginx;如果想一键安装,则输入install all;还有一个选项是只安装OpenResty:install openresty。
因为我需要使用自行编译的OpenResty,所以安装命令如下:
[root@web-t1 VeryNginx-master]# python install.py install verynginx ### copy VeryNginx files ... cp -r -f ./verynginx /opt/verynginx openresty not fount, so not copy nginx.conf chmod -R 777 /opt/verynginx/verynginx/configs *** All work finished successfully, enjoy it~
从上面的输出可以看到,只安装verynginx的话,只是做一些复制与权限修改的操作。
0x03 配置
verynginx有以下三个配置文件需要include到相应的位置中:
#添加到http区块外 include /opt/verynginx/verynginx/nginx_conf/in_external.conf; #添加到http区块内 include /opt/verynginx/verynginx/nginx_conf/in_http_block.conf; #添加到server区块内 include /opt/verynginx/verynginx/nginx_conf/in_server_block.conf;
简单的配置文件如下:
worker_processes 1; events { worker_connections 1024; } include /opt/verynginx/verynginx/nginx_conf/in_external.conf; http { include /opt/verynginx/verynginx/nginx_conf/in_http_block.conf; include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { include /opt/verynginx/verynginx/nginx_conf/in_server_block.conf; listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
请注意上方的高亮行,然后重新加载nginx:
#测试nginx配置文件 [root@web-t1 verynginx]# nginx -t nginx: the configuration file /usr/local/nginx/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/nginx.conf test is successful #重新加载 [root@web-t1 verynginx]# nginx -s reload
0x04 使用 1 Block URL
在浏览器中输入:
http://[your domain or ip]/verynginx/index.html
即可看到登陆界面,然后使用默认的用户名和密码:verynginx即可登入:
下面来测试block一个路径:
以上是一个不存在的路径,我想服务器返回403,设置如下:
在config标签中选择Matcher,在Add Rule对话框中输入匹配规则名称,然后点选New Conditions添加规则,要注意的是,规则支持正则表达式:
修改了配置请不要忘记保存!
然后在Custom Action中的Filter标签中定义动作:
添加后也需要手动点击save保存!保存后并不需要重新加载nginx,这一切都是动态完成加载的。现在再次测试刚才的404连接,返还的结果为设定的403:
0x05 使用 2 BLOCK UA
我首先使用anache ab进行测试:
MacBook-Air-wifi:~ terence$ ab -c 200 -n 100 -t 99 http://10.1.1.111/
相关图标如下:
nginx日志如下:
10.1.1.66 - - [19/Mar/2017:13:32:11 +0800] "GET / HTTP/1.0" 200 10 "-" "ApacheBench/2.3"
现在我想屏蔽ApacheBench这个UA,那么Matcher的配置为:
然后在Filter中将这个匹配规则的响应设为403或其他即可,在这里我尝试设置为502:
再使用apache ab测试:
MacBook-Air-wifi:~ terence$ ab -c 200 -n 100 -t 99 http://10.1.1.111/ Server Software: openresty/1.11.2.2 Server Hostname: 10.1.1.111 Server Port: 80 Document Path: / Document Length: 179 bytes Concurrency Level: 200 Time taken for tests: 6.420 seconds Complete requests: 8411 Failed requests: 0 Non-2xx responses: 8411 Total transferred: 2834507 bytes HTML transferred: 1505569 bytes Requests per second: 1310.04 [#/sec] (mean) Time per request: 152.667 [ms] (mean) Time per request: 0.763 [ms] (mean, across all concurrent requests) Transfer rate: 431.14 [Kbytes/sec] received
请注意第14行,全部响应已经是非200。再看看nginx日志:
10.1.2.66 - - [19/Mar/2017:13:37:21 +0800] "GET / HTTP/1.0" 502 179 "-" "ApacheBench/2.3"
所有响应都变成了502,证明配置有效,完全达到应有的目的。下面再试试curl:
#通过curl获取页面 MacBook-Air-wifi:~ terence$ curl http://10.1.1.111 #响应内容 <html> <head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>openresty/1.11.2.2</center> </body> </html>
curl同样返还502,也达到屏蔽的目的。
0x06 使用 3 防御CC
CC攻击一般是使用工具或脚本不断访问动态页面,诸如搜索或用户验证等页面。但这类工具一般有一个共同点:不跟随302或307跳转、不跟随js跳转、无法验证Cookie等。
如果是正常的浏览器,肯定会有以上动作,当然verynginx也会相应的检测功能:
以下为添加的Cookie验证:
再次通过浏览器访问http://10.1.1.111/,使用控制台检查跳转情况发现有一个302跳转,而且Set-Cookie中存在verynginx_sign_cookie的数值。由此可见,上方的设置是有效的:
我先关闭先前添加的curl UA block,然后使用curl检查,返还302。但curl并不会跟随跳转,所以停留在了302的状态。
MacBook-Air-wifi:~ terence$ curl http://10.1.1.111 <html> <head><title>302 Found</title></head> <body bgcolor="white"> <center><h1>302 Found</h1></center> <hr><center>openresty/1.11.2.2</center> </body> </html>
用apache ab检查:
MacBook-Air-wifi:~ terence$ ab -c 200 -n 100 -t 99 http://10.1.1.111/ Server Software: openresty/1.11.2.2 Server Hostname: 10.1.1.111 Server Port: 80 Document Path: / Document Length: 167 bytes Concurrency Level: 200 Time taken for tests: 6.372 seconds Complete requests: 10451 Failed requests: 0 Non-2xx responses: 10451 Total transferred: 4567087 bytes HTML transferred: 1745317 bytes Requests per second: 1640.27 [#/sec] (mean) Time per request: 121.931 [ms] (mean) Time per request: 0.610 [ms] (mean, across all concurrent requests) Transfer rate: 700.00 [Kbytes/sec] received
日志显示所有的响应为非2xx,查看日志可以发现所有响应码都是302:
10.1.2.66 - - [19/Mar/2017:13:59:48 +0800] "GET / HTTP/1.0" 302 167 "-" "ApacheBench/2.3"
由此可见,这可以达到防御CC攻击的目的。
0x07 结语
这里有一个很重要的地方要注意的:如果开启了浏览器验证功能,也就是防御CC的功能,切记要定义放行的UA,例如百度、Google这类蜘蛛的UA。经过测试发现,蜘蛛大都不会跟随跳转,所以会导致索引量急剧下降或不收录。
这里建议如非必要,请勿开启浏览器验证功能!
经过几天的使用,我觉得这个比naxsi用起来要方便,添加规则也极为方便快捷。
还有一点要注意的是,请不要将这个服务暴露在公网中。如果必须暴露公网中,则务必要做好保护工作,例如使用HTTPS和双向身份验证。可以参考以下文章中双向身份验证的相关内容: