Nginx使用Lua模块实现WAF的原理解析


Posted in Servers onSeptember 04, 2021

前言:最近一段时间在写加密数据功能,对安全相关知识还是缺少积累,无意间接触到了WAF相关知识,刚好Nginx可以实现WAF功能,也简单学习了Lua这门语言,分享下

一、WAF产生的背景

过去企业通常会采用防火墙,作为安全保障的第一道防线;当时的防火墙只是在第三层(网络层)有效的阻断一些数据包;而随着web应用的功能越来越丰富的时候,Web服务器因为其强大的计算能力,处理性能,蕴含较高的价值,成为主要的被攻击目标(第七层应用层)。而传统防火墙在阻止利用应用程序漏洞进行的攻击方面,却没有办法;在此背景下,WAF(Web Application Firewall)应运而生。

二、什么是WAF

Web 应用防火墙 (WAF-Web Application Firewall) 旨在保护 Web 应用免受各类应用层攻击,例如跨站点脚本 (XSS)、SQL 注入,以及 cookie 中毒等。应用是您重要数据的网关,因此针对应用发起的攻击就成为了造成漏洞的主要原因。有了 WAF 就可以拦截一系列企图通过入侵系统来泄漏数据的攻击。

三、工作原理

Nginx使用Lua模块实现WAF的原理解析

1.用户通过浏览器向Web服务器发送网页请求。

2.用户的请求到达Web服务器之前,WAF对用户的请求进行过滤

3.WAF拿到用户的HTTP请求参数去跟配置文件定义的规则做比较(比如ip黑名单),如果匹配上就返回403拒绝,否则就放行。

4.WEB服务器响应用户请求,把页面数据返回给用户。

四、WAF作用

waf是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。

五、WAF和传统防火墙的区别

1.传统防火墙是工作在网络层(第三层)和传输层(第四层)

2.WAF是工作在应用层(第七层)

3.传统防火墙更多是对IP和端口进行过滤

4.WAF是对HTTP请求进行过滤,包括URL,IP,User-Agent等等

六、WAF和DDos

Nginx使用Lua模块实现WAF的原理解析

DDos的全称是Distributed Denial of service。主要依靠一组计算机来发起对一个单一的目标系统的请求,从而造成目标系统资源耗尽而拒绝正常的请求。

根据OSI网络模型,最常见的DDos有三类,第三层(网络层)DDos、第四层(传输层)DDos和第七层(应用层)DDos。

WAF主要处理第七层DDos攻击,它在处理第七层DDos攻击时会比其它防护手段更高效一些。WAF会对HTTP流量做详细的分析,这样WAF就能针对正常的访问请求进行建模,然后使用这些模型来区分正常的请求和攻击者使用机器人或者脚本触发的请求

七、Nginx WAF功能

  • 支持IP白名单和黑名单功能,直接将黑名单的IP访问拒绝(新增cdip功能支持ip段)
  • 支持URL白名单,将不需要过滤的URL进行定义
  • 支持User-Agent的过滤,匹配自定义规则中的条目,然后进行处理
  • 支持CC攻击防护,单个URL指定时间的访问次数,超过设定值(新增针对不同域名)
  • 支持Cookie过滤,匹配自定义规则中的条目,然后进行处理
  • 支持URL过滤,匹配自定义规则中的条目,如果用户请求的URL包含这些
  • 支持URL参数过滤,原理同上
  • 支持日志记录,将所有拒绝的操作,记录到日志中去
  • 新增支持拉黑缓存(默认600秒)

八、Nginx Waf防护流程

if whiteip() then
elseif blockip() then
elseif denycc() then
elseif ngx.var.http_Acunetix_Aspect then
    ngx.exit(444)
elseif ngx.var.http_X_Scan_Memo then
    ngx.exit(444)
elseif whiteurl() then
elseif ua() then
elseif url() then
elseif args() then
elseif cookie() then
elseif PostCheck then

  • 检查IP白名单,通过就不检测;
  • 检查IP黑名单,不通过即拒绝;
  • 检查CC攻击,匹配即拒绝
  • 检查http_Acunetix_Aspect扫描是否开启
  • 检查http_X_Scan_Memo扫描是否开启
  • 检查白名单URL检查;
  • 检查UA,UA不通过即拒绝;
  • 检查URL参数检查;
  • 检查cookie;
  • 检查post;

九、基于Nginx实现的WAF

9.1安装依赖包

yum -y install gcc gcc-c++ autoconf automake make unzip
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel

9.2安装LuaJIT2.0

LuaJIT是Lua的即时编译器,简单来说,LuaJIT是一个高效的Lua虚拟机。

# 进入目录
cd /usr/local/src/
 
# 下载LuaJIT2.0
wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
 
# 解压
tar xf LuaJIT-2.0.5.tar.gz && cd LuaJIT-2.0.5
 
