最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nginx中Lua腳本實(shí)現(xiàn)動(dòng)態(tài)黑名單自動(dòng)封禁機(jī)制

 更新時(shí)間:2026年04月27日 08:59:36   作者:舞夢(mèng)輝影  
本文主要介紹了Nginx中Lua腳本實(shí)現(xiàn)動(dòng)態(tài)黑名單自動(dòng)封禁機(jī)制,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

為什么直接用 access_by_lua_block 寫封禁邏輯容易失效

因?yàn)?Nginx 的 Lua 模塊(OpenResty)中,access_by_lua_block 階段執(zhí)行時(shí),請(qǐng)求尚未進(jìn)入 upstream 或日志階段,但若后續(xù)有 rewrite_by_lua_block 或其他模塊重寫 URI、跳轉(zhuǎn),可能繞過該階段;更關(guān)鍵的是,它不自動(dòng)阻斷后續(xù)處理——你得顯式調(diào)用 ngx.exit(403),否則腳本跑完就繼續(xù)往下走。

常見錯(cuò)誤現(xiàn)象:ngx.var.remote_addr 被封了,但請(qǐng)求仍能訪問后端;或日志里看到 IP 出現(xiàn)在黑名單里,HTTP 狀態(tài)碼卻是 200。

  • 務(wù)必在封禁分支末尾加 ngx.exit(403),不能只設(shè)變量或?qū)?Redis
  • 如果用了 try_files 或 error_page 重定向,要確認(rèn)它們不會(huì)覆蓋或跳過 access_by_lua_block
  • 避免在 access_by_lua_block 中做耗時(shí)操作(如 HTTP 請(qǐng)求),會(huì)阻塞 worker 進(jìn)程

如何用 Redis + Lua 做毫秒級(jí)黑名單匹配

本地內(nèi)存(如 shared_dict)適合短時(shí)頻控,但跨 worker、跨實(shí)例的黑名單必須依賴外部存儲(chǔ)。Redis 是最常用選擇,關(guān)鍵是用原子操作避免并發(fā)查改導(dǎo)致漏放行。

推薦用 EVAL 執(zhí)行一段內(nèi)聯(lián) Lua 腳本,一次性完成「查是否存在」+「若存在則返回 1」,不依賴兩次網(wǎng)絡(luò)往返:

local exists = redis.call("EXISTS", "blacklist:" .. KEYS[1])
if exists == 1 then
  return 1
else
  return 0
end

在 Nginx 配置中調(diào)用:

access_by_lua_block {
  local red = require "resty.redis"
  local r = red:new()
  r:set_timeout(100)
  local ok, err = r:connect("127.0.0.1", 6379)
  if not ok then
    ngx.log(ngx.ERR, "failed to connect to redis: ", err)
    return
  end
  local ip = ngx.var.remote_addr
  local res, err = r:eval(
    "return redis.call('EXISTS', 'blacklist:' .. ARGV[1])",
    0, ip
  )
  if res == 1 then
    ngx.exit(403)
  end
}
  • 不要用 GET + IF 兩步,競態(tài)下可能剛查完就被刪掉
  • Redis key 建議帶前綴(如 blacklist:)并設(shè)置 TTL,避免長期堆積
  • 連接池比每次新建連接更高效,可用 resty.redis.connect + set_keepalive

怎么讓封禁規(guī)則支持動(dòng)態(tài)更新而不 reload Nginx

