【Openresty】实现防刷机制

923 阅读2分钟

安装Openresty

1 下载离线安装包和创建配置文件

官网下载页 选择合适的版本(我的是centos7 选择的是 openresty-1.15.8.3.tar.gz)

  • 解压
  tar -xzvf openresty-1.15.8.3.tar.gz   
  cd openresty-1.15.8.3/
  ./configure
  make
  sudo make install
  • 创建工作目录
 mkdir work
 cd  work
 mkdir logs
 mkdir conf

  • 创建Nginx配置文件
  cd word/conf
  vim nginx.conf
  worker_processes  1;
  error_log logs/error.log;
  events {
      worker_connections 1024;
  }
  http {
      server {
          listen 8989;
          location / {
              default_type text/html;
              content_by_lua_block {
                  ngx.say("<p>hello, world</p>")
              }
          }
          location /login {
               default_type 'text/html';
               access_by_lua_file "/opt/openresty-1.15.8.3/work/conf/access_by_redis.lua";
               content_by_lua_block {
                    ngx.say("ok: ")
                }
           }
      }
  }
  • 创建Lua文件
  vim  access_by_redis.lua
p_bind_time = 30  --封禁IP多长时间
ip_time_out = 6    --指定统计ip访问频率时间范围
connect_count = 10 --指定ip访问频率计数最大值
--上面的意思就是6秒内访问超过10次,自动封 IP 30秒

  ----连接redis
local redis = require "resty.redis"
local cache = redis.new()
local ok , err = cache.connect(cache,"192.168.103.107","6379")
cache:set_timeout(6000)
--
----如果连接失败,跳转到脚本结尾
if not ok then
  goto Lastend
end
--
--  --查询ip是否在封禁段内,若在则返回403错误代码
--  --因封禁时间会大于ip记录时间,故此处不对ip时间key和计数key做处理
is_bind , err = cache:get("bind_"..ngx.var.remote_addr)

if is_bind == '1' then
  ngx.exit(ngx.HTTP_FORBIDDEN)
  -- 或者 ngx.exit(403)
  -- 当然,你也可以返回500错误啥的,搞一个500页面,提示,亲您访问太频繁啥的。
  goto Lastend
end
  
start_time , err = cache:get("time_"..ngx.var.remote_addr)
ip_count , err = cache:get("count_"..ngx.var.remote_addr)
  
 --如果ip记录时间大于指定时间间隔或者记录时间或者不存在ip时间key则重置时间key和计数key
 --如果ip时间key小于时间间隔,则ip计数+1,且如果ip计数大于ip频率计数,则设置ip的封禁key为1
 --同时设置封禁key的过期时间为封禁ip的时间--
if start_time == ngx.null or os.time() - start_time > ip_time_out then
  res , err = cache:set("time_"..ngx.var.remote_addr , os.time())
  res , err = cache:set("count_"..ngx.var.remote_addr , 1)
else
 ip_count = ip_count + 1
 res , err = cache:incr("count_"..ngx.var.remote_addr)
 if ip_count >= connect_count then
  res , err = cache:set("bind_"..ngx.var.remote_addr,1)
  res , err = cache:expire("bind_"..ngx.var.remote_addr,ip_bind_time)
  --fix keys
 end
end
--结尾标记
::Lastend::

启动Openresty

1 配置环境变量

  • 方法一(暂时生效) 直接运行命令
export PATH=/usr/local/openresty/nginx/sbin:$PATH
  • 方法二(只对当前登陆用户生效,永久生效)
 vim ~/.bash_profile  
 export PATH=/usr/local/openresty/nginx/sbin:$PATH
 source ~/.bash_profile
  • 方法三(永久生效,所有用户)
 vim /etc/profile
 export PATH=/usr/local/openresty/nginx/sbin:$PATH
 source /etc/profile
  • 启动命令
 nginx -p `/opt/openresty-1.15.8.3/work` / -c conf/nginx.conf