基于openresty部署WAF

WAF: Web  Application Firewall

1、下载zip包
在浏览器上打开 https://github.com/unixhot/waf

下载zip包

 

或者在服务器上输入git clone https://github.com/unixhot/waf.git
2、解压unzip waf-master.zip

解压后得到一个waf文件夹
3、将waf文件夹拷贝到openresty的nginx路径下

默认的openresty路径为 /usr/local/openresty下
cp -r waf-master/waf/ /usr/local/openresty/nginx/conf/
4、修改waf中的config.lua文件也就是lua防火墙规则
cd到waf路径下
cd /usr/local/openresty/nginx/conf/waf
编辑配置文件
vim config.lua
修改第6行的日志存储路径
config_log_dir = "/home/tmp/waf_logs"
修改32行的选择跳转网址
config_waf_redirect_url = "https://www.baidu.com"
修改41行的内容
<h1 align="center"> 您的行为已违反本网站相关规定,注意操作规范。</h1>
4、编辑nginx.conf文件 添加以下配置
vim /usr/local/openresty/nginx/conf/nginx.conf
在http{}中增加以下内容:
lua_shared_dict limit 50m; #防cc使用字典,大小50M
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";
5、创建日志文件目录
mkdir -p /home/tmp/waf_logs
6、设置软连接
ln -s /usr/local/openresty/lualib/resty/ /usr/local/openresty/nginx/conf/waf/resty
7、重启openresty服务
systemctl restart openresty
8、模拟sql注入
访问openresty网站
在浏览器访问http://192.168.1.56:82/mysql.sql

 


或者在服务器上输入curl -l http://192.168.1.56:82/mysql.sql

 

然后cd /home/tmp/waf_logs
会看到以日期生成的一个waf.log文件

例如:

 可以看到里面的一些信息为:

{"req_url":"\/msql.sql","req_data":"-","rule_tag":"\\.(bak|inc|old|mdb|sql|backup|java|class|tgz|gz|tar|zip)$","attack_method":"Deny_URL","client_ip":"192.168.1.56","local_time":"2023-08-08 14:20:01","user_agent":"curl\/7.29.0","server_name":"192.168.1.56"}

 8.1过滤日志只显示IP和访问次数(可选)

vim grep_ip_number.sh

#/bin/bash
#只需替换2023-10-02_waf.log为日志的名字即可
grep -o '"client_ip":"[^"]*"' 2023-10-02_waf.log | sort | uniq -c

保存退出

查看效果

chmod 777 grep_ip_number.sh

sh grep_ip_number.sh

显示结果如图所示:

 


9、压力测试(可选)
安装ab工具
yum install httpd-tools -y
压力并发测试
ab -c 50 -n 1000 http://192.168.1.56:82/
输出信息:
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.56 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software: openresty/1.21.4.2
Server Hostname: 192.168.1.56
Server Port: 82

Document Path: /mysql.sql
Document Length: 306 bytes

