前面提到過,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
解壓并執行安裝命令
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
訪問地址

安裝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版本成功)

解壓&安裝
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

配置nginx.conf
測試lua功能


可以看到已經可以使用lua腳本,下面我們將redis sdk引用進來

配置請求路徑訪問lua腳本(本處只是做一個demo,如果對所有路徑進行訪問限制,可以攔截/,然后lua驗證通過后,進行請求轉發)

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后,請求一直報錯

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版本
正常請求

異常請求

最后openresty的運行周期圖如下,可以從整體上了解openresty
原文地址:https://www.toutiao.com/i6901200619571364356/