openresty部署WAF

  我们都知道Nginx有很多的特性和好处,但是在Nginx上开发成了一个难题,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开发者对其望而生畏。为了开发人员方便,所以接下来我们要介绍一种整合了Nginx和lua的框架,那就是OpenResty,它帮我们实现了可以用lua的规范开发,实现各种业务,并且帮我们弄清楚各个模块的编译顺序。关于OpenResty,我想大家应该不再陌生,随着系统架构的不断升级、优化,OpenResty在被广泛的应用。

  Nginx 采用的是 master-worker 模型,一个 master 进程管理多个 worker 进程,基本的事件处理都是放在 woker 中,master 负责一些全局初始化,以及对 worker 的管理。在OpenResty中,每个 woker 使用一个 LuaVM,当请求被分配到 woker 时,将在这个 LuaVM 里创建一个 coroutine(协程)。协程之间数据隔离,每个协程具有独立的全局变量_G。

  ps. 协程和多线程下的线程类似:有自己的堆栈,自己的局部变量,有自己的指令指针,但是和其他协程程序共享全局变量等信息。线程和协程的主要不同在于:多处理器的情况下,概念上来说多线程是同时运行多个线程,而协程是通过代码来完成协程的切换,任何时刻只有一个协程程序在运行。并且这个在运行的协程只有明确被要求挂起时才会被挂起。

  首先我们选择使用OpenResty,其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。

  借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。

  而且OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒杀、动态服务、单品页、列表页等都在使用Nginx+Lua架构,其他公司如淘宝、去哪儿网等。

机器规划

192.168.10.191

安装openresty

192.168.10.192

压力测试访问策略

 

 

部署,不难,很多地方都能能找到就不多说了

yum -y install gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel
useradd www -u 10000 -s /sbin/nologin -M
mkdir -p /application
wget https://openresty.org/download/openresty-1.15.8.2.tar.gz
tar xf openresty-1.15.8.2.tar.gz -C /application/
cd /application/openresty-1.15.8.2/
./configure 
--prefix=/application/openresty-1.15.8.2 
--with-luajit 
--with-pcre 
--with-pcre-jit 
--user=www 
--group=www 
--with-http_stub_status_module 
--with-http_ssl_module
gmake && gmake install
ln -s /application/openresty-1.15.8.2 /application/openresty

测试openresty安装

#修改nginx.conf文件,添加如下location段

vim /application/openresty/nginx/conf/nginx.conf

        location /hi {
            default_type text/html;
            content_by_lua_block{
            ngx.say("hello openrastry!!!");
            }
        }

#重载openresty中的nginx服务

/application/openresty/nginx/sbin/nginx -t
/application/openresty/nginx/sbin/nginx -s  reload

基于openresty来部署WAF

github上克隆下代码

git clone https://github.com/unixhot/waf.git

waf文件拷贝到openresty的nginx路径下

cp -r waf/waf/ /application/openresty/nginx/conf/

修改waf中的config.lua文件,修改lua防火前规则路径

 vim /application/openresty/nginx/conf/waf/config.lua

--WAF config file,enable = "on",disable = "off"
 
--waf status
config_waf_enable = "on"
--log dir
config_log_dir = "/tmp/waf_logs"
--rule setting
config_rule_dir = "/application/openresty/nginx/conf/waf/rule-config"
--enable/disable white url
config_white_url_check = "on"
--enable/disable white ip
config_white_ip_check = "on"
--enable/disable block ip
config_black_ip_check = "on"
--enable/disable url filtering
config_url_check = "on"
--enalbe/disable url args filtering
config_url_args_check = "on"
--enable/disable user agent filtering
config_user_agent_check = "on"
--enable/disable cookie deny filtering
config_cookie_check = "on"
--enable/disable cc filtering
config_cc_check = "on"
--cc rate the xxx of xxx seconds
config_cc_rate = "30/60"
--enable/disable post filtering
config_post_check = "on"
--config waf output redirect/html
config_waf_output = "html"
--if config_waf_output ,setting url
config_waf_redirect_url = "https://www.cnblogs.com/huanglingfa"
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"> 您的行为已违反本网站相关规定,注意操作规范。</h1>
</body>
</html>
]]

修改openresty中nginx的配置文件,在http段添加如下内容

vim /application/openresty/nginx/conf/nginx.conf

    lua_shared_dict limit 50m; #防cc使用字典,大小50M
    lua_package_path "/application/openresty/nginx/conf/waf/?.lua";
    init_by_lua_file "/application/openresty/nginx/conf/waf/init.lua";
    access_by_lua_file "/application/openresty/nginx/conf/waf/access.lua";

根据日志记录位置,创建日志目录并授予www用户的权限

mkdir /tmp/waf_logs
chown www.www /tmp/waf_logs/

检查nginx语法并重载nginx服务

/application/openresty/nginx/sbin/nginx  -t
/application/openresty/nginx/sbin/nginx  -s reload

至于lua语言的编写可以参考Nginx API for Lua :

https://github.com/openresty/lua-nginx-module#nginx-api-for-lua

模拟sql注入即url攻击

http://192.168.10.191/mysql.sql

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

tail -f /tmp/waf_logs/2020-10-18_waf.log 
{"local_time":"2020-10-18 20:38:16","client_ip":"192.168.10.1","rule_tag":"\.(bak|inc|old|mdb|sql|backup|java|class|tgz|gz|tar|zip)$","attack_method":"Deny_URL","server_name":"localhost","req_url":"/mysql.sql","req_data":"-","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"}

使用一台客户端,使用ab压测工具模拟防cc攻击

yum  install httpd-tools  -y

压力并发测试

ab -c 50 -n 1000 http://192.168.10.191/

Server Software:        openresty/1.15.8.2
Server Hostname:        192.168.10.191
Server Port:            80
Document Path:          /
Document Length:        649 bytes
Concurrency Level:      50
Time taken for tests:   1.588 seconds
Complete requests:      1000
Failed requests:        989
   (Connect: 0, Receive: 0, Length: 989, Exceptions: 0)

#从上面可以看出失败了989此请求,这是由config.lua配置文件配置决定的

vim /application/openresty/nginx/conf/waf/config.lua

--cc rate the xxx of xxx seconds

config_cc_rate = "10/60"

当然还可以模拟ip黑名单和模拟ip白名单,配置类似,只要在

/application/openresty/nginx/conf/waf/rule-config/whiteip.rule  或  blackip.rule

规则文件添加白名单的ip或黑名单的ip

模拟URL参数检测:   浏览器输入:

http://192.168.10.191/?id=select * from name where name="huanglingfa"

显示如下:

WAF上线注意事项

初期上线只记录日志,不开启WAF,防止误杀
WAF规则管理使用saltstack工具
要知道并不是有了WAF就安全,安全在很大一部分是人为因素

参考地址:https://www.cnblogs.com/wangbin/p/13542024.html

原文地址:https://www.cnblogs.com/huanglingfa/p/13841028.html