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用於存儲黑名單

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章