Web应用防火墙(WAF)的架构与实现

打印 上一主题 下一主题

主题 563|帖子 563|积分 1689

1. 目标

     为了保护Web服务安全稳定,部署Web应用防火墙(Web Application Firewall, WAF),通过对HTTP(S)请求举行检测,识别并阻断SQL注入、跨站脚本攻击(Cross Site Scripting, XSS)、网页木马上传、命令/代码注入、文件包罗、敏感文件访问、第三方应用毛病攻击、CC(寻衅黑洞)攻击、恶意爬虫扫描、跨站请求伪造等攻击。
     2. 架构

     (架构图)
     3. 实现功能

     

  • 支持IP白名单和黑名单功能,直接将黑名单的IP访问拒绝。
  • 支持URL白名单,将不需要过滤的URL举行界说。
  • 支持User-Agent的过滤,匹配自界说规则中的条目,然后举行处置处罚(返回403)。
  • 支持CC攻击防护,单个URL指定时间的访问次数,超过设定值,直接返回403。
  • 支持Cookie过滤,匹配自界说规则中的条目,然后举行处置处罚(返回403)。
  • 支持URL过滤,匹配自界说规则中的条目,如果用户请求的URL包罗这些,返回403。
  • 支持URL参数过滤,原理同上。
  • 支持日志记录,将所有拒绝的操纵,记录到日志中去。
  • 日志记录为JSON格式,便于日志分析,例如使用ELKStack举行攻击日志网络、存储、搜刮和展示。
     4. 构建WAF的方案

     

  • 开源框架openresty+nginx 实现web应用防火墙(WAF)
     

  • 官网: https://openresty.org/cn/download.html
     

  • nginx lua lua-nginx-module构建web应用防火墙(WAF)
     

  •  https://github.com/unixhot/waf
     

  • ModSecurity
     

  • 项目地址: https://github.com/SpiderLabs/ModSecurity
     

  • HiHTTPS
     

  • 项目地址: https://github.com/qq4108863/hihttps
     

  • OpenWAF
     

  • 项目地址: https://github.com/titansec/OpenWAF
     

  • FreeWAF
  • ESAPI WAF
  • Java WAF
     

  • 项目地址: https://github.com/chengdedeng/waf
     

  • Naxsi
     

  • 项目地址: https://github.com/nbs-system/naxsi
     

  • X-WAF
     

  • 项目地址: https://github.com/xsec-lab/x-waf
     

  • VeryNginx
     

  • 项目地址: https://github.com/alexazhou/VeryNginx/
     5. 安装openresty

     5.1. 安装依赖

                                   登录后复制                        
  1. yum install pcre-devel openssl-devel readline-devel gcc gcc-c++ curl wget -y
复制代码
      

  • 1.
                       5.2. 下载openresty

     下载地址:
     

  •  https://github.com/openresty/openresty/releases
  •  https://openresty.org/download/
                                   登录后复制                        
  1. wget https://github.com/openresty/openresty/releases/download/v1.15.8.2/openresty-1.15.8.2.tar.gz
复制代码
      

  • 1.
                       5.3. 解压openresty

                                   登录后复制                        
  1. tar -zxvf openresty-1.15.8.2.tar.gz
  2. cd openresty-1.15.8.2
复制代码
      

  • 1.
  • 2.
                       5.4. 编译安装openresty

                                   登录后复制                        
  1. ./configure --with-http_stub_status_module --with-http_ssl_module --with-pcre --with-pcre-jit --with-luajit
  2. gmake
  3. gmake install
复制代码
      

  • 1.
  • 2.
  • 3.
                       参数阐明:
     

  • --with-http_stub_status_module nginx监控模块
  • --with-http_ssl_module nginx ssl模块
     6. 安装WAF

     6.1. 下载WAF

                                   登录后复制                        
  1. git clone https://github.com/unixhot/waf.git
  2. cp -a ./waf/waf/ /usr/local/nginx/conf/
复制代码
      

  • 1.
  • 2.
                       6.2. 设置WAF

                                   登录后复制                        
  1. vi /usr/local/nginx/conf/nginx.conf
复制代码
      

  • 1.
                       在nginx.conf的http字段内添加以下内容:
                                   登录后复制                        
  1. #WAF
  2. lua_shared_dict limit 50m; #防cc使用字典,大小50M
  3. lua_package_path "/usr/local/nginx/conf/waf/?.lua";
  4. init_by_lua_file "/usr/local/nginx/conf/waf/init.lua";
  5. access_by_lua_file "/usr/local/nginx/conf/waf/access.lua";
复制代码
      

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
                       根据日志记录位置,创建日志目录:
                                   登录后复制                        
  1. mkdir /tmp/waf_logs
  2. chown -R nginx.nginx /tmp/waf_logs
