Nginx實(shí)現(xiàn)動(dòng)態(tài)封禁IP的設(shè)計(jì)方案
環(huán)境準(zhǔn)備
linux version: centos7 / ubuntu 等
redis version: 5.0.5
nginx version: nginx-openresty
設(shè)計(jì)方案
實(shí)現(xiàn) IP 黑名單的功能有很多途徑:
1、在操作系統(tǒng)層面,配置 iptables,來(lái)攔截指定 IP 的網(wǎng)絡(luò)請(qǐng)求。
優(yōu)點(diǎn):簡(jiǎn)單直接,在服務(wù)器物理層面上進(jìn)行攔截
缺點(diǎn):每次需要手動(dòng)上服務(wù)器修改配置文件,操作繁瑣且不靈活
2、在 Web 服務(wù)器層面,通過(guò) Nginx 自身的 deny 選項(xiàng)或者 lua 插件配置 IP 黑名單。
優(yōu)點(diǎn):可動(dòng)態(tài)實(shí)現(xiàn)封禁 ip,通過(guò)設(shè)置封禁時(shí)間可以做到分布式封禁
缺點(diǎn):需要了解 Lua 腳本和 Nginx 配置,有一定的學(xué)習(xí)成本
3、在應(yīng)用層面,在處理請(qǐng)求之前檢查客戶端的 IP 地址是否在黑名單中。
優(yōu)點(diǎn):通過(guò)編寫(xiě)代碼來(lái)實(shí)現(xiàn),相對(duì)簡(jiǎn)單且易于維護(hù)。
缺點(diǎn):代碼可能會(huì)變得冗長(zhǎng),而且在高并發(fā)情況下可能影響性能。
為了方便管理和共享黑名單,通過(guò) nginx + lua + redis 的架構(gòu)實(shí)現(xiàn) IP 黑名單的功能
配置 nginx.conf
在需要進(jìn)行限制的 server 的 location 中添加如下配置:
location / { # 如果該location 下存在靜態(tài)資源文件可以做一個(gè)判斷 #if ($request_uri ~ .*\.(html|htm|jpg|js|css)) { # access_by_lua_file /usr/local/lua/access_limit.lua; #} access_by_lua_file /usr/local/lua/access_limit.lua; # 加上了這條配置,則會(huì)根據(jù) access_limit.lua 的規(guī)則進(jìn)行限流 alias /usr/local/web/; index index.html index.htm; }
配置 lua 腳本
/usr/local/lua/access_limit.lua
-- 可以實(shí)現(xiàn)自動(dòng)將訪問(wèn)頻次過(guò)高的IP地址加入黑名單封禁一段時(shí)間 --連接池超時(shí)回收毫秒 local pool_max_idle_time = 10000 --連接池大小 local pool_size = 100 --redis 連接超時(shí)時(shí)間 local redis_connection_timeout = 100 --redis host local redis_host = "your redis host ip" --redis port local redis_port = "your redis port" --redis auth local redis_auth = "your redis authpassword"; --封禁IP時(shí)間(秒) local ip_block_time= 120 --指定ip訪問(wèn)頻率時(shí)間段(秒) local ip_time_out = 1 --指定ip訪問(wèn)頻率計(jì)數(shù)最大值(次) local ip_max_count = 3 -- 錯(cuò)誤日志記錄 local function errlog(msg, ex) ngx.log(ngx.ERR, msg, ex) end -- 釋放連接池 local function close_redis(red) if not red then return end local ok, err = red:set_keepalive(pool_max_idle_time, pool_size) if not ok then ngx.say("redis connct err:",err) return red:close() end end --連接redis local redis = require "resty.redis" local client = redis:new() local ok, err = client:connect(redis_host, redis_port) -- 連接失敗返回服務(wù)器錯(cuò)誤 if not ok then close_redis(client) ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end --設(shè)置超時(shí)時(shí)間 client:set_timeout(redis_connection_timeout) -- 優(yōu)化驗(yàn)證密碼操作 代表連接在連接池使用的次數(shù),如果為0代表未使用,不為0代表復(fù)用 在只有為0時(shí)才進(jìn)行密碼校驗(yàn) local connCount, err = client:get_reused_times() -- 新建連接,需要認(rèn)證密碼 if 0 == connCount then local ok, err = client:auth(redis_auth) if not ok then errlog("failed to auth: ", err) return end --從連接池中獲取連接,無(wú)需再次認(rèn)證密碼 elseif err then errlog("failed to get reused times: ", err) return end -- 獲取請(qǐng)求ip local function getIp() local clientIP = ngx.req.get_headers()["X-Real-IP"] if clientIP == nil then clientIP = ngx.req.get_headers()["x_forwarded_for"] end if clientIP == nil then clientIP = ngx.var.remote_addr end return clientIP end local cliendIp = getIp(); local incrKey = "limit:count:"..cliendIp local blockKey = "limit:block:"..cliendIp --查詢ip是否被禁止訪問(wèn),如果存在則返回403錯(cuò)誤代碼 local is_block,err = client:get(blockKey) if tonumber(is_block) == 1 then ngx.exit(ngx.HTTP_FORBIDDEN) close_redis(client) end local ip_count, err = client:incr(incrKey) if tonumber(ip_count) == 1 then client:expire(incrKey,ip_time_out) end --如果超過(guò)單位時(shí)間限制的訪問(wèn)次數(shù),則添加限制訪問(wèn)標(biāo)識(shí),限制時(shí)間為ip_block_time if tonumber(ip_count) > tonumber(ip_max_count) then client:set(blockKey,1) client:expire(blockKey,ip_block_time) end close_redis(client)
總結(jié)
以上,便是 Nginx+Lua+Redis 實(shí)現(xiàn)的 IP 黑名單功能,具有如下優(yōu)點(diǎn):
配置簡(jiǎn)單輕量,對(duì)服務(wù)器性能影響小。
多臺(tái)服務(wù)器可以通過(guò)共享 Redis 實(shí)例共享黑名單。
動(dòng)態(tài)配置,可以手工或者通過(guò)某種自動(dòng)化的方式設(shè)置 Redis 中的黑名單
擴(kuò)展
1、IP 黑名單的應(yīng)用場(chǎng)景
IP 黑名單在實(shí)際應(yīng)用中具有廣泛的應(yīng)用場(chǎng)景,主要用于保護(hù)服務(wù)器和應(yīng)用免受惡意攻擊、爬蟲(chóng)或?yàn)E用行為的影響。下面列舉幾個(gè)常見(jiàn)的應(yīng)用場(chǎng)景:
防止惡意訪問(wèn): 黑名單可以阻止那些試圖通過(guò)暴力破 解密碼、SQL 注入、XSS 攻擊等方式進(jìn)行非法訪問(wèn)的 IP 地址。
防止爬蟲(chóng)和數(shù)據(jù)濫用: 黑名單可以限制那些頻繁訪問(wèn)網(wǎng)站并抓取大量數(shù)據(jù)的爬蟲(chóng),以減輕服務(wù)器負(fù)載和保護(hù)數(shù)據(jù)安全。
防止 DDOS 攻擊: 黑名單可以封禁那些發(fā)起大規(guī)模DDoS攻擊的IP地址,保護(hù)服務(wù)器的穩(wěn)定性和安全性。
限制訪問(wèn)頻率: 黑名單可以限制某個(gè)IP在特定時(shí)間段內(nèi)的訪問(wèn)次數(shù),防止惡意用戶進(jìn)行暴力破 解、刷票等行為。
2、高級(jí)功能和改進(jìn)
除了基本的 IP 黑名單功能外,還可以進(jìn)行一些高級(jí)功能和改進(jìn),以提升安全性和用戶體驗(yàn):
異常檢測(cè)和自動(dòng)封禁: 通過(guò)分析訪問(wèn)日志和行為模式,可以實(shí)現(xiàn)異常檢測(cè)功能,并自動(dòng)將異常行為的 IP 地址封禁,提高安全性。
白名單機(jī)制: 除了黑名單,還可以引入白名單機(jī)制,允許某些 IP 地址繞過(guò)黑名單限制,確保合法用戶的正常訪問(wèn)。
驗(yàn)證碼驗(yàn)證: 對(duì)于頻繁訪問(wèn)或異常行為的 IP,可以要求其進(jìn)行驗(yàn)證碼驗(yàn)證,以進(jìn)一步防止惡意行為。
數(shù)據(jù)統(tǒng)計(jì)和分析: 將黑名單相關(guān)的數(shù)據(jù)進(jìn)行統(tǒng)計(jì)和分析,例如記錄封禁 IP 的次數(shù)、持續(xù)時(shí)間等信息,以便后續(xù)優(yōu)化和調(diào)整策略。
通過(guò)不斷改進(jìn)和優(yōu)化 IP 黑名單功能,可以更好地保護(hù)服務(wù)器和應(yīng)用的安全。
到此這篇關(guān)于Nginx實(shí)現(xiàn)動(dòng)態(tài)封禁IP的設(shè)計(jì)方案的文章就介紹到這了,更多相關(guān)Nginx動(dòng)態(tài)封禁IP內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
服務(wù)器使用Nginx部署Springboot項(xiàng)目的詳細(xì)教程(jar包)
這篇文章主要介紹了服務(wù)器使用Nginx部署Springboot項(xiàng)目的詳細(xì)教程(jar包),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07nginx請(qǐng)求時(shí)找路徑問(wèn)題解決
當(dāng)你安裝了nginx的時(shí)候,為nginx配置了如下的location,想要去訪問(wèn)路徑下面的內(nèi)容,可是總是出現(xiàn)404,找不到文件,這是什么原因呢,今天我們就來(lái)解決這個(gè)問(wèn)題,感興趣的朋友一起看看吧2023-10-10升級(jí)nginx支持HTTP/2服務(wù)端推送的方法
這篇文章主要介紹了升級(jí)nginx支持HTTP/2服務(wù)端推送的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05詳解Nginx服務(wù)器中HTTP Headers相關(guān)的模塊配置使用
這篇文章主要介紹了詳解Nginx服務(wù)器中HTTP Headers相關(guān)的模塊配置使用,包括ngx_http_headers_module與它的增強(qiáng)版ngx_headers_more的配置使用講解,需要的朋友可以參考下2016-01-01nginx實(shí)現(xiàn)IP地址透?jìng)鞯氖纠a
默認(rèn)后端服務(wù)器只能看到是前端nginx調(diào)度器訪問(wèn)的本機(jī),本文主要介紹了nginx實(shí)現(xiàn)IP地址透?jìng)鞯氖纠a,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08生產(chǎn)環(huán)境部署Nginx服務(wù)器雙機(jī)熱備部署keepalived的步驟(多種模式教程)
今天演示下生產(chǎn)環(huán)境keepalived的部署方式,安裝模式有很多,比如說(shuō)主備模型和雙主模型,主備分:搶占模式 和 非搶占模式,對(duì)Nginx keepalived 雙機(jī)熱備部署相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧2024-07-07國(guó)外著名論壇程序IPB(Invision Power Board)在nginx下的配置示例
這篇文章主要介紹了國(guó)外著名論壇程序IPB(Invision Power Board)在nginx下的配置示例,使用fastcgi配置模式,需要的朋友可以參考下2014-07-07nginx進(jìn)行端口轉(zhuǎn)發(fā)的實(shí)現(xiàn)
本文主要介紹了nginx進(jìn)行端口轉(zhuǎn)發(fā)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03