reload 會(huì)中斷連接、丟失共享字典狀態(tài),不適合高頻更新的黑名單。真正可行的方式是:把規(guī)則存 Redis,Nginx 每次請(qǐng)求都實(shí)時(shí)查——只要 Redis 響應(yīng)夠快(通常如果你真想降低 Redis 查詢壓力,可以用雙層緩存:先查 shared_dict,未命中再查 Redis,并異步刷新本地緩存(用 lua-resty-lock 防穿透):

local dict = ngx.shared.blacklist_cache
local ip = ngx.var.remote_addr
local cached = dict:get(ip)
if cached == 1 then
  ngx.exit(403)
end
-- 加鎖后查 Redis 并回填
local lock = require "resty.lock":new("locks")
local elapsed, err = lock:lock(ip)
if not elapsed then
  ngx.log(ngx.ERR, "failed to acquire lock: ", err)
  return
end
local red = --[[...redis init...]]
local res, _ = red:eval("return redis.call('EXISTS', 'blacklist:' .. ARGV[1])", 0, ip)
if res == 1 then
  dict:set(ip, 1, 60) -- 緩存 60 秒
  ngx.exit(403)
end
lock:unlock()
  • 別用定時(shí)拉取(如 timer.at)同步 Redis 到 shared_dict,worker 間不同步且易超時(shí)
  • shared_dict 的 TTL 必須比 Redis 的短,否則會(huì)出現(xiàn)“Redis 已解封,本地還攔著”的情況
  • 若業(yè)務(wù)對(duì)延遲極度敏感,考慮用 Redis 的 SCAN + 本地 Bloom Filter 預(yù)篩,但實(shí)現(xiàn)復(fù)雜度陡增

誤封怎么快速放行又不影響線上

最安全的做法是提供獨(dú)立管理接口(比如一個(gè)僅限內(nèi)網(wǎng)訪問的 /api/unban),由運(yùn)維或自動(dòng)化腳本調(diào)用,而不是手動(dòng)改 Redis 或 reload。

示例接口只需一行命令:

location /api/unban {
  allow 10.0.0.0/8;
  deny all;
  content_by_lua_block {
    local ip = ngx.var.arg_ip
    if not ip or #ip == 0 then
      ngx.status = 400
      ngx.say("missing ip")
      return
    end
    local red = require "resty.redis":new()
    red:set_timeout(100)
    red:connect("127.0.0.1", 6379)
    red:del("blacklist:" .. ip)
    red:del("blacklist_cache:" .. ip) -- 清本地緩存
    ngx.say("ok")
  }
}
  • 嚴(yán)禁開放 DEL * 或無白名單的批量操作接口
  • Redis 的 DEL 是原子的,但 shared_dict 清除需各 worker 協(xié)同,所以建議用 key 名一致的命名空間(如都加 blacklist: 前綴),便于腳本批量清理
  • 記錄所有封禁/解封操作到獨(dú)立日志文件(用 ngx.log(ngx.INFO, ...)),排查誤封時(shí)比翻 access.log 直觀得多

實(shí)際部署時(shí)最容易被忽略的是 Redis 連接失敗后的降級(jí)策略——默認(rèn)行為是放行,但有些場景要求“寧可誤殺也不能漏封”,這時(shí)就得在 redis:connect 失敗時(shí)主動(dòng) ngx.exit(503),而不是靜默跳過。這個(gè)決策點(diǎn)不在代碼里,而在你的安全等級(jí)定義中。

到此這篇關(guān)于Nginx中Lua腳本實(shí)現(xiàn)動(dòng)態(tài)黑名單自動(dòng)封禁機(jī)制的文章就介紹到這了,更多相關(guān)Nginx Lua動(dòng)態(tài)黑名單自動(dòng)封禁內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 對(duì)nginx-naxsi白名單規(guī)則詳解

    對(duì)nginx-naxsi白名單規(guī)則詳解

    今天小編就為大家分享一篇對(duì)nginx-naxsi白名單規(guī)則詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Nginx超時(shí)時(shí)間的配置說明

    Nginx超時(shí)時(shí)間的配置說明

    Nginx超時(shí)時(shí)間非常重要,因?yàn)樗鼘⒅苯佑绊懢W(wǎng)站的響應(yīng)速度和用戶體驗(yàn),本文主要介紹了Nginx超時(shí)時(shí)間的配置說明,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • Nginx實(shí)現(xiàn)外網(wǎng)訪問內(nèi)網(wǎng)的步驟詳解

    Nginx實(shí)現(xiàn)外網(wǎng)訪問內(nèi)網(wǎng)的步驟詳解

    外網(wǎng)瀏覽器與內(nèi)網(wǎng)是不通的,但是外網(wǎng)與中間過渡服務(wù)器是通的,中間過渡服務(wù)器與內(nèi)網(wǎng)服務(wù)器是通的,這樣在外網(wǎng)訪問過渡服務(wù)器時(shí),過渡服務(wù)器再跳轉(zhuǎn)到后臺(tái)服務(wù)器,本文給大家介紹了Nginx外網(wǎng)訪問內(nèi)網(wǎng)如何實(shí)現(xiàn)步驟,需要的朋友可以參考下
    2023-10-10
  • nginx配置中$http_host、$host、$host:$proxy_port和$host:$server_port區(qū)別解析

    nginx配置中$http_host、$host、$host:$proxy_port和$host:$server_por

    nginx為了實(shí)現(xiàn)反向代理的需求而增加了一個(gè)ngx_http_proxy_module模塊,其中proxy_set_header指令就是該模塊需要讀取的配置文件,這篇文章主要介紹了nginx配置中$http_host、$host、$host:$proxy_port和$host:$server_port區(qū)別,需要的朋友可以參考下
    2024-03-03
  • nginx作為下載服務(wù)器配置過程

    nginx作為下載服務(wù)器配置過程

    本文詳細(xì)介紹了如何配置Nginx作為下載服務(wù)器,包括基本配置指令、location塊配置、Content-Disposition頭部信息、sendfile指令、文件系統(tǒng)權(quán)限設(shè)置以及訪問控制,通過實(shí)驗(yàn),驗(yàn)證了Nginx在文件下載場景中的高效和安全性
    2025-12-12
  • nginx搭建高可用集群的實(shí)現(xiàn)方法

    nginx搭建高可用集群的實(shí)現(xiàn)方法

    本文主要介紹了nginx搭建高可用集群的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • nginx處理http請(qǐng)求實(shí)現(xiàn)過程解析

    nginx處理http請(qǐng)求實(shí)現(xiàn)過程解析

    這篇文章主要介紹了nginx處理http請(qǐng)求實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • nginx從編譯安裝到配置文件說明中文詳細(xì)介紹

    nginx從編譯安裝到配置文件說明中文詳細(xì)介紹

    Nginx配置文件主要分成四部分:main(全局設(shè)置)、server(主機(jī)設(shè)置)、upstream(上游服務(wù)器設(shè)置,主要為反向代理、負(fù)載均衡相關(guān)配置)和 location(URL匹配特定位置后的設(shè)置)
    2018-10-10
  • nginx proxy_cache批量清除緩存的腳本介紹

    nginx proxy_cache批量清除緩存的腳本介紹

    今天小編就為大家分享一篇關(guān)于nginx proxy_cache批量清除緩存的腳本介紹,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • 一句簡單命令重啟nginx

    一句簡單命令重啟nginx

    最近我的多個(gè)VPS經(jīng)常出現(xiàn)502錯(cuò)誤,經(jīng)常需要重啟nginx,但網(wǎng)上的很多教程都需要繁瑣的啟動(dòng)腳本,遠(yuǎn)不如apache的重啟命令那么簡單。
    2010-03-03

最新評(píng)論

呼伦贝尔市| 津市市| 都安| 洛隆县| 左云县| 神木县| 高雄县| 冕宁县| 交城县| 营山县| 五原县| 贵溪市| 汶上县| 清远市| 宁国市| 晋城| 通江县| 上栗县| 阿勒泰市| 元氏县| 绵竹市| 伊春市| 玉龙| 金坛市| 阜新市| 云阳县| 九台市| 珠海市| 庆安县| 阜阳市| 双流县| 和田市| 长岛县| 广州市| 绿春县| 松桃| 六盘水市| 靖州| 福州市| 山东省| 松阳县|