复制代码
      

  • 1.
  • 2.
                       注意:日志目录权限与nginx启动权限相同
     WAF上生产之前,发起不要直接上生产,而是先记录日志,不做任何动作。确定WAF不产生误杀。
                                   登录后复制                        
  1. vi /usr/local/nginx/conf/waf/config.lua
复制代码
      

  • 1.
                                                     登录后复制                        
  1. config_log_dir = "/tmp/waf_logs" #日志记录地址
  2. --rule setting
  3. config_rule_dir = "/usr/local/nginx/conf/waf/rule-config"
复制代码
      

  • 1.
  • 2.
  • 3.
                       学习access.lua的设置
序次:先检查白名单,通过即不检测;再检查黑名单,不通过即拒绝,检查UA,UA不通过即拒绝;检查cookie;URL检查;URL参数检查,post检查;
     6.3. 启动WAF

                                   登录后复制                        
  1. /usr/local/openresty/nginx/sbin/nginx -t
  2. /usr/local/openresty/nginx/sbin/nginx -s reload
复制代码
      

  • 1.
  • 2.
                       6.4. 设置阐明

                                   登录后复制                        
  1. --WAF config file,enable = "on",disable = "off" --waf status config_waf_enable = "on" #是否开启设置--log dir config_log_dir = "/tmp/waf_logs" #日志记录地址
  2. --rule setting
  3. config_rule_dir = "/usr/local/nginx/conf/waf/rule-config" #匹配规则缩放地址--enable/disable white url config_white_url_check = "on" #是否开启url检测--enable/disable white ip config_white_ip_check = "on" #是否开启IP白名单检测--enable/disable block ip config_black_ip_check = "on" #是否开启ip黑名单检测--enable/disable url filtering config_url_check = "on" #是否开启url过滤--enalbe/disable url args filtering config_url_args_check = "on" #是否开启参数检测--enable/disable user agent filtering config_user_agent_check = "on" #是否开启ua检测--enable/disable cookie deny filtering config_cookie_check = "on" #是否开启cookie检测--enable/disable cc filtering config_cc_check = "on" #是否开启防cc攻击--cc rate the xxx of xxx seconds config_cc_rate = "10/60" #允许一个ip60秒内只能--enable/disable post filtering config_post_check = "on" #是否开启post检测--config waf output redirect/html config_waf_output = "html" #action一个html页面,也可以选择跳转--if config_waf_output ,setting url config_waf_redirect_url = "http://www.baidu.com"  config_output_html=[[ #下面是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>
复制代码
      

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
                       7. 安装包

     

  • Luajit: http://luajit.org/
  • Nginx: http://nginx.org/download/
  • ngx_devel_kit: https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
  • lua-nginx-module: https://github.com/openresty/lua-nginx-module/releases
     8. 安装依赖

                                   登录后复制                        
  1. yum install -y readline-devel pcre-devel openssl-devel gcc gcc-c++ lua-devel wget
复制代码
      

  • 1.
                       9. 解压NDK和lua-nginx-module

                                   登录后复制                        
  1. tar zxvf lua-nginx-module-0.10.10.tar.gz
  2. tar zxvf ngx_devel_kit-0.3.0.tar.gz
复制代码
      

  • 1.
  • 2.
                       10. 安装LuaJIT

     10.1. 下载LuaJIT

                                   登录后复制                        
  1. git clone https://github.com/openresty/luajit2
复制代码
      

  • 1.
                       10.2. 编译并安装LuaJIT

                                   登录后复制                        
  1. make
  2. make install
复制代码
      

  • 1.
  • 2.
                       10.3. 设置环境变量

                                   登录后复制                        
  1. cat >/etc/profile.d/luajit.sh<<EOF
  2. export LUAJIT_LIB=/usr/local/lib
  3. export LUAJIT_INC=/usr/local/include/luajit-2.1
  4. EOF
复制代码
      

  • 1.
  • 2.
  • 3.
  • 4.
                       10.4. 加载环境变量

                                   登录后复制                        
  1. source /etc/profile
复制代码
      

  • 1.
                       11. 安装lua-cjson

     11.1. 下载lua-cjson

      https://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz
     11.2. 解压

                                   登录后复制                        
  1. tar zxvf lua-cjson-2.1.0.tar.gz
  2. cd lua-cjson-2.1.0
复制代码
      

  • 1.
  • 2.
                       11.3. 设置lua-cjson

                                   登录后复制                        
  1. find / -name lua.h
