使用Nginx+Openresty实现WAF功能

什么是WAF

Web应用防护系统(也称为:网站应用级入侵防御系统。英文:Web Application Firewall,简称: WAF)。利用国际上公认的一种说法:Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。

实现WAF

两种方式

  1. 使用nginx+lua来实现WAF,须在编译nginx的时候配置上lua
  2. 部署OpenResty,不需要在编译nginx的时候指定lua

功能列表

  1. 支持IP白名单和黑名单功能,直接将黑名单的IP访问拒绝。
  2. 支持URL白名单,将不需要过滤的URL进行定义。
  3. 支持User-Agent的过滤,匹配自定义规则中的条目,然后进行处理(返回403)。
  4. 支持CC攻击防护,单个URL指定时间的访问次数,超过设定值,直接返回403。
  5. 支持Cookie过滤,匹配自定义规则中的条目,然后进行处理(返回403)。
  6. 支持URL过滤,匹配自定义规则中的条目,如果用户请求的URL包含这些,返回403。
  7. 支持URL参数过滤,原理同上。
  8. 支持日志记录,将所有拒绝的操作,记录到日志中去。
  9. 日志记录为JSON格式,便于日志分析,例如使用ELKStack进行攻击日志收集、存储、搜索和展示

具体操作

采用第二种方式实现WAF较为方便

以下操作的前提是:centos7.4 

部署OpenResty

# 安装依赖包
yum install -y readline-devel pcre-devel openssl-devel zlib-devel
cd /usr/local/src
# 下载编译安装openresty
wget https://openresty.org/download/openresty-1.15.8.1.tar.gz
tar -zxv -f openresty-1.15.8.1.tar.gz
cd openresty-1.15.8.1
./configure --with-luajit --with-http_stub_status_module --with-pcre --with-pcre-jit
gmake && gmake install

使用yum方式安装,推荐使用
同时结合配置yum下载的rpm包不删除,可以保留安装包

yum install yum-utils
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
yum install openresty

测试openresty安装,在nginx的配置文件加入

server {
    location /hello {
        default_type text/html;
        content_by_lua_block {
            ngx.say("HelloWorld")
        }
    }
}

保存退出,访问ip/hello,出现HelloWorld证明安装成功。

部署WAF

# 从github克隆waf
git clone https://github.com/unixhot/waf.git
cp -a ./waf/waf /usr/local/openresty/nginx/conf/
waf目录:/usr/local/openresty/nginx/conf/waf
lua配置文件:/usr/local/openresty/nginx/conf/waf/config.lua
Waf的ip黑名单:/usr/local/openresty/nginx/conf/waf/rule-config/blackip.rule
Waf的ip白名单:/usr/local/openresty/nginx/conf/waf/rule-config/whiteip.rule
Waf的规则存放目录:/usr/local/openresty/nginx/conf/waf/rule-config

修改nginx的配置文件,在http里加入

#WAF
lua_shared_dict limit 10m;
lua_package_path "/usr/local/openresty/nginx/conf/waf/?.lua";
init_by_lua_file "/usr/local/openresty/nginx/conf/waf/init.lua";
access_by_lua_file "/usr/local/openresty/nginx/conf/waf/access.lua";

保存退出。

#测试配置
/usr/local/openresty/nginx/sbin/nginx –t
#重新加载配置
/usr/local/openresty/nginx/sbin/nginx reload

至此,WAF已经配置成功.

测试WAF

  1. 模拟sql注入,访问ip/test.sql,看是否出现拦截

  2. 模拟参数检测,访问ip/?id=test,看是否出现拦截

  3. 黑白名单

    #白名单路径
    /usr/local/openresty/nginx/conf/waf/rule-config/whiteip.rule
    #黑名单路径
    /usr/local/openresty/nginx/conf/waf/rule-config/blackip.rule

检测顺序:先检查白名单,通过即不检测;再检查黑名单,不通过即拒绝,检查UA,UA不通过即拒绝;检查cookie;URL检查;URL参数检查,post检查;

日志显示如下,记录了UA,匹配规则,URL,客户端类型,攻击的类型,请求的数据

[root@h1 ~]# ab -c 100 -n 100 http://192.168.1.5/hello
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.1.5 (be patient).....done


Server Software:        openresty/1.15.8.1
Server Hostname:        192.168.1.5
Server Port:            80

Document Path:          /hello
Document Length:        11 bytes

Concurrency Level:      100
Time taken for tests:   0.040 seconds
Complete requests:      100
Failed requests:        89
   (Connect: 0, Receive: 0, Length: 89, Exceptions: 0)
