软WAF的另一种思路:基于Openresty+Naxsi的WAF实现

Posted 疯猫网络

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软WAF的另一种思路:基于Openresty+Naxsi的WAF实现相关的知识,希望对你有一定的参考价值。

0×00 WAF概要

目前软WAF的开发,大部分都采用nginx+Lua基于openresty的方式,安全防护策略如果是基于lua正则匹配http请求内容的话,在加载了大量的防护规则后,nginx的性能会大大降低。

本文采用了lua+naxsi整合的方式,使用lua来实现如cc攻击的防护、IP访问频率限制等相对复杂的安全防护策略,使用Naxsi来防护相对简单的http请求内容策略规则,有效的扬长避短,大大提升nginx 防护性能。

0×01 WAF功能

Naxsi在本WAF中主要实现基于http请求内容的防护策略规则,用于防护一些常见的漏洞,如:


SQL注入攻击 XSS攻击 目录遍历漏洞 命令注入攻击 虚拟补丁 扫描器攻击等

Lua在本waf中主要负责实现相对复杂的安全防护策略,如cc攻击防护、全局IP访问频率限制、特定url访问频率限制、ip黑白名单防护、url白名单防护、http请求转发等功能。

WAF管理后台可实现WAF节点的统一管理,本WAF可以基于云WAF模式部署或者直接嵌入到应用现有的nginx的方式部署。

0×02 WAF架构

软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


0×03 WAF管理后台

由于WAF使用了两个独立的nginx模块,所以需要两套完全不同的配置文件。naxsi模块的防护规则配置需要以文件的形式下发到nginx节点,Lua代码也需要以文件的形式下发到nginx节点。为实现文件的下发和同步,我们将配置文件放到WAF的管理端,由WAF的nginx节点定期通过http访问管理端下载配置文件。

其中naxsi的配置文件建议和lua的代码分开存放。


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


配置文件的管理,为了防止修改配置文件出错而造成nginx运行异常,我们通过python脚本结合nginx检查配置文件是是否正确,并且做到了配置文件有更新才去服务端拉取文件并且reload nginx,避免了频繁的reload nginx节点。


def get_rules_file(rulesdir,rulesfile):
    for filename in os.listdir(rulesdir):        if filename not in  ['files.txt', 'files.md5', 'get_naxsi-rules.py', 'install_naxsi_rules.py']:
            CalcMD5(rulesdir,filename,rulesfile)def CalcMD5(path,filename,rulesfile):
    filepath = path + filename    with open(filepath,'rb') as f:
        md5obj = hashlib.md5()
        md5obj.update(f.read())
        hash = md5obj.hexdigest()
        rulesfile.write(filename + ';,' + hash + '\n')        print filename + ';,' + hashdef calc_files_md5(filedir,fimename):
    files_md5 = open(fimename,"w")
    filepath = filedir + 'files.txt'
    with open(filepath,'rb') as f:
        md5obj = hashlib.md5()
        md5obj.update(f.read())
        hash = md5obj.hexdigest()
        files_md5.write(hash)
    f.close()def check_rules():
    check = commands.getstatusoutput("/usr/local/nginx/sbin/nginx -t")    if check[0] == 0:
        pattern = re.compile(r'test is successful')
        match = pattern.search(check[1])        if match:
            msg = "rules update successful"
            print msg
            get_rules_file(rulesdir,naxsi_rulesfile)
            naxsi_rulesfile.close()
            calc_files_md5(rulesdir,naxsi_md5_file)
            get_rules_file(lua_waf_dir, lua_waf_file)
            lua_waf_file.close()
            calc_files_md5(lua_waf_dir,lua_wafi_md5_file)
            commands.getstatusoutput("/usr/local/nginx/sbin/nginx -s reload")        else:
            msg = "rules update fales"
            print msg    else:
        msg = check[1]        print check[0]        print msg    return msg


为了后续的自动化生成配置文件,naxsi的个性化配置文件要由三个文件组成

**_rules.conf为站点的防护规则配置,主要有防护规则的配置文件和站点防护规则配置文件


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


0

**_active-mode.rules 是站点的防护模式配置


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


**.rules是站点的规则配置文件,因加载了naxsi的全局配置规则,一般waf会出现大量的误拦的情况,所以该规则文件主要还是配置站点的白名单规则。


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


因为每个节点是根据nginx.conf配置所配置的内容选择的配置文件,所以每个nginx节点将会同步所有的WAF配置文件。


Lua模块采用的redis+django的方式实现了配置的管理,可以通过web管理后台直接修改配置。

waf节点状态展示


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


url访问频率限制


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


站点防护功能配置


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


实时拦截情况展示


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


0×04 Naxsi配置

如要加载Naxsi,需要在nginx的http段include naxsi全局的配置文件rules.conf。在这里,我们将naxsi_core.rules 跟doxi-rules放到一个rules.conf文件内,

doxi-rules是naxsi rules的一个发布版本,是naxsi_core.rules的一个补充,doxi-rules主要包括了web_server.rules、web_apps.rules、scanner.rules、 app_server.rules等防护规则。

rules.conf的配置可以参考如下:


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


在nginx的每个server段加入 set $naxsi_extensive_log 1; 开启naxsi的扩展日志记录功能,可以记录下具体触发naxsi拦截规则的请求内容,方便后续分析拦截的是攻击请求还是误拦了正常的业务请求。


在nginx的每个server的location 段加入include /etc/nginx/naxsi-rules/**_rules.conf; 具体的规则配置文件。通过该配置文件,可以区分出不同的应用,方便WAF naxsi 防护策略的统一管理。

在每个server加入 拦截后跳转的location配置


 location /RequestDenied {        rewrite ^ http://security.*****.com/block?type=1&msec=$msec&url=$scheme://$host$request_uri redirect;
  }

0×05 Lua 配置

为了方便配置在nginx中加载waf配置,我们将Lua的配置统一写到一个配置文件内,只需要incloud 到nginx的http段内即可。

配置文件的内容如下


lua_package_path "/etc/nginx/lua_waf/?.lua;/usr/local/lib/lua/?.lua;;";init_by_lua '    waf = require("waf");    --根据应用名称修改app_name    app_name = "cc"; ';init_worker_by_lua '    cron = require("cron"); ';access_by_lua_file /etc/nginx/lua_waf/access.lua;log_by_lua_file /etc/nginx/lua_waf/sendlog.lua;

0×06 WAF日志管理

Naxsi kibana dashboa


软WAF的另一种思路:基于Openresty+Naxsi的WAF实现


http request kibana dashboa



0×07 总结

通过Lua+naxsi的整合,可满足基本的web安全防护需求,WAF功能目前还比较简陋,WAF还在不断完善中,如有不足的地方欢迎各位大佬指出。



以上是关于软WAF的另一种思路:基于Openresty+Naxsi的WAF实现的主要内容,如果未能解决你的问题,请参考以下文章

使用NGINX+Openresty实现WAF功能

基于Openresty实现业务安全防护

OpenResty+OpenWAF的WEB防护实战

基于openresty实现透明部署动态口令功能

XSS的另一种利用思路

处理 Vue 单页面 SEO 的另一种思路