复制代码
      

  • 1.
                       选择其中一个修改Makefile文件
                                   登录后复制                        
  1. ##### Build defaults #####
  2. LUA_VERSION =       5.1
  3. TARGET =            cjson.so
  4. PREFIX =            /usr/local
  5. #CFLAGS =            -g -Wall -pedantic -fno-inline
  6. CFLAGS =            -O3 -Wall -pedantic -DNDEBUG
  7. CJSON_CFLAGS =      -fpic
  8. CJSON_LDFLAGS =     -shared
  9. LUA_INCLUDE_DIR =   /root/luajit2/src
  10. LUA_CMODULE_DIR =   $(PREFIX)/lib/lua/$(LUA_VERSION)
  11. LUA_MODULE_DIR =    $(PREFIX)/share/lua/$(LUA_VERSION)
  12. LUA_BIN_DIR =       $(PREFIX)/bin
复制代码
      

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
                       11.4. 安装lua-cjson

                                   登录后复制                        
  1. make && make install
复制代码
      

  • 1.
                       报luaL_setfuncs错解决:
                                   登录后复制                        
  1. vi lua_cjson.c
复制代码
      

  • 1.
                       将static去掉static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup)
                                   登录后复制                        
  1. make && make install
复制代码
      

  • 1.
                       12. 重新编译nginx

     12.1. 升级或新安装

     使用新版本升级
                                   登录后复制                        
  1. wget http://nginx.org/download/nginx-1.16.1.tar.gz
  2. tar zxvf nginx-1.16.1.tar.gz
  3. cd nginx-1.16.1
复制代码
      

  • 1.
  • 2.
  • 3.
                       12.2. 编译nginx

                                   登录后复制                        
  1. ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx  --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_gzip_static_module --add-module=../ngx_devel_kit-0.3.0/ --add-module=../lua-nginx-module-0.10.15/
复制代码
      

  • 1.
                       编译完成了,执行make,记住,这里不要执行make install,不然会把以前安装的会覆盖的
                                   登录后复制                        
  1. make
复制代码
      

  • 1.
                       参数阐明:
     

  • --with-http_stub_status_module nginx监控模块
  • --with-http_ssl_module nginx ssl模块
  • --ngx_http_sub_module模块是一个过滤器,通过将一个指定的字符串更换为另一个字符串来修改相应
  • --with-http_gzip_static_module 启动预压缩功能
     12.3. 创建毗连

                                   登录后复制                        
  1. ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2
复制代码
      

  • 1.
                       12.4. 验证nginx

     编译完成后,会新生成一个nginx执行文件,在nginx-1.16.1/objs目录下,测试一下对应的依赖有没有装上
                                   登录后复制                        
  1. cd nginx-1.16.1/objs
  2. ./nginx -V
复制代码
      

  • 1.
  • 2.
                       12.5. 备份nginx

     复制nginx命令覆盖以前的nginx
复制前,最好把之前的nginx备份一下,以防不测
                                   登录后复制                        
  1. cd /usr/local/nginx/sbin/
  2. cp nginx nginx.old
复制代码
      

  • 1.
  • 2.
                       12.6. 覆盖nginx

     新的覆盖,覆盖之前,最好停掉nginx
                                   登录后复制                        
  1. cd nginx-1.16.1/
  2. cp objs/nginx /usr/local/nginx/sbin/
复制代码
      

  • 1.
  • 2.
                       修改nginx设置在http块下设置
                                   登录后复制                        
  1. lua_load_resty_core off;
复制代码
      

  • 1.
                       12.7. 测试nginx

     先测试nginx有没有被玩坏,先检查一下
                                   登录后复制                        
  1. cd /usr/local/nginx
  2. ./sbin/nginx -t
  3. ./sbin/nginx
复制代码
      

  • 1.
  • 2.
  • 3.
                       接下来部署WAF方法和上面一样
     13. 测试WAF功能

     13.1. 模拟sql注入即url攻击

                                   登录后复制                        
  1. http://10.8.17.32/abc.sql
复制代码
      

  • 1.
                                                     登录后复制                        
  1. [root@localhost waf]# cat /tmp/waf_logs/2019-12-20_waf.log
复制代码
      

  • 1.
                       日志表现如下,记录了
                                   登录后复制                        
  1. {"user_agent":"Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/71.0.3573.0 Safari\/537.36","rule_tag":"\\.(bak|inc|old|mdb|sql|backup|java|class|tgz|gz|tar|zip)$","req_url":"\/abc.sql","client_ip":"10.8.80.104","local_time":"2019-12-20 14:37:29","attack_method":"Deny_URL","req_data":"-","server_name":"localhost"}
复制代码
      

  • 1.
                       日志记录了UA、匹配规则、请求URL、客户端IP、当地时间、攻击方法、请求数据和服务器名称。
     13.2. 使用ab压测工具模拟防cc攻击

                                   登录后复制                        
  1. yum -y install httpd-tools
  2. ab -n 1000 -c 500 http://10.8.17.32/
