【Nginx】使用 Nginx+Lua 實現基于 IP 的訪問頻率限制

使用 Nginx+Lua 實現基于 IP 的訪問頻率限制

在高并發場景下,限制某個 IP 的訪問頻率是非常重要的,可以有效防止惡意攻擊或錯誤配置導致的服務宕機。以下是一個詳細的實現方案,使用 Nginx 和 Lua 腳本結合 Redis 來實現基于 IP 的訪問頻率限制。

1.環境準備

在開始之前,請確保已安裝以下組件:

? Nginx:作為反向代理服務器。

? Lua 模塊:需要在 Nginx 中編譯或安裝ngx_http_lua_module

? Redis:作為數據存儲,用于記錄訪問頻率。

2.方案概述

我們將通過 Lua 腳本和 Redis 實現以下功能:

? 記錄每個 IP 的訪問頻率。

? 設置閾值,當某個 IP 的訪問次數超過此閾值時,將其加入黑名單。

? 每次請求時檢查該 IP 是否在黑名單中。

3.Redis 數據結構

在 Redis 中,我們可以使用以下數據結構:

? 訪問計數存儲:ip:<client_ip>,值為該 IP 的請求次數。

? 黑名單存儲:blocked_ip:<client_ip>,值為 1(表示被封禁)。

4.Lua 腳本示例

以下是一個完整的 Lua 腳本示例,用于實現訪問頻率限制和封禁邏輯:

local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)  -- 1秒超時-- 獲取客戶端 IP
local client_ip = ngx.var.remote_addr
local max_requests = 100  -- 設置最大請求次數
local expire_time = 60    -- 設置過期時間為60秒
local block_time = 300    -- 設置封禁時間為300秒-- 連接 Redis
local ok, err = red:connect("127.0.0.1", 6379)
if not ok thenngx.say("failed to connect to Redis: ", err)return
end-- 檢查是否被封禁
local blocked_res, err = red:get("blocked_ip:" .. client_ip)
if blocked_res == "1" thenngx.exit(ngx.HTTP_FORBIDDEN)  -- 如果被封禁,返回403
end-- 記錄訪問次數
local count, err = red:incr("ip:" .. client_ip)
if not count thenngx.say("failed to increment IP counter: ", err)return
end-- 設置過期時間
if count == 1 thenred:expire("ip:" .. client_ip, expire_time)
end-- 檢查訪問次數是否超過閾值
if count > max_requests thenred:set("blocked_ip:" .. client_ip, 1)red:expire("blocked_ip:" .. client_ip, block_time)  -- 封禁300秒ngx.exit(ngx.HTTP_FORBIDDEN)  -- 返回403
end-- 關閉 Redis 連接
red:close()

5.Nginx 配置

接下來,我們需要在 Nginx 配置文件中使用此 Lua 腳本。

http {lua_shared_dict limit_dict 10m;  # 定義共享內存字典server {listen 80;server_name example.com;location / {access_by_lua_block {-- 在此使用上述的 Lua 腳本local script = [[local redis = require "resty.redis"local red = redis:new()red:set_timeout(1000)  -- 1秒超時-- 獲取客戶端 IPlocal client_ip = ngx.var.remote_addrlocal max_requests = 100  -- 設置最大請求次數local expire_time = 60    -- 設置過期時間為60秒local block_time = 300    -- 設置封禁時間為300秒-- 連接 Redislocal ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.say("failed to connect to Redis: ", err)returnend-- 檢查是否被封禁local blocked_res, err = red:get("blocked_ip:" .. client_ip)if blocked_res == "1" thenngx.exit(ngx.HTTP_FORBIDDEN)  -- 如果被封禁,返回403end-- 記錄訪問次數local count, err = red:incr("ip:" .. client_ip)if not count thenngx.say("failed to increment IP counter: ", err)returnend-- 設置過期時間if count == 1 thenred:expire("ip:" .. client_ip, expire_time)end-- 檢查訪問次數是否超過閾值if count > max_requests thenred:set("blocked_ip:" .. client_ip, 1)red:expire("blocked_ip:" .. client_ip, block_time)  -- 封禁300秒ngx.exit(ngx.HTTP_FORBIDDEN)  -- 返回403end-- 關閉 Redis 連接red:close()]]ngx.execute_lua(script)}proxy_pass http://backend;}}
}

6.測試

? 啟動 Redis:

   redis-server

? 啟動 Nginx:

   nginx -s reload

? 訪問測試:

