問題描述:
在項目中碰到用戶刷註冊接口,騙取註冊成功後的一些列獎勵。
達到的要求:
於是安全這邊想要對用戶的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用於存儲黑名單 |