评论

收藏

[Nginx] 通过OpenResty实现Nginx动态拉黑IP

web服务器 web服务器 发布于:2021-08-08 22:28 | 阅读数:552 | 评论:0

前面提到过,nginx在项目中的作用。其实还有很多高级模块功能,例如今天我们利用OpenResty来防止一些IP恶意攻击。
OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
官方地址:http://openresty.org/cn/
环境搭建
本文使用centos 7进行操作,安装nginx,本处安装nginx并非是openresty前提,只是为了演示openresty安装后,访问地址会将nginx变成openresty
wget下载
wget http://nginx.org/download/nginx-1.19.5.tar.gz
DSC0000.png

解压并执行安装命令
tar -zxvf nginx-1.19.5.tar.gz #解压 
cd nginx-1.19.5 #进入目录 
./configure #配置 
make #编译 
make install #安装 
cd /usr/local/nginx/sbin #切换到nginx命令目录 
./nginx #启动nginx
访问地址
DSC0001.png 安装openresty,先下载openresty,
wget https://openresty.org/download/openresty-1.19.3.1.tar.gz 
(此版本最终一直无法加载一些lua脚本,最终使用openresty-1.15.8.3版本成功)
(此版本最终一直无法加载一些lua脚本,最终使用openresty-1.15.8.3版本成功)
DSC0002.png 解压&安装
tar -zxvf openresty-1.19.3.1.tar.gz 
cd openresty-1.19.3.1 
yum install pcre-devel openssl-devel gcc curl  
./configure 
make 
make install
执行完后,我们启动openresty中得nginx,注意,切换到openresty安装得路径
/usr/local/openresty/nginx/sbin
启动后,访问,发现nginx变成了openresty
DSC0003.png 配置nginx.conf
测试lua功能
DSC0004.png DSC0005.jpg 可以看到已经可以使用lua脚本,下面我们将redis sdk引用进来
DSC0006.png 配置请求路径访问lua脚本(本处只是做一个demo,如果对所有路径进行访问限制,可以拦截/,然后lua验证通过后,进行请求转发)
DSC0007.png lua脚本
# Lua 
local function close_redis(redcli) 
  if not redcli then 
    return 
  end 
  --释放连接(连接池实现) 
  local pool_max_idle_time = 10000 --毫秒 
  local pool_size = 100 --连接池大小 
  local ok, err = redcli:set_keepalive(pool_max_idle_time, pool_size) 
 
  if not ok then 
    ngx_log(ngx_ERR, "set redis keepalive error : ", err) 
  end 
end 
 
-- 连接redis 
local redis = require('resty.redis') 
local redcli = redis.new() 
redcli:set_timeout(1000) 
 
local ip = "127.0.0.1"  ---修改变量 
local port = "6379" ---修改变量 
local ok, err = redcli:connect(ip,port) 
if not ok then 
  return close_redis(redcli) 
end 
 
local clientIP = ngx.var.remote_addr 
 
-- increKey为请求频率,blackKey黑名单key 
local incrKey = "user:"..clientIP..":request:frequency" 
local blackKey = "user:"..clientIP..":black:list" 
 
local is_black,err = redcli:get(blackKey) 
 
if tonumber(is_black) == 1 then 
  ngx.exit(403) 
  close_redis(redcli) 
end 
 
inc  = redcli:incr(incrKey) 
 
ngx.say(inc) 
 
if inc < 2 then 
   inc = redcli:expire(incrKey,1) 
end 
 
if inc > 2 then --每秒2次以上访问即视为非法,会阻止30s的访问 
  redcli:set(blackKey,1) 
  redcli:expire(blackKey,30) 
end 
 
close_redis(redcli)
启动nginx后,请求一直报错
DSC0008.png
2020/12/01 19:13:53 [error] 2101#0: *2 lua entry thread aborted: runtime error: /usr/local/openresty/nginx/lua/access_by_redis.lua:29: attempt to call field 'get_headers' (a nil value) 
stack traceback: 
coroutine 0: 
    /usr/local/openresty/nginx/lua/access_by_redis.lua: in main chunk, client: 192.168.49.1, server: localhost, request: "GET /test1 HTTP/1.1", host: "192.168.49.131"
这个问题困扰了我很久(凡是不要一上来就最新版本,吐血说明)
windows版本的openresty并没有出现此问题,liunux一直都有问题,最终降低了openresty版本,实验成功,openresty-1.15.8.3版本
正常请求
DSC0009.png 异常请求
DSC00010.png 最后openresty的运行周期图如下,可以从整体上了解openresty
DSC00011.png

原文地址:https://www.toutiao.com/i6901200619571364356/

关注下面的标签,发现更多相似文章