—— 目录 ——

  • 1. Lua 和 ngx_lua_waf 简介
  • 2. 前置问题
  • 3. 安装和配置各模块
  • 4. 配置 Nginx
  • 5. 检验是否添加模块成功
  • 6. 配置安全防火墙
  • 7. 详细设置安全防火墙



1. Lua 和 ngx_lua_waf 简介

Lua 是一门轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放
其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

Lua 的应用场景:游戏开发、独立应用脚本、Web 应用脚本、扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench、安全系统,如入侵检测系统

ngx_lua_waf 引用作者原话:
是一个基于 lua-nginx-module(openresty) 的 web 应用防火墙,主要用途是:

防止sql注入,本地包含,部分溢出,fuzzing测试,xss,SSRF等web攻击
防止svn/备份之类文件泄漏
防止ApacheBench之类压力测试工具的攻击
屏蔽常见的扫描黑客工具,扫描器
屏蔽异常的网络请求
屏蔽图片附件类目录php执行权限
防止webshell上传

2. 前置问题

笔者配置的过程中,在启动 nginx 时报了一下错误:

nginx lua 限流 问题 nginx lua waf_nginx


各种找不到文件,一开始还以为是前边俩个模块没安装好,折腾了好一段时间

直到看见一篇排坑的博客,才发现了原来是版本对不上的问题

感谢:nginx 中添加 lua 模块,支持lua脚本以及遇到的坑


3. 安装和配置各模块

安装 lua-nginx-modulengx_devel_kit,注意版本!

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz
tar -zxvf v0.10.9rc7.tar.gz

wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
tar -zxvf v0.3.0.tar.gz

安装 LuaJIT

wget -c http://luajit.org/download/LuaJIT-2.0.5.tar.gz
tar -zxvf LuaJIT-2.0.5.tar.gz
cd LuaJIT-2.0.5
make [后面可跟 PREFIX=/xx/xx 指定安装的路径]
make install [后面可跟 PREFIX=/xx/xx 指定安装的路径(俩个都要写)]

确认安装成功 luajit -v 默认安装(不指定路径)会将 luajit 放到 bin 下
指定路径时不会,需要到安装目录的 bin 下 ./luajit -v

配置环境变量

vim /etc/profile

# 将下边两句加到最后面,路径根据自己设定的路径
# 下边展示的是默认路径
export LUAJIT_LIB=/usr/local/lib  
export LUAJIT_INC=/usr/local/include/luajit-2.0

source /etc/profile

添加软链接映射,并使生效
否则在启动时可能会报找不到的错误,路径依旧按照实际情况

echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

4. 配置 Nginx

如果 nignx 已经在生产环境下了,则只需要重新配置一份 nginx,替换掉原有的 nginx 启动程序就行了
但无论原先有或者没有,都需要一份 nginx 的源代码,原先有的需要下载同版本的 nginx
这里以 nginx-1.20.1 为例进行配置:

# 下载 nginx 源代码
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar -zxvf nginx-1.20.1.tar.gz

进入 nginx 源码目录下,进行配置,增加两个模块(xx 路径是这两个模块所在的全路径)
后面可指定安装路径,添加上 --prefix=/xxx/xxx 指定安装路径

./configure \ 
--add-module=/xxx..xx/lua-nginx-module-0.10.9rc7 \
--add-module=/xxx..xx/ngx_devel_kit-0.3.0

# 编译,没有指定路径的情况下,默认安装在 /usr/local/nginx
make

① 生产环境下配置

▲ 如果 nginx 已经在生产环境下了,不要使用 make install,会破坏原有的 nginx 配置
编译后,在 objs 目录下会产生新的 nginx 启动程序
这里先备份一下,再将新的 nginx 拷贝一份到生产环境

# 先重命名员 nignx
cd /xx..xx/nginx/sbin
mv nginx nginx2

# 进入到源码目录下的 objs
cd /xx..xx/nginx-1.20.1/objs
cp nginx /xx..//nginx/sbin

先停止正在运行的 nginx 程序,然后启动新的没报错就欧了!

./nginx2 -s stop
./nginx

② 从零开始的配置

直接安装就可以了

make install

最后启动 nignx,先进入到 nginx 的 sbin 目录下
执行 ./nginx,没有报错的话,就表示配置成功拉!

cd /xx..xx/nginx/sbin
./nginx

5. 检验是否添加模块成功

首先可以通过 ./nginx -V 来判断,是否有添加俩个模块:

nginx lua 限流 问题 nginx lua waf_waf_02


然后通过实操判断:

conf/nignx.conf 中添加:

server {
	listen	80;
	server_name	localhost;
	location /lua {
		default_type 'text/plain';
		content_by_lua 'ngx.say("hello, lua")';
   	}
	...
}

重新加载 ./nginx -s reload 并访问 curl localhoist/lua 得到下面结果表示成功配置 Lua 模块了!

nginx lua 限流 问题 nginx lua waf_lua_03


6. 配置安全防火墙