# 编译
make
 
# 安装
make install PREFIX=/usr/local/lj2
 
# 建立软连接
ln -s /usr/local/lj2/lib/libluajit-5.1.so.2 /lib64/
 
# 添加环境变量
export LUAJIT_LIB=/usr/local/lj2/lib/
export LUAJIT_INC=/usr/local/lj2/include/luajit-2.0/

9.3安装ngx_devel_kit

kit模块是一个拓展nginx服务器核心功能的模块,第三方模块开发可以基于它来快速实现。

# 进入目录
cd /user/local/src/
 
# 下载v0.3.0.tar.gz
wget  https://github.com/simplresty/ngx_devel_kit/archive/v0.3.0.tar.gz -O ngx_devel_kit.tar.gz
 
# 解压
tar xf ngx_devel_kit.tar.gz

9.4安装lua-nginx-module

ngx_lua_module 是一个nginx http模块,它把 lua 解析器内嵌到 nginx,用来解析并执行lua 语言编写的网页后台脚本。

ngx_lua模块的原理

1. 每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM;
2. 将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问;
3. 每个外部请求都由一个Lua协程处理,协程之间数据隔离;
4. Lua代码调用I/O操作等异步接口时,会挂起当前协程(并保护上下文数据),而不阻塞worker;
5. I/O等异步操作完成时还原相关协程上下文数据,并继续运行

安装

# 进入目录
cd /user/local/src/
 
# 下载v0.10.9rc7.tar.gz
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz
 
# 解压
tar -xzvf v0.10.9rc7.tar.gz

9.5安装Nginx

# 进入目录
cd /user/local/src/
 
# 下载
wget http://nginx.org/download/nginx-1.21.0.tar.gz
 
# 解压
tar xf nginx-1.21.0.tar.gz
 
# 进入nginx目录
cd nginx-1.21.0
 
# 编译
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module --with-pcre --add-module=/usr/local/src/lua-nginx-module-0.10.9rc7 --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --with-stream
 
# 安装
make && make install
 
# 添加nginx配置,在server块里添加下面内容
[root@localhost_test_192.168.10.132 11:04:48 ~]# vim /usr/local/nginx/conf/nginx.conf
 
location /lua {
    default_type 'text/plain';
 
    content_by_lua 'ngx.say("hello, lua")';
}
 
# 检查语法
[root@localhost_test_192.168.10.132 09:59:33 /usr/local/src]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
 
# 启动
[root@localhost_test_192.168.10.132 11:08:35 ~]# nginx
 
# 测试
curl 127.0.0.1:80/lua

9.6安装ngx_lua_waf

# 进入目录
cd /user/local/src/
 
# 把ngx_lua_waf下载到conf目录下
wget https://github.com/loveshell/ngx_lua_waf/archive/master.zip
 
# 解压命名为waf
unzip master.zip -d /usr/local/nginx/conf/
 
# 更改目录名
mv /usr/local/nginx/conf/ngx_lua_waf-master /usr/local/nginx/conf/waf
 
# 在nginx.conf的http段添加
lua_package_path "/usr/local/nginx/conf/waf/?.lua";
lua_shared_dict limit 10m;
init_by_lua_file  /usr/local/nginx/conf/waf/init.lua;
access_by_lua_file /usr/local/nginx/conf/waf/waf.lua;
 
# 在nginx.conf最外层添加用户运行
user www;
 
# 创建日志目录
mkdir /usr/local/nginx/logs/hack
chown www /usr/local/nginx/logs/hack
 
# Lua_waf 配置
[root@localhost_test_192.168.10.132 11:33:53 /usr/local/nginx/conf/waf]# cat config.lua
# 规则存放路径
RulePath = "/usr/local/nginx/conf/waf/wafconf/"
# 是否开启攻击信息记录,需要配置logdir
attacklog = "on"
# log存储目录,该目录需要用户自己新建,切需要nginx用户的可写权限
logdir = "/usr/local/nginx/logs/hack/"
# 是否拦截url访问
UrlDeny="on"
# 是否拦截后重定向
Redirect="on"
# 是否拦截cookie攻击
CookieMatch="on"
# 是否拦截post攻击
postMatch="on"
# 是否开启URL白名单
whiteModule="on"
# 填写不允许上传文件后缀类型
black_fileExt={"php","jsp"}
# ip白名单,多个ip用逗号分隔
ipWhitelist={"127.0.0.1"}
# ip黑名单,多个ip用逗号分隔
ipBlocklist={"192.168.10.1"}
# 是否开启拦截cc攻击(需要nginx.conf的http段增加lua_shared_dict limit 10m;)
CCDeny="off"
# 设置cc攻击频率,单位为秒.
# 默认1分钟同一个IP只能请求同一个地址100次
CCrate="100/60"
# 告警内容
html= []
 