复制代码
      

  • 1.
  • 2.
                       13.3. 模拟ip黑名单

     将请求ip放入ip黑名单中
                                   登录后复制                        
  1. echo "10.8.17.32" >>/usr/local/nginx/conf/waf/rule-config/blackip.rule
复制代码
      

  • 1.
                       13.4. 模拟ip白名单

     将请求ip放入ip白名单中,此时将不对此ip举行任何防护措施,所以sql注入时应该返回404
                                   登录后复制                        
  1. echo "10.8.17.32" >> /usr/local/nginx/conf/waf/rule-config/whiteip.rule
复制代码
      

  • 1.
                       13.5. 模拟URL参数检测

     浏览器输入http://10.8.17.32/?id=select * from name where name="jack"
     具体规定在arg.rule中有规定,对请求举行了规范
     14. 防cc攻击利器之httpgrard

     14.1. httpgrard介绍

     HttpGuard是基于openresty,以lua脚本语言开发的防cc攻击软件。而openresty是集成了高性能web服务器Nginx,以及一系列的Nginx模块,这其中最紧张的,也是我们主要用到的nginx lua模块。HttpGuard基于nginx lua开发,继续了nginx高并发,高性能的特点,可以以非常小的性能消耗来防范大规模的cc攻击。
     14.2. httpgrard防cc殊效

     

  • 限制访客在肯定时间内的请求次数
  • 向访客发送302转向相应头来识别恶意用户,并克制其再次访问
  • 向访客发送带有跳转功能的js代码来识别恶意用户,并克制其再次访问
  • 向访客发送cookie来识别恶意用户,并克制其再次访问
  • 支持向访客发送带有验证码的页面,来进一步识别,以免误伤
  • 支持直接断开恶意访客的毗连
  • 支持结合iptables来克制恶意访客再次毗连
  • 支持白名单功能
  • 支持根据统计特定端口的毗连数来自动开启或关闭防cc模式
     详见github地址 https://github.com/centos-bz/HttpGuard
     15. WAF上线

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

     16.1. FAQ1

     运行报错:
                                   登录后复制                        
  1. nginx: [error] lua_load_resty_core failed to load the resty.core module from https://github.com/openresty/lua-resty-core; ensure you are using an OpenResty release from https://openresty.org/en/download.html (rc: 2, reason: module 'resty.core' not found:
  2. no field package.preload['resty.core']
  3. no file '../lua-resty-core/lib/resty/core.lua'
  4. no file '../lua-resty-lrucache/lib/resty/core.lua'
  5. no file './resty/core.lua'
  6. no file '/usr/local/share/luajit-2.1.0-beta3/resty/core.lua'
  7. no file '/usr/local/share/lua/5.1/resty/core.lua'
  8. no file '/usr/local/share/lua/5.1/resty/core/init.lua'
  9. no file './resty/core.so'
  10. no file '/usr/local/lib/lua/5.1/resty/core.so'
  11. no file '/usr/local/lib/lua/5.1/loadall.so'
  12. no file './resty.so'
  13. no file '/usr/local/lib/lua/5.1/resty.so'
  14. no file '/usr/local/lib/lua/5.1/loadall.so')
复制代码
      

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
                       一旦使用了lua-nginx-module就表现使用了openresty,这个resty.core是openresty的核心模块,对其下的许多函数举行了优化等。之前的一些版本默认是不编译进去的,所以需要你手动安装
     下面是解决该问题的完整步骤:
     

  • 下载lua-resty-core
                                   登录后复制                        
  1. git clone https://github.com/openresty/lua-resty-core.git
复制代码
      

  • 1.
                       

  • 进入lua-resty-core目录
                                   登录后复制                        
  1. cd lua-resty-core
复制代码
      

  • 1.
                       

  • 使用luajit编译
                                   登录后复制                        
  1. export LUAJIT_LIB=/path/to/luajit/lib
  2. export LUAJIT_INC=/path/to/luajit/include/luajit-2.1
  3. make install
复制代码
      

  • 1.
  • 2.
  • 3.
                       注意将/path/to/luajit/lib和/path/to/luajit/include/luajit-2.1更换为现实的luajit库和头文件路径。
     

  • 编辑nginx.conf,在http块中添加
                                   登录后复制                        
  1. lua_package_path "/path/to/lua-resty-core/lib/?.lua;;";
  2. lua_package_cpath "/path/to/lua-resty-core/lib/?.lua;;";
复制代码
      

  • 1.
  • 2.
                       将/path/to/lua-resty-core/lib/更换为现实的lua-resty-core安装路径。
     

  • 重新加载nginx设置
                                   登录后复制                        
  1. nginx -s reload
复制代码
      

  • 1.
                       这样应该就可以解决lua_load_resty_core失败的问题了。如果还是不行,可以检查一下luajit的路径是否正确,lua-resty-core是否安装成功等。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表