? 使用瀏覽器或工具(如curl)訪問你的 Nginx 服務。

? 在 60 秒內多次訪問,觀察是否觸發封禁邏輯。

7.注意事項

? 連接池:

? 在生產環境中,建議使用連接池來管理 Redis 連接,避免頻繁建立和關閉連接。

? 錯誤處理:

? 在 Lua 腳本中,確保對 Redis 連接失敗等錯誤進行適當的處理,避免影響正常服務。

? 性能優化:

? 根據實際需求調整max_requestsexpire_timeblock_time等參數,以達到最佳性能。

總結

通過結合 Nginx、Lua 和 Redis,我們實現了一個簡單而有效的基于 IP 的訪問頻率限制機制。這種方案不僅提高了服務器的安全性,還能有效防止惡意攻擊。在實際應用中,你可以根據具體的場景和需求調整訪問頻率的限制和封禁策略。希望這些方法和示例對你有所幫助!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908754.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908754.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908754.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

華為OD機考-機房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的區別while (in.hasNextLine()) { // 注意 while 處理多個 caseSystem.out.println(solve(in.nextLine()));}}priv…

Server - 使用 Docker 配置 PyTorch 研發環境

歡迎關注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/148421901 免責聲明&#xff1a;本文來源于個人知識與公開資料&#xff0c;僅用于學術交流&#xff0c;歡迎討論&#xff0c;不支持轉載。 建議使…

HarmonyOS5.0——CodeGenie:鴻蒙生態的AI編程革命?

??CodeGenie&#xff1a;鴻蒙生態的AI編程革命?? 華為推出的 ??CodeGenie?? 是集成于 DevEco Studio 的 AI 輔助編程工具&#xff0c;專為 HarmonyOS 應用開發設計。它通過深度優化 ArkTS 和 C 語言的代碼生成能力&#xff0c;顯著提升開發效率&#xff0c;降低鴻蒙生…

大模型模型部署和暴露接口

創建環境 激活案件 安裝相關依賴 conda create -n fastApi python3.10 conda activate fastApi conda install -c conda-forge fastapi uvicorn transformers pytorch pip install safetensors sentencepiece protobuf 新建文件夾 mkdir App cd App touch main.py 復制代碼…

Redis初入門

Nosql&#xff1a;Not-Only SQL&#xff08;泛指非關系型數據庫&#xff09;&#xff0c;作為關系型數據庫的補充 作用&#xff1a;應對基于海量用戶和海量數據前提下的數據處理問題 redis&#xff1a;C語言開發的一個開源的高性能鍵值對數據庫 特征&#xff1a; 1、數據之…

【原神 × 二叉樹】角色天賦樹、任務分支和圣遺物強化路徑的算法秘密!

【原神 二叉樹】角色天賦樹、任務分支和圣遺物強化路徑的算法秘密! 作者:星之辰 標簽:#原神 #二叉樹 #天賦樹 #任務分支 #圣遺物強化 #算法科普 發布時間:2025年6月 總字數:6000+ 一、引子:提瓦特大陸的“樹型奧秘” 你是否曾留意過《原神》角色面板的天賦樹? 升級技能…

C++信息學競賽中常用函數的一般用法

在C 信息學競賽中&#xff0c;有許多常用函數能大幅提升編程效率。下面為你介紹一些常見函數及其一般用法&#xff1a; 一、比較函數 1、max()//求出a&#xff0c;b的較大值 int a10,b5,c;cmax(a,b);//得出的結果就是c等于10. 2、min()//求出a&#xff0c;b的較小值 int a1…

Linux【3】-----系統框架概述

系統架構 文件系統 linux一定需要掛載操作系統 一切皆文件 三個文件 引導文件 uboot.bin內核鏡像 zImage文件系統鏡像 system.img 設備樹文件&#xff08;屬于內核&#xff09; 應用程序編程 arm中通過軟中斷實現 各程序的構成 文件I/O 5種I/O模型 阻塞非阻塞信號多…

Tensorrt python api 10.11.0筆記

關于Tensorrt的python api文檔閱讀翻譯加總結 文檔源地址 Overview Getting started with TensorRT Installation(安裝) 安裝可參考:官方地址 Samples 關于樣例的內容可參考:樣例地址 Operator Documentation 有關更多信息&#xff08;包括示例&#xff09;&#xff0…

電鍍機的陽極是什么材質?

知識星球&#xff08;星球名&#xff1a;芯片制造與封測技術社區&#xff0c;點擊加入&#xff09;里的學員問&#xff1a;電鍍的陽極有什么講究&#xff1f;什么是可溶性陽極和非可溶性陽極&#xff1f; 什么是可溶性陽極與非可溶性陽極&#xff1f; 可溶性陽極 陽極本身就是…

前段三劍客之JavaScript-02

目錄 簡介 核心 函數 字符串對象 事件 運算符和控制語句 DOM 正則表達式 BOM JSON 簡介 JavaScript由JavaScript語法&#xff0c;DOM和BOM組成 JS中提供了一些輸入輸出語句&#xff1a; alert(); //瀏覽器彈出警示框 console.log(); //控制臺打印 prompt(); //瀏覽器…

Qiskit:量子計算模擬器

參考文獻&#xff1a; IBM Qiskit 官網Qiskit DocumentationQiskit Benchpress packageQiskit Algorithms package量子計算&#xff1a;基本概念常見的幾類矩陣&#xff08;正交矩陣、酉矩陣、正規矩陣等&#xff09;Qiskit 安裝指南-博客園使用Python實現量子電路模擬&#x…

【Elasticsearch】Elasticsearch 核心技術(二):映射

Elasticsearch 核心技術&#xff08;二&#xff09;&#xff1a;映射 1.什么是映射&#xff08;Mapping&#xff09;1.1 元字段&#xff08;Meta-Fields&#xff09;1.2 數據類型 vs 映射類型1.2.1 數據類型1.2.2 映射類型 2.實際運用案例案例 1&#xff1a;電商產品索引映射案…

serv00 ssh登錄保活腳本-郵件通知版

適用于自己有服務器情況&#xff0c;ssh定時登錄到serv00&#xff0c;并在登錄成功后發送郵件通知 msmtp 和 mutt安裝 需要安裝msmtp 和 mutt這兩個郵件客戶端并配置&#xff0c;參考如下文章前幾步是講配置這倆客戶端的&#xff0c;很簡單&#xff0c;不再贅述 用Shell腳本實…

前端 Electron 桌面應用學習筆記

前端 Electron 桌面應用學習筆記 介紹Electron是什么?為什么選擇Electron?創建你的第一個桌面應用程序啟動項目運行結果截圖打開調試面板方法生命周期函數常用配置配置窗口標題配置小圖標隱藏菜單欄關閉調試面板是否可以使用Node.js隱藏 Electron 標題、小圖標和菜單欄獲取窗…

LeetCode - 94. 二叉樹的中序遍歷

題目 94. 二叉樹的中序遍歷 - 力扣&#xff08;LeetCode&#xff09; 什么是中序遍歷 二叉樹的中序遍歷是按照"左-根-右"的順序訪問二叉樹中的所有節點。 具體過程&#xff1a; 先遍歷左子樹&#xff08;遞歸&#xff09;然后訪問根節點最后遍歷右子樹&#xff…

PyTorch——搭建小實戰和Sequential的使用(7)

import torch from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass TY(nn.Module):def __init__(self):"""初始化TY卷積神經網絡模型模型結構&#xff1a;3層卷積池化&#xff0c;2層全連接設計目標&#xff1a;處理32x32像素的…

C#、VB.net——如何設置窗體應用程序的外邊框不可拉伸

以Visual studio 2015為例&#xff0c;具體操作如下&#xff1a; 1、將窗體的“FormBorderStyle”屬性值修改為“FixedSingle”&#xff1a; 2、點擊“格式”——“鎖定控件”&#xff1a; 這樣生成的程序邊框即可固定住&#xff0c;無法拉伸。

深入了解NIO的優化實現原理

網絡 I/O 模型優化 網絡通信中&#xff0c;最底層的就是內核中的網絡 I/O 模型了。隨著技術的發展&#xff0c;操作系統內核的網絡模型衍生出了五種 I/O 模型&#xff0c;《UNIX 網絡編程》一書將這五種 I/O 模型分為阻塞式 I/O、非阻塞式 I/O、I/O 復用、信號驅動式 I/O 和異步…

【前端】vue3性能優化方案

以下是Vue 3性能優化的系統性方案&#xff0c;結合核心優化策略與實用技巧&#xff0c;覆蓋渲染、響應式、加載、代碼等多個維度&#xff1a; ?? 一、渲染優化 精準控制渲染范圍 v-if vs v-show&#xff1a; v-if&#xff1a;條件為假時銷毀DOM&#xff0c;適合低頻切換場景&…