Nginx使用Lua模块实现WAF
前言:最近一段时间在写加密数据功能,对安全相关知识还是缺少积累,无意间接触到了WAF相关知识,刚好Nginx可以实现WAF功能,也简单学习了Lua这门语言,分享下
一、WAF产生的背景
过去企业通常会采用防火墙,作为安全保障的第一道防线;当时的防火墙只是在第三层(网络层)有效的阻断一些数据包;而随着web应用的功能越来越丰富的时候,Web服务器因为其强大的计算能力,处理性能,蕴含较高的价值,成为主要的被攻击目标(第五层应用层)。而传统防火墙在阻止利用应用程序漏洞进行的攻击方面,却没有办法;在此背景下,WAF(Web Application Firewall)应运而生。
二、什么是WAF
Web 应用防火墙 (WAF-Web Application Firewall) 旨在保护 Web 应用免受各类应用层攻击,例如跨站点脚本 (XSS)、SQL 注入,以及 cookie 中毒等。应用是您重要数据的网关,因此针对应用发起的攻击就成为了造成漏洞的主要原因。有了 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

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
http://192.168.10.132/?id=<script>

总结:Nginx使用Lua模块实现WAF的功能很强大,可以对代码进行修改二次开发,修改成为自己想要的效果,不妨试试看看
Nginx使用Lua模块实现WAF的更多相关文章
- nginx 增加 lua模块
Nginx中的stub_status模块主要用于查看Nginx的一些状态信息. 本模块默认是不会编译进Nginx的,如果你要使用该模块,则要在编译安装Nginx时指定: ./configure –wi ...
- nginx安装lua模块实现高并发
nginx安装lua扩展模块 1.下载安装LuaJIT-2.0.4.tar.gz wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz tar ...
- nginx 安装第三方模块(lua)并热升级
需求: nginx上将特定请求拒绝,并返回特定值. 解决办法: 使用lua脚本,实现效果. 操作步骤: 安装Luajit环境 重新编译nginx(目标机器上nginx -V 配置一致,并新增两个模块n ...
- Nginx与Lua开发
1.Lua及基础语法 Nginx与Lua环境 场景:用Nginx结合Lua实现代码的灰度发布 1.Lua 是一个简洁.轻量.可扩展的脚本语言 2.Nginx+Lua优势 充分的结合Nginx的并发处理 ...
- nginx+lua构建简单waf网页防火墙
需求背景 类似于论坛型的网站经常会被黑掉,除了增加硬件防护感觉效果还是不太好,还会偶尔被黑,waf的功能正好实现了这个需求. waf的作用: 防止sql注入,本地包含,部分溢出,fuzzing测试,x ...
- Nginx + Lua 搭建网站WAF防火墙
前言 对于项目里面只是使用代理等常用功能,在线安装即可,如需制定化模块,则推荐编译安装 PS:本文不仅仅包含Nginx相关的知识点,还包含了逆天学习方法(对待新事物的处理) 官方网站:https:// ...
- mac下Nginx+lua模块编译安装
Nginx的nb之处就不说了,lua也是一个小巧的脚本语言,由标准C编写而成,几乎可以运行在所有的平台上,也非常强大,其他特性请自行度娘.nginx_lua_module是由淘宝的工程师清无(王晓哲) ...
- nginx添加编译lua模块
一 .安装LuaJit 1.下载LuaJit # wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz 2.编译安装 # tar xzvf LuaJI ...
- Nginx详解二十八:Nginx架构篇Nginx+Lua的安全waf防火墙
Nginx+Lua的安全waf防火墙 看一下别人写好的:https://github.com/loveshell/ngx_lua_waf 先安装git:yum -y install git 在/opt ...
随机推荐
- LinkedHashMap 与 LRUcache
LRU 缓存介绍 我们平时总会有一个电话本记录所有朋友的电话,但是,如果有朋友经常联系,那些朋友的电话号码不用翻电话本我们也能记住,但是,如果长时间没有联系了,要再次联系那位朋友的时候,我们又不得不求 ...
- 04.委托Delegation
1. 基本了解 1.1 委托简述 官方文档 委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用,用于将方法作为参数传递给其他方法,可将任何可访问类或结构中与委托类型匹配的任何方法分配给委 ...
- 使用Magicodes.IE快速导出Excel
前言 总是有很多朋友咨询Magicodes.IE如何基于ASP.NET Core导出Excel,出于从框架的体验和易用性的角度,决定对Excel的导出进行独立封装,以便于大家更易于使用,开箱即用. 注 ...
- linux中的dhcp
目录 一.DHCP服务 二.DHCP的租约过程 三.使用DHCP动态配置主机地址 四.安装DHCP服务器 一.DHCP服务 ① DHCP (Dynamic HostConfiguration Prot ...
- Linux命令(六)之防火墙iptables的相关操作以及端口的开放
.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...
- 修改Linux系统的默认语言编码集
RedHat 今天晚上发现服务器上vi的界面提示变成了乱码,只能将XShell的编码改为GBK才能正常显示,导致consolas字体无法使用,GBK编码下的字体丑陋无比,无法忍受,一轮google之后 ...
- jeesite中重启项目时用户头像丢失的疑惑
jeesite中重启项目时用户头像丢失 使用的时候发现,在更换完头像以后,进行页面的刷新会将头像同步给各个位置,但是在系统重新载入的时候,会出现用户的头像加载不出来的情况,还是以demo为例 可以看到 ...
- Redis实现分布式锁那件事
今天我们来聊一聊分布式锁的那些事. 相信大家对锁已经不陌生了,我们在多线程环境中,如果需要对同一个资源进行操作,为了避免数据不一致,我们需要在操作共享资源之前进行加锁操作.在计算机科学中,锁(lock ...
- Sqli-Labs less25-25a
less-25 前置基础知识:后面的关卡涉及到WAF绕过: 主要有三种方式:白盒绕过.黑盒绕过.fuzz测试 网上sql注入WAF绕过的教程有很多,可以自己查询,总之就是比谁思路猥琐 根据第25关下面 ...
- cpu设计实践1
本栏目将实现一个简单cpu(8-32位)的设计,使用xinlink spatan6平台