前面提到過,nginx在項(xiàng)目中的作用。其實(shí)還有很多高級(jí)模塊功能,例如今天我們利用OpenResty來(lái)防止一些IP惡意攻擊。
OpenResty® 是一個(gè)基于 Nginx 與 Lua 的高性能 Web 平臺(tái),其內(nèi)部集成了大量精良的 Lua 庫(kù)、第三方模塊以及大多數(shù)的依賴項(xiàng)。用于方便地搭建能夠處理超高并發(fā)、擴(kuò)展性極高的動(dòng)態(tài) Web 應(yīng)用、Web 服務(wù)和動(dòng)態(tài)網(wǎng)關(guān)。
官方地址:http://openresty.org/cn/
環(huán)境搭建
本文使用centos 7進(jìn)行操作,安裝nginx,本處安裝nginx并非是openresty前提,只是為了演示openresty安裝后,訪問地址會(huì)將nginx變成openresty
wget下載
wget http://nginx.org/download/nginx-1.19.5.tar.gz
解壓并執(zhí)行安裝命令
tar -zxvf nginx-1.19.5.tar.gz #解壓
cd nginx-1.19.5 #進(jìn)入目錄
./configure #配置
make #編譯
make install #安裝
cd /usr/local/nginx/sbin #切換到nginx命令目錄
./nginx #啟動(dòng)nginx
訪問地址

安裝openresty,先下載openresty,
wget https://openresty.org/download/openresty-1.19.3.1.tar.gz
(此版本最終一直無(wú)法加載一些lua腳本,最終使用openresty-1.15.8.3版本成功)
(此版本最終一直無(wú)法加載一些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
執(zhí)行完后,我們啟動(dòng)openresty中得nginx,注意,切換到openresty安裝得路徑
/usr/local/openresty/nginx/sbin
啟動(dòng)后,訪問,發(fā)現(xiàn)nginx變成了openresty

配置nginx.conf
測(cè)試lua功能


可以看到已經(jīng)可以使用lua腳本,下面我們將redis sdk引用進(jìn)來(lái)

配置請(qǐng)求路徑訪問lua腳本(本處只是做一個(gè)demo,如果對(duì)所有路徑進(jìn)行訪問限制,可以攔截/,然后lua驗(yàn)證通過后,進(jìn)行請(qǐng)求轉(zhuǎn)發(fā))

lua腳本
# Lua
local function close_redis(redcli)
if not redcli then
return
end
--釋放連接(連接池實(shí)現(xiàn))
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為請(qǐng)求頻率,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次以上訪問即視為非法,會(huì)阻止30s的訪問
redcli:set(blackKey,1)
redcli:expire(blackKey,30)
end
close_redis(redcli)
啟動(dòng)nginx后,請(qǐng)求一直報(bào)錯(cuò)

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"
這個(gè)問題困擾了我很久(凡是不要一上來(lái)就最新版本,吐血說(shuō)明)
windows版本的openresty并沒有出現(xiàn)此問題,liunux一直都有問題,最終降低了openresty版本,實(shí)驗(yàn)成功,openresty-1.15.8.3版本
正常請(qǐng)求

異常請(qǐng)求

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