1. 下载openresty
在官方网站下载最新openresty,比如1.19.9.1
官方网站/
可以下载
2. 安装依赖软件包
yum install readline-devel pcre-devel openssl-devel
主要是考虑后面要用到等
3. 安装OpenResty
1.将下载的 openresty-1.19.9.1.tar.gz 上传linux服务器指定目录比如
当然如果机器联网 也可以wget 命令下载
wget
2.解压openresty-1.19.9.1.tar.gz
tar zxf openresty-1.19.9.1.tar.gz
3. 编译
首先cd 到上面解压的目录
cd openresty-1.19.9.1
执行编译命令
./configure --prefix=/usr/local/openresty-1.19.9.1 --with-luajit --with-
prefix 指定 安装目录,我安装后的目录就在 /usr/local/openresty-1.19.9.1
4. make
编译后 直接make
5. make install
执行 make install
6. 通过以上步骤完成安装,安装后的openresty-1.19.9.1 查看
4. 测试 OpenResty和运行Lua
vim /usr/local/openresty-1.19.9.1/nginx/conf/nginx.conf
#在默认的server配置中增加 location /hello { default_type text/html; content_by_lua_block { ngx.say("<p>hello, world</p>") } }
验证 nginx 配置是否OK
/usr/local/openresty-1.19.9.1/nginx/sbin/nginx -t
5. 部署WAF
下载 waf 地址
将下载压缩包上传linux 服务器
复制waf 文件到/usr/local/openresty-1.19.9.1/nginx/conf 目前下
修改nginx 配置
#在
#WAF
lua_shared_dict limit 50m;
lua_package_path "/usr/local/openresty-1.19.9.1/nginx/conf/waf/?.lua";
init_by_lua_file "/usr/local/openresty-1.19.9.1/nginx/conf/waf/init.lua";
access_by_lua_file "/usr/local/openresty-1.19.9.1/nginx/conf/waf/access.lua";
修改后的nginx
lualib 做软连接 (****** 这个很关键)
ln -s /usr/local/openresty-1.19.9.1/lualib/resty/ /usr/local/openresty-1.19.9.1/nginx/conf/waf/resty
执行后会在waf目录下面 多个软连接
修改 waf 目录下的config.lua
文件路径
/usr/local/openresty-1.19.9.1/nginx/conf/waf
修改规则配置路径。确保和当前安装文件路径一致。
检查nginx 配置
/usr/local/openresty-1.19.9.1/nginx/sbin/nginx -t
重启nginx 生效
6. 验证waf
我们请求非法的带sql url
请求出现当前安全拦截页面,证明安全防护是OK的
默认安装好的页面openresty 欢迎页面
1.注意事项
启动nginx,会报如下错误。
/usr/local/openresty/nginx/sbin/nginx
解决:lualib 做软连接
ln -s /usr/local/openresty/lualib/resty/ /usr/local/openresty/nginx/conf/waf-master/waf/resty
当前waf 文件下面多了一个resty 软连接
通过以上步骤实现openresty+waf 网站防护,有时候我们经常需要拦截一些非法请求,将非法IP 拦截写入黑名单中。按照之前的步骤我们可以修改waf 的blackip.rule 实现。但是发现有个问题,这个文件需要手动添加,另外修改后需要重启。我们知道在实际生产过程中保证系统的高可用nginx是很少重启的。能不能实现动态IP 黑名单功能呢?答案是肯定的。
7. 修改代码 增加一个读取redis 函数
function get_rule_new(rule_name) --Configuration --Redis最大超时 local redis_timeout = 1000; --Redis地址 local redis_location = "192.168.*.83"; --Redis端口 local redis_port = 6379; --Redis密码 local redis_password = "******"; --Redis库序号 local redis_table = 1; --Code local redis = require "resty.redis"; local red = redis:new(); red:set_timeout(redis_timeout); local _,err1 = red:connect(redis_location, redis_port); if err1 then ngx.log(ngx.DEBUG, "Redis Error: " .. err1); red:set_keepalive(1000, 200); return {}; end red:auth(redis_password); red:select(redis_table); local ip_list, err2 = red:smembers(rule_name); if err2 then ngx.log(ngx.DEBUG, "Redis Error: " .. err2); red:set_keepalive(1000, 200); return {}; end red:set_keepalive(1000, 200) return ip_list;end在调用地方修改
function black_ip_check() if config_black_ip_check == "on" then local IP_BLACK_RULE = get_rule('blackip.rule') local BLACK_IP = get_client_ip() if IP_BLACK_RULE ~= nil then for _,rule in pairs(IP_BLACK_RULE) do if rule ~= "" and rulematch(BLACK_IP,rule,"jo") then log_record('BlackList_IP',ngx.var_request_uri,"_","_") if config_waf_enable == "on" then ngx.exit(403) return true end end end end endend替换成上面读取redis 方式
function black_ip_check() if config_black_ip_check == "on" then local IP_BLACK_RULE = get_rule_new('blackip.rule') local BLACK_IP = get_client_ip() if IP_BLACK_RULE ~= nil then for _,rule in pairs(IP_BLACK_RULE) do if rule ~= "" and rulematch(BLACK_IP,rule,"jo") then log_record('BlackList_IP',ngx.var_request_uri,"_","_") if config_waf_enable == "on" then ngx.exit(403) return true end end end end endend将rule-config 文件夹下面
更新到redis 里面,换句话说,读取文件方式替换成读取redis方式
下面里面黑名单案例测试动态获取IP 实现禁用访问和启用访问模式
下面我们测试一下 效果
黑名单中没有禁用访问
在redis 添加本机IP :172.xx.xxx.91
刷新页面,里面起作用了。
总结,在实际项目过程中我们可以利用nginx日志请求 通过logstack 收集请求日志写入的ELK中,再结合大数据和算法判断当前请求是否非法,每 5-10分钟就行一次计算最终判定是否非正常用户请求,把IP写入到redis中实现防护。防止爬虫软件或黑客攻击行为对当前系统进行破坏。感兴趣的小伙伴可以关注我,后期我会根据需要分享 利用大数据+算法实现动态防护。
参考文献: