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 相关文章推荐
Nginx+Tomcat实现负载均衡、动静分离的原理解析
Mar 31 Servers
nginx搭建图片服务器的过程详解(root和alias的区别)
Mar 31 Servers
nginx配置虚拟主机的详细步骤
Jul 21 Servers
在Windows Server 2012上安装 .NET Framework 3.5 所遇到的问题
Apr 29 Servers
Nginx限流和黑名单配置
May 20 Servers
GPU服务器的多用户配置方法
Jul 07 Servers
Nginx代理Redis哨兵主从配置的实现
Jul 15 Servers
详解apache编译安装httpd-2.4.54及三种风格的init程序特点和区别
Jul 15 Servers
SpringBoot前端后端分离之Nginx服务器下载安装过程
Aug 14 Servers
修改Nginx配置返回指定content-type的方法
Sep 23 Servers
Fluentd搭建日志收集服务
Sep 23 Servers
CentOS7设置ssh服务以及端口修改方式
Dec 24 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 方便水印和缩略图的图形类
2009/05/21 PHP
php抓取页面的几种方法详解
2013/06/17 PHP
PHP的curl实现get,post和cookie(实例介绍)
2013/06/17 PHP
php cookie用户登录的详解及实例代码
2017/01/03 PHP
php实现通过soap调用.Net的WebService asmx文件
2017/02/27 PHP
YII框架模块化处理操作示例
2019/04/26 PHP
PHP常见过waf webshell以及最简单的检测方法
2019/05/21 PHP
制作特殊字的脚本
2006/06/26 Javascript
Stop SQL Server
2007/06/21 Javascript
js每次Title显示不同的名言
2008/09/25 Javascript
javascript中tostring()和valueof()的用法及两者的区别
2015/11/16 Javascript
JavaScript学习笔记之ES6数组方法
2016/03/25 Javascript
JavaScript中数组Array方法详解
2017/02/27 Javascript
webpack实现热更新(实施同步刷新)
2017/07/28 Javascript
详解JSONObject和JSONArray区别及基本用法
2017/10/25 Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变opacity实现)
2019/01/24 Javascript
小程序中英文混合排序问题解决
2019/08/02 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
[00:49]完美世界DOTA2联赛10月28日开团时刻:随便打
2020/10/29 DOTA
详解python3中socket套接字的编码问题解决
2017/07/01 Python
Python爬虫小技巧之伪造随机的User-Agent
2018/09/13 Python
python 计算平均平方误差(MSE)的实例
2019/06/29 Python
在python中实现同行输入/接收多个数据的示例
2019/07/20 Python
深入了解python中元类的相关知识
2019/08/29 Python
python读取dicom图像示例(SimpleITK和dicom包实现)
2020/01/16 Python
解决python pandas读取excel中多个不同sheet表格存在的问题
2020/07/14 Python
基于CentOS搭建Python Django环境过程解析
2020/08/24 Python
HTML5移动端开发中的Viewport标签及相关CSS用法解析
2016/04/15 HTML / CSS
美国在线家具网站:GDFStudio
2021/03/13 全球购物
优秀大学生推荐信范文
2013/11/28 职场文书
环保建议书300字
2014/05/14 职场文书
自主招生自荐信格式范文
2015/03/25 职场文书
乡镇团代会开幕词
2016/03/04 职场文书
2019财务管理制度最新范本!
2019/07/09 职场文书
浅谈MySQL表空间回收的正确姿势
2021/10/05 MySQL
Python简易开发之制作计算器
2022/04/28 Python