Write errors:           0
Non-2xx responses:      89
Total transferred:      29784 bytes
HTML transferred:       14272 bytes
Requests per second:    2488.55 [#/sec] (mean)
Time per request:       40.184 [ms] (mean)
Time per request:       0.402 [ms] (mean, across all concurrent requests)
Transfer rate:          723.82 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    6   1.3      6       8
Processing:     4   15   6.1     15      26
Waiting:        1   15   6.2     15      25
Total:         10   22   5.0     21      30

Percentage of the requests served within a certain time (ms)
  50%     21
  66%     24
  75%     26
  80%     27
  90%     28
  95%     29
  98%     30
  99%     30
 100%     30 (longest request)

将对方IP放入黑名单

echo 192.168.1.3 >> /usr/local/openresty/nginx/conf/waf/rule-config/blackip.rule

再拿192.168.1.3访问的时候就提示403:

[root@h1 ~]# curl 192.168.1.5/hello
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>

将对方IP放入白名单

echo 192.168.1.3 >> /usr/local/openresty/nginx/conf/waf/rule-config/whiteip.rule

此时将不对此ip进行任何防护措施,所以sql注入时应该返回404

[root@h1 ~]# curl 192.168.1.5/test.sql
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>
### WAF配置文件详细说明
#路径
/usr/local/openresty/nginx/conf/waf/config.lua   
#详细说明,lua文件中,--为注释
--WAF config file,enable = "on",disable = "off"
--waf status waf状态是否开启
config_waf_enable = "on"
--log dir 日志位置,json格式,根据实际情况修改
config_log_dir = "/tmp"
--rule setting 匹配规则地址,根据实际情况修改
config_rule_dir = "/usr/local/openresty/nginx/conf/waf/rule-config"
--enable/disable white url 是否开启url检测
config_white_url_check = "on"
--enable/disable white ip 是否开启白名单ip检测
config_white_ip_check = "on"
--enable/disable block ip 是否开启黑名单ip检测
config_black_ip_check = "on"
--enable/disable url filtering 是否开启url过滤
config_url_check = "on"
--enalbe/disable url args filtering 是否开启参数检测
config_url_args_check = "on"
--enable/disable user agent filtering 是否开启ua检测
config_user_agent_check = "on"
--enable/disable cookie deny filtering 是否开启cookie检测
config_cookie_check = "on"
--enable/disable cc filtering 是否开启CC检测
config_cc_check = "on"
--cc rate the xxx of xxx seconds 允许一个ip60秒内只能访问10次
config_cc_rate = "10/60"
--enable/disable post filtering 是否开启post检测
config_post_check = "on"
--config waf output redirect/html 拦截开启跳转还是一个html页面
config_waf_output = "html"
--if config_waf_output ,setting url 跳转地址和输出页面
config_waf_redirect_url = "https://www.gov.cn/"
--访问被拦截后出现的页面
config_output_html=[[
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-cn" />
<title>网站防火墙</title>
</head>
<body>
<h1 align="center"> 您的行为已违反本网站相关规定,注意操作规范。
</body>
</html>
]]

说明

过滤规则在waf/rule-config/下,可根据需求自行调整,每条规则需换行,或者用|分割

    args里面的规则get参数进行过滤的
    url是只在get请求url过滤的规则     
    post是只在post请求过滤的规则      
    whitelist是白名单,里面的url匹配到不做过滤 
   blackip.rule是黑名单
    user-agent是对user-agent的过滤规则

默认没有开启post参数过滤,在文件access.lua中取消注释即可

WAF日志默认存放在/tmp/日期_waf.log

config.lua文件中的提示信息:
放在两个中括号中

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>网站防火墙</title>
<style>
p {
    line-height:20px;
}
ul{ list-style-type:none;}
li{ list-style-type:none;}
</style>
</head>

<body style=" padding:0; margin:0; font:14px/1.5 Microsoft Yahei, 宋体,sans-serif; color:#555;">

 <div style="margin: 0 auto; width:1000px; padding-top:70px; overflow:hidden;">
  
  
  <div style="width:600px; float:left;">
    <div style=" height:40px; line-height:40px; color:#fff; font-size:16px; overflow:hidden; background:#6bb3f6; padding-left:20px;">网站防火墙 </div>
    <div style="border:1px dashed #cdcece; border-top:none; font-size:14px; background:#fff; color:#555; line-height:24px; height:220px; padding:20px 20px 0 20px; overflow-y:auto;background:#f3f7f9;">
      <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#fc4f03;">您的请求带有不合法参数,已被网站管理员设置拦截!</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">可能原因:您提交的内容包含危险的攻击请求</p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:1; text-indent:0px;">如何解决:</p>
<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1)检查提交内容;</li>
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2)如网站托管,请联系空间提供商;</li>
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3)普通网站访客,请联系网站管理员;</li></ul>
    </div>
  </div>
</div>
</body></html>

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值