Concurrency Level: 50
Time taken for tests: 0.150 seconds
Complete requests: 1000
Failed requests: 990
(Connect: 0, Receive: 0, Length: 990, Exceptions: 0)
Write errors: 0
Non-2xx responses: 1000
Total transferred: 316470 bytes
HTML transferred: 160470 bytes
Requests per second: 6682.17 [#/sec] (mean)
Time per request: 7.483 [ms] (mean)
Time per request: 0.150 [ms] (mean, across all concurrent requests)
Transfer rate: 2065.14 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 0 7 0.8 7 8
Waiting: 0 7 0.8 7 8
Total: 2 7 0.7 7 9

Percentage of the requests served within a certain time (ms)
50% 7
66% 7
75% 8
80% 8
90% 8
95% 8
98% 8
99% 8
100% 9 (longest request)

 

 

 

 


从上面可以看出失败了989次请求,这是由config.lua配置文件配置决定的
也就是/usr/local/openresty/nginx/conf/waf/config.lua配置文件
第26行配置
config_cc_rate = "10/60"

(允许一个ip60秒内只能访问10次)
10、添加IP黑名单或白名单(可选)
在/usr/local/openresty/nginx/conf/waf/rule-config路径下有

 这些文件

可以设置 blackip.rule 黑名单IP  whiteip.rule 白名单IP  whiteurl.rule 白名单url规则

这里配置下blackip.rule 黑名单IP 

vim /usr/local/openresty/nginx/conf/waf/rule-config/blackip.rule

192.168.1.119

 

保存退出
把IP为192.168.1.119添加为黑名单
重启服务
systemctl restart openresty
在浏览器访问http://192.168.1.56:82
会发现403

 11、隐藏openresty版本号(可选)

 编辑nginx.conf文件

vim /usr/local/openresty/nginx/conf/nginx.conf

在http{}中添加

server_tokens           off;

例如:

 

保存退出

重启openresty服务

systemctl restart openresty

再次访问,发现没有显示openresty版本号了

12、针对某个端口号禁止60秒内访问超过特定的次数后返回403

例如:

当访问8080端口时 60秒内超过10次访问返回403

而当访问8180端口时 60秒内超过10次访问不返回403 只有60秒超过6000次才返回403

这时候应该怎么配置?

12.1首先需要修改waf的config.lua配置文件

waf默认路径:/usr/local/openresty/nginx/conf/waf
然后去修改config.lua

vim /usr/local/openresty/nginx/conf/waf/config.lua

找到config_cc_rate去修改

原先配置为:
config_cc_rate = "10/60"

也就是60秒内超过10次访问返回403

修改后的配置为:

config_cc_rate = {
 ["8080"] = "10/60", -- 对于 8080 端口,60秒内访问超过10次,返回 403
 ["8180"] = "6000/60", -- 对于 8180 端口,60秒内访问超过6000次,返回 403
 }

修改后的整体配置如下:

 然后保存退出

12.2然后我们去修改waf的init.lua文件

vim /usr/local/openresty/nginx/conf/waf/init.lua

找到

--deny cc attack

原先的配置:

 把这些都删除掉 

修改成如下配置:

function cc_attack_check()
        if config_cc_check == "on" then
      local ATTACK_URI = ngx.var.uri
    local CC_TOKEN = get_client_ip() .. ATTACK_URI
    local limit = ngx.shared.limit
    local cc_rate = config_cc_rate[ngx.var.server_port]

    if cc_rate then
       local rate = tonumber(cc_rate:match("(.-)/"))
       local req, _ = limit:get(CC_TOKEN)

       if req then
         if req > rate then
         log_record('CC_Attack', ngx.var.request_uri, "-", "-")
         if config_waf_enable == "on" then
              ngx.exit(403)
        end
        else
              limit:incr(CC_TOKEN, 1)
                       end
                   else
                        limit:set(CC_TOKEN, 1, rate)
                   end
              end
       end
        return false
end

如图所示:

修改完后,保存退出 

12.3重启openresty服务

systemctl restart openresty

12.4访问测试效果

使用ab压力测试工具:

先访问8080端口
ab -c 50 -n 1000 https://192.168.1.56:8080/mysql.sql

注意:我这里是https访问的,如果你是http,则需修改下

发现访问8080端口1000次,发现失败了989次

再访问8180端口

ab -c 50 -n 10000 https://192.168.1.56:8180/mysql.sql 

注意:我这里是https访问的,如果你是http,则需修改下

发现访问8180端口10000次,发现失败了4999次

 证明配置成功

13.不同端口访问 记录访问日志

因为通过openresty启动了很多不同端口号的http服务

而默认路径又是在/usr/local/openresty/nginx/logs下

不好区分不同端口之间的访问日志

这时候 可以自定义设置端口的记录访问日志

只需修改对应的***.conf文件即可

13.1例如:

vim /usr/local/openresty/nginx/conf/conf.d/1.conf
注意这里conf.d的话是因为在nginx.conf文件的http{}中指定了路径

include /usr/local/openresty/nginx/conf/conf.d/*.conf;

如图所示:

 

 我们再回到1.conf配置文件中

在server中添加以下配置

access_log  /usr/local/openresty/nginx/logs/8080-access.log;
8080-access.log可以替换成自定义的名字

如图所示:

保存退出

13.2然后我们去访问下8080端口

curl -l https://lcoalhost:8080

注意这里我是配置了https,如果你没有配置的话则是http访问

然后cd到日志目录中

cd /usr/local/openresty/nginx/logs

会看到一个8080-access.log文件

如图所示:

证明配置成功

13.3过滤日志信息,只显示访问的IP和访问的总次数

vim grep_ip_number.sh

#!/bin/bash
#只需替换8180-access.log为日志的名字即可
#统计每个IP的访问次数
awk '{print $1}' 8180-access.log | sort | uniq -c

保存退出

chmod 777 grep_ip_number.sh

sh grep_ip_number.sh

显示结果

如图所示:

 13.4过滤日志信息,只显示在08/Oct/2023期间访问的IP和访问的总次数

#统计每个IP在08/Oct/2023访问8180-access.log的次数
#只需替换08/Oct/2023为实际需要的时间即可
#只需替换8180-access.log为实际的日志名即可

vim grep_date_ip_number.sh

#统计每个IP在08/Oct/2023访问8180-access.log的次数
#只需替换08/Oct/2023为实际需要的时间即可
#只需替换8180-access.log为实际的日志名即可

grep '08/Oct/2023' 8180-access.log | awk '{print $1}' | sort | uniq -c | awk '{total += $1} END {print "[[08/Oct/ " $2, total "]"}'

保存退出

chmod 777 grep_date_ip_number.sh

输出结果

如图所示:

 

 

 

 

 

 

           

          

 

posted @ 2023-08-10 10:50  宝英姐姐  阅读(258)  评论(1编辑  收藏  举报