openresty加lua脚本实现在nginx层的ip拦截

问题描述:

在项目中碰到用户刷注册接口,骗取注册成功后的一些列奖励。

达到的要求:

于是安全这边想要对用户的IP做一个过滤,做一套黑名单与白名单过滤,同时限制用户在1分钟内注册的次数。

使用的方案:

决定采用openresty加lua脚本,在nginx层面对用户ip做拦截过滤。

 

具体实施方案:

原理图:

黑白名单查询逻辑:

 

环境搭建:

总述

操作名称

具体操作

搭建openresty

1、下载openresty

下载地址:http://openresty.org/cn/download.html

(这里使用openresty-1.13.6.2.tar.gz

2、解压openresty

将下载的openresty-1.13.6.2.tar.gz包上传到服务器的/apps/svr路径下,并解压tar –xzvf openresty-1.13.6.2.tar.gz

3、修改openresty的默认配置信息

cd /apps/svr/openresty-1.13.6.2目录下,输入命令:

./configure --prefix=/apps/svr/openresty

(这里只简单改了下路径)

4、编译

gmake

(有的服务器命令是make)

5、安装

gmake install

(/apps/svr/目录下出现openresty文件夹即表示安装成功)

6、修改nginx.conf配置文件

cd  /apps/svr/openresty/nginx/conf目录下,rm –rf nginx.conf删除原有的nginx.conf配置文件。接着将已有的配置文件复制过来。

cp /apps/svr/nginx-1.9.12/conf/nginx.conf  /apps/svr/openresty/nginx/conf/

7、新建lua脚本文件

在/apps/svr/openresty/nginx/目录下输入命令mkdir thirdlua新建thirdlua,并在thirdlua中新建lua文件operateip.lua文件。

8、编写operateip.lua脚本

local REDIS_HOST = "127.0.0.1"

local REDIS_PORT = "6379"

 

local REDIS_CONN_TIMEOUT = 3

local WHITEIPS_KEY = "ip_white"

local BLACKIPS_KEY = "ip_black"

local LIMITIPS_KEY = "ip_limit"

 

local ip = ngx.var.remote_addr

local redis = require "resty.redis";

local red=redis:new();

 

function ignoreWhitelist(ip)

         local exists = red:exists(WHITEIPS_KEY);

         if tonumber(exists) == 1 then

                   exists = red:sismember(WHITEIPS_KEY,ip);

                   if tonumber(exists) == 1 then

                         ngx.log(ngx.INFO," this is white ip ");

                            return true;

                   end

        end

        return false;

end

 

function checkBlacklist(ip)

         local exists = red:exists(BLACKIPS_KEY);

         if tonumber(exists) == 1 then

                   exists = red:sismember(BLACKIPS_KEY,ip);

                   if tonumber(exists) == 1 then

                         ngx.log(ngx.INFO," this is black ip ");

                            return true;

                   end

        end

        return false;

end

 

function limitIpFrequency(ip, times)

         local exists = red:exists(LIMITIPS_KEY..ip);

         ngx.log(ngx.INFO," exists ",exists);

        if tonumber(exists) == 0 then

                   red:zincrby(LIMITIPS_KEY..ip,1,ip);

                   red:expire(LIMITIPS_KEY..ip,60);

        else

                 local count = red:zscore(LIMITIPS_KEY..ip,ip);

                 ngx.log(ngx.INFO,count);

                 if count then

                            if tonumber(count)  > times then

                return true;

                            end

                 end

                   red:zincrby(LIMITIPS_KEY..ip, 1,ip);

        end

         return false;

end

 

ngx.log(ngx.DEBUG,"remote_addr is ",ip);

red:set_timeout(REDIS_CONN_TIMEOUT);

local ok,err = red:connect(REDIS_HOST,REDIS_PORT);

if not ok then

         ngx.log(ngx.INFO,"redis connection error ");

else

    local hit = false;

    flg = ignoreWhitelist(ip);

    if flg==false then

       flg = checkBlacklist(ip);

       if flg==true then

                 return ngx.exit(ngx.HTTP_NOT_FOUND);

       else

                 flg = limitIpFrequency(ip,5);

                 if flg==true then

                          return ngx.exit(ngx.HTTP_NOT_FOUND);

                 end

       end

    end

end

 

ok, err = red:set_keepalive(1000,100);

if not ok then

        red:close();

end

 

9、上传lua脚本

在/apps/svr/openresty/nginx/目录下输入命令mkdir thirdlua新建thirdlua

10、配置lua脚本

在/apps/svr/openresty/nginx/conf/nginx.conf文件中添加如下配置信息

location /login/login.do {

           proxy_pass   http://ip/login/login.do;

           access_by_lua_file thirdlua/operateip.lua;

        }

 

搭建redis

1、下载redis

下载地址:https://redis.io/download

(这里用redis-3.2.12.tar.gz)

2、解压redis包

将下载的redis-3.2.12.tar.gz 包上传到服务器的/apps/svr路径下,并解压tar –xzvf redis-3.2.12.tar.gz

3、编译

cd /apps/svr/redis-3.2.12 输入编译命令:make

4、启动redis

cd /apps/svr/redis-3.2.12/src 输入./redis-server启动redis服务

 

运营维护

1、添加白名单集合

在redis中新建set集合ip_white用于存储白名单

2、添加黑名单集合

在redis中新建set集合ip_black用于存储黑名单

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值