安装并配置 ngx_lua_waf 注意要将它安装到 nignx 的 conf 目录下
下载完将其重命名为 waf

wget https://github.com/loveshell/ngx_lua_waf
mv ngx_lua_waf/ waf

修改 config.lua 中的路径:

RulePath = "/xx.xx/conf/waf/wafconf/"

nginx.confhttp 段添加:

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;

● 验收阶段

在浏览器访问 域名/.svn 出现以下提示,说明防火墙配置完毕拉~

nginx lua 限流 问题 nginx lua waf_生产环境_04


如果出现 500,则可能是上面的路径没配置对

在 nginx 的 logs/error.log 下会出现此报错:

[error] 1312#0: *38 lua entry thread aborted: runtime error: /xx.xx/nginx/conf/waf/init.lua:150: bad argument #1 to 'pairs' (table expected, got nil)

重新把 RuleRath 配置成 wafconf 所在的 绝对路径 就好了!


7. 详细设置安全防火墙

接下来就是配置各种规则,增加防火墙的防御力了
注意每次配置完都要重新加载 nginx nginx -s reload

config.lua 配置说明(摘原作者):

--规则存放目录
attacklog = "off"
--是否开启攻击信息记录,需要配置logdir
logdir = "/usr/local/nginx/logs/hack/"
--log存储目录,该目录需要用户自己新建,切需要nginx用户的可写权限
UrlDeny="on"
--是否拦截url访问
Redirect="on"
--是否拦截后重定向
CookieMatch = "on"
--是否拦截cookie攻击
postMatch = "on" 
--是否拦截post攻击
whiteModule = "on" 
--是否开启URL白名单
black_fileExt={"php","jsp"}
--填写不允许上传文件后缀类型
ipWhitelist={"127.0.0.1"}
--ip白名单,多个ip用逗号分隔
ipBlocklist={"1.0.0.1"}
--ip黑名单,多个ip用逗号分隔
CCDeny="on"
--是否开启拦截cc攻击(需要nginx.conf的http段增加lua_shared_dict limit 10m;)
CCrate = "100/60"
--设置cc攻击频率,单位为秒.
--默认1分钟同一个IP只能请求同一个地址100次
html=[[Please go away~~]]
--警告内容,可在中括号内自定义
备注:不要乱动双引号,区分大小写

① 配置攻击信息日志

在 nginx 的 logs 目录下新建日志文件
名字和配置里写的对上就行,这里是 hack 最后需要赋予权限,然后重新加载

mkdir hack
chmod -R 755 hack
nginx -s reload

② 设置白名单和黑名单

如果想要不拦截某些用户的请求无论是否不合法,可以为其设置白名单

ipWhitelist={"127.0.0.1"}

而设置黑名单,则表示拦截改用户的所有请求,无论是否合法

ipBlocklist={"1.0.0.1"}

拦截的效果是直接禁止访问:

nginx lua 限流 问题 nginx lua waf_waf_05

③ 配置防御 CC 攻击

CC (ChallengeCollapsar,挑战黑洞) 攻击是DDoS攻击的一种类型
使用指向受害服务器发送大量貌似合法的请求来导致服务器拒绝服务,是一种连接攻击

CC 攻击又可分为代理 CC 攻击,和肉鸡 CC 攻击
代理 CC 攻击借助的是代理服务器,而肉鸡 CC 攻击是指控制大量肉鸡模拟正常用户访问

启动 CC 攻击防御,在 config.lua 中配置:
以下配置表示,60s 内最多只能访问 2 次(测试用,生产环境自行调整)

CCDeny="on"
CCrate = "2/60"

效果如下:第 3、4 次访问出现图 1,往后在改 60s 内访问出现图 2,60s 过后恢复正常

nginx lua 限流 问题 nginx lua waf_waf_06


nginx lua 限流 问题 nginx lua waf_nginx_07


④ 配置防御 SQL 注入 和 XSS 攻击

SQL 注入和 XSS 工具的防御主要在于检测参数
该检测规则存放在 waf/wafconf/args
默认为我们配置了大部分拦截,有需求可以动态增加,文件内容如下:

\.\./
\:\$
\$\{
select.+(from|limit)
(?:(union(.*?)select))
having|rongjitest
sleep\((\s*)(\d*)(\s*)\)
benchmark\((.*)\,(.*)\)
base64_decode\(
(?:from\W+information_schema\W)
(?:(?:current_)user|database|schema|connection_id)\s*\(
(?:etc\/\W*passwd)
into(\s+)+(?:dump|out)file\s*
group\s+by.+\(
xwork.MethodAccessor
(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(
xwork\.MethodAccessor
(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
java\.lang
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
\<(iframe|script|body|img|layer|div|meta|style|base|object|input)
(onmouseover|onerror|onload)\=

效果测试:以下都会被检测出来并跳转到防火墙页面

域名/lua?id=<script>aaa</script>
域名/lua?id=select * from t_user

爬完山坡履平地(IceClean)