# 规则文件
[root@localhost_test_192.168.10.132 11:42:12 /usr/local/nginx/conf/waf]# ll wafconf/
total 24
-rw-r--r-- 1 root root 749 Apr  6  2016 args
-rw-r--r-- 1 root root 652 Apr  6  2016 cookie
-rw-r--r-- 1 root root 733 Apr  6  2016 post
-rw-r--r-- 1 root root 335 Apr  6  2016 url
-rw-r--r-- 1 root root 177 Apr  6  2016 user-agent
-rw-r--r-- 1 root root   8 Apr  6  2016 whiteurl
 
args里面的规则get参数进行过滤的
cookie是对请求过滤的cookie过滤
url是只在get请求url过滤的规则
post是只在post请求过滤的规则
whiteurl是白名单,里面的url匹配到不做过滤
user-agent是对user-agent的过滤规则
 
# 加载Nginx
[root@localhost_test_192.168.10.132 11:32:41]# nginx -s reload

9.7测试效果  

访问带有参数的URL

 

Servers 相关文章推荐
使用Apache的rewrite
Mar 09 Servers
Linux安装Nginx步骤详解
Mar 31 Servers
Mac环境Nginx配置和访问本地静态资源的实现
Mar 31 Servers
JVM上高性能数据格式库包Apache Arrow入门和架构详解(Gkatziouras)
May 26 Servers
nginx配置虚拟主机的详细步骤
Jul 21 Servers
学习nginx基础知识
Sep 04 Servers
Nginx 反向代理解决跨域问题多种情况分析
Jan 18 Servers
Apache Hudi 加速传统的批处理模式
Apr 24 Servers
Windows Server 2008配置防火墙策略详解
Jun 28 Servers
Zabbix对Kafka topic积压数据监控的解决方案
Jul 07 Servers
nginx七层负载均衡配置详解
Jul 15 Servers
Nginx如何限制IP访问只允许特定域名访问
Jul 23 Servers
Nginx部署vue项目和配置代理的问题解析
centos8安装nginx1.9.1的详细过程
Aug 02 #Servers
Nginx反向代理至go-fastdfs案例讲解
Aug 02 #Servers
Nginx配置之实现多台服务器负载均衡
Aug 02 #Servers
nginx服务器的下载安装与使用详解
Aug 02 #Servers
nginx反向代理配置去除前缀案例教程
Jul 26 #Servers
nginx结合openssl实现https的方法
You might like
php,不用COM,生成excel文件
2006/10/09 PHP
php图片验证码代码
2008/03/27 PHP
显示youtube视频缩略图和Vimeo视频缩略图代码分享
2014/02/13 PHP
配置php.ini实现PHP文件上传功能
2014/11/27 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
2017/09/17 PHP
[原创]网络复制内容时常用的正则+editplus
2006/11/30 Javascript
JavaScript 精粹读书笔记(1,2)
2010/02/07 Javascript
jQuery替换字符串(实例代码)
2013/11/13 Javascript
javascript日期对象格式化为字符串的实现方法
2014/01/14 Javascript
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
JS实现自定义简单网页软键盘效果代码
2015/11/05 Javascript
基于jquery实现简单的手风琴特效
2015/11/24 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
JS中的Replace()传入函数时的用法详解
2017/09/11 Javascript
Vue 理解之白话 getter/setter详解
2019/04/16 Javascript
JavaScript字符串处理常见操作方法小结
2019/11/15 Javascript
JS 创建对象的模式实例小结
2020/04/28 Javascript
vue element-ui中table合计指定列求和实例
2020/11/02 Javascript
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
python获取局域网占带宽最大3个ip的方法
2015/07/09 Python
Windows下Python使用Pandas模块操作Excel文件的教程
2016/05/31 Python
Python输出各行命令详解
2018/02/01 Python
PyTorch快速搭建神经网络及其保存提取方法详解
2018/04/28 Python
pytorch cnn 识别手写的字实现自建图片数据
2018/05/20 Python
Python使用pymongo模块操作MongoDB的方法示例
2018/07/20 Python
使用Python的toolz库开始函数式编程的方法
2018/11/15 Python
Python File(文件) 方法整理
2019/02/18 Python
python 实现turtle画图并导出图片格式的文件
2019/12/07 Python
css3 media 响应式布局的简单实例
2016/08/03 HTML / CSS
Nicole Miller官方网站:纽约女装品牌
2019/09/14 全球购物
灰雀教学反思
2014/04/28 职场文书
2014法制宣传日活动总结
2014/07/09 职场文书
研究生简历自我评价范文
2014/09/13 职场文书
python3 实现mysql数据库连接池的示例代码
2021/04/17 Python
详解Flutter自定义应用程序内键盘的实现方法
2022/06/14 Java/Android