当前位置: 首页
业界动态
Nginx 动态封禁 IP 实战:从配置到落地全流程

Nginx 动态封禁 IP 实战:从配置到落地全流程

热心网友 时间:2026-04-22
转载

构建动态IP黑名单:Nginx+Lua+Redis实战方案 服务器时不时遭遇恶意爬虫或攻击者的频繁请求,怎么办?一个行之有效的防御策略是建立动态的IP黑名单。简单说,就是把那些“不受欢迎”的IP地址列入名单,在一段时间内拒绝其所有访问请求。这不仅能有效拦截恶意流量,还能灵活设置封禁时长,实现自动化管

构建动态IP黑名单:Nginx+Lua+Redis实战方案

服务器时不时遭遇恶意爬虫或攻击者的频繁请求,怎么办?一个行之有效的防御策略是建立动态的IP黑名单。简单说,就是把那些“不受欢迎”的IP地址列入名单,在一段时间内拒绝其所有访问请求。这不仅能有效拦截恶意流量,还能灵活设置封禁时长,实现自动化管理。

需求与环境准备

我们的目标很明确:搭建一个能够动态更新、支持分布式共享、且对应用性能影响极小的IP黑名单系统。在开始动手前,需要准备好以下环境:

服务器系统: CentOS 7 或 Ubuntu 等主流Linux发行版均可。
Redis版本: 5.0.5 或更高。
Nginx版本: 推荐使用集成Lua模块的OpenResty,它让在Nginx中嵌入Lua逻辑变得轻而易举。

设计方案选型

实现IP黑名单,路子其实不少,各有优劣:

1. 操作系统层面(如iptables)
直接在服务器防火墙上动手。优点是拦截彻底,效果立竿见影。但缺点也很明显:每次操作都得登录服务器手动修改配置,既麻烦又难以应对快速变化的攻击,更别提在多台服务器间同步名单了。

2. Web服务器层面(如Nginx)
利用Nginx自身的deny指令或强大的Lua扩展模块。这个方案的魅力在于“动态化”——可以通过程序逻辑实时更新黑名单,并能方便地设置过期时间。一套配置可以分发到多台Nginx服务器,实现分布式封禁。当然,它需要你稍微了解一下Lua脚本和Nginx配置。

3. 应用层面
在业务代码处理请求前,先检查IP是否在黑名单里。这种方式对开发者最友好,容易理解和维护。但问题在于,它增加了应用的逻辑负担,在高并发场景下可能成为性能瓶颈,而且代码容易变得冗长。

综合来看,为了兼顾灵活性、性能和易管理性,Nginx + Lua + Redis的组合脱颖而出。它利用Redis作为中心化的存储和共享点,通过Lua脚本在Nginx的访问阶段进行高效判断,几乎不影响正常业务响应速度。

架构示意图上图清晰地展示了这个工作流程:请求到达Nginx,由Lua脚本查询Redis中的黑名单,并决定是放行还是拒绝。

配置nginx.conf

配置起来并不复杂。首先,在你需要启用IP黑名单的站点配置中,找到对应的location块,加入一行Lua脚本调用即可。

location / {
    # 如果该location下存在静态资源文件,可以考虑做个判断,避免对静态资源也进行黑名单校验
    # 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; # 关键配置,引入Lua限流脚本
    alias /usr/local/web/;
    index index.html index.htm;
}

这里有个小技巧:如果你的这个location主要存放图片、CSS等静态文件,且攻击主要针对动态接口,可以用if判断(注释部分所示)来减少不必要的Redis查询,进一步提升性能。不过,对于大多数场景,直接全局启用也没问题。

编写核心Lua脚本

接下来是重头戏:编写/usr/local/lua/access_limit.lua脚本。这个脚本负责具体的封禁逻辑,其核心思想是:在单位时间内,如果某个IP的访问次数超过阈值,则将其加入黑名单一段时间。

-- access_limit.lua
-- 目标:自动将访问过频的IP加入黑名单封禁一段时间

-- ---------- 配置区 ----------
local pool_max_idle_time = 10000  -- Redis连接池超时回收时间(毫秒)
local pool_size = 100             -- Redis连接池大小
local redis_connection_timeout = 100 -- Redis连接超时时间(毫秒)

local redis_host = "your redis host ip" -- Redis服务器地址
local redis_port = "your redis port"    -- Redis端口
local redis_auth = "your redis auth password" -- Redis认证密码

local ip_block_time = 120         -- IP被封禁的时长(秒)
local ip_time_out = 1             -- 统计访问频率的时间窗口(秒)
local ip_max_count = 3            -- 时间窗口内允许的最大访问次数
-- ---------- 配置结束 ----------

-- 记录错误日志
local function errlog(msg, ex)
    ngx.log(ngx.ERR, msg, ex)
end

-- 将Redis连接归还至连接池
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 connect 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)
if not ok then
    close_redis(client)
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) -- 连接失败,返回500错误
end

-- 设置超时
client:set_timeout(redis_connection_timeout)

-- 优化:只有新建的连接才需要认证密码
local connCount, err = client:get_reused_times()
if 0 == connCount then
    local ok, err = client:auth(redis_auth)
    if not ok then
        errlog("failed to auth: ", err)
        return
    end
elseif err then
    errlog("failed to get reused times: ", err)
    return
end

-- 获取客户端真实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 clientIp = getIp();
local incrKey = "limit:count:" .. clientIp -- 用于计数器的Key
local blockKey = "limit:block:" .. clientIp -- 用于标记是否封禁的Key

-- 检查IP是否已被封禁
local is_block, err = client:get(blockKey)
if tonumber(is_block) == 1 then
    ngx.exit(ngx.HTTP_FORBIDDEN) -- 如果已被封禁,直接返回403
    close_redis(client)
end

-- IP访问计数:每次访问+1,如果是首次(值为1),设置计数器过期时间
local ip_count, err = client:incr(incrKey)
if tonumber(ip_count) == 1 then
    client:expire(incrKey, ip_time_out)
end

-- 判断:如果计数超过阈值,则设置封禁标识
if tonumber(ip_count) > tonumber(ip_max_count) then
    client:set(blockKey, 1)
    client:expire(blockKey, ip_block_time)
end

-- 操作完成,释放连接
close_redis(client)

这个脚本的逻辑链条非常清晰:获取IP -> 查是否已封禁 -> 统计访问次数 -> 判断是否触发封禁。所有状态都存储在Redis中,因此多台Nginx服务器可以共享同一份黑名单,实现了分布式防护。

方案总结

至此,一个基于Nginx+Lua+Redis的动态IP黑名单系统就搭建完成了。回顾一下,这个方案有几个突出的优点:

1. 轻量高效: 在Nginx的访问阶段进行拦截,对后端应用服务几乎无感,性能损耗极小。
2. 集中管理: 通过Redis集中存储黑名单,任何服务器上的策略变更都能实时同步,管理起来非常方便。
3. 动态灵活: 封禁策略(如时间窗口、阈值、封禁时长)可以通过修改Lua脚本或Redis数据动态调整,无需重启服务。

扩展思考

1. IP黑名单的典型应用场景

这个功能可不是简单的“关门谢客”,它在多种安全防护场景下都能大显身手:

防御恶意扫描与攻击: 有效拦截那些进行密码暴力破解、SQL注入、XSS跨站脚本测试的IP源。
反爬虫与数据保护: 限制恶意爬虫高频抓取数据,既能减轻服务器负载,也能保护核心数据资产。
缓解DDoS攻击: 虽然无法应对海量分布式攻击,但对于小规模或持续性的攻击源,将其IP加入黑名单可以快速切断流量,为其他防护措施争取时间。
业务风控: 例如,限制同一IP在秒杀活动中的抢购次数,或者在投票系统中防止刷票。

2. 高级功能与优化方向

基础功能实现后,还可以在此基础上做更多文章,让防护体系更智能、更健壮:

智能异常检测与自动封禁: 结合日志分析,可以建立更复杂的模型。例如,不仅检测访问频率,还分析访问路径、User-Agent等特征,自动识别并封禁有异常行为的IP。
引入白名单机制: 有黑就有白。将可信的IP(如公司出口IP、合作伙伴IP)加入白名单,确保其访问永远不会被误拦截,这对于运维和内部测试至关重要。
验证码挑战: 对于可疑但又不确定是恶意攻击的IP(例如频率略高于阈值),可以不直接封禁,而是弹出验证码进行人机验证。通过则正常访问,失败则加入黑名单。
数据统计与分析: 将黑名单的触发记录、封禁时长、IP来源等信息进行统计和分析。这些数据是优化防护策略的宝贵依据,能帮你回答诸如“攻击主要来自哪个地区?”“哪种攻击模式最常见?”等问题。

安全防护是一个持续的过程。通过不断迭代和优化IP黑名单策略,你可以为服务器和应用构筑起一道更加灵活、智能的动态防线。

来源:https://server.51cto.com/article/837353.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
先导智能交付海外首条全极耳圆柱电芯产线助推欧洲豪车电气化转型

先导智能交付海外首条全极耳圆柱电芯产线助推欧洲豪车电气化转型

先导智能成功交付海外首条全极耳圆柱电芯产线,用于欧洲顶尖豪华车品牌德国诺德林根电池工厂。产线搭载自研智能系统,实现单电芯100%在线溯源,AI视觉检测识别潜在风险,焊接不良率和运营成本均降低30%。

时间:2026-07-11 15:04
八位堂Xbox机械键盘新版新增RGB背光

八位堂Xbox机械键盘新版新增RGB背光

八位堂推出Retro87机械键盘Xbox版,采用初代Xbox透明绿外壳,首次加入RGB背光,提供八种模式。键盘为87键布局,搭载凯华JellyfishX开关,内置2000mAh电池,续航达200小时。同步发布RetroR8鼠标,配备PAW3395传感器和充电底座。键盘现已在亚马逊开启预售,售价119 99美元,2025年1月16日发货。

时间:2026-07-11 15:03
天硕V60 256GB SD卡 高速稳定的卓越品质 开启存储新境界

天硕V60 256GB SD卡 高速稳定的卓越品质 开启存储新境界

天硕V60256GBSD卡具备256GB容量,读取260MB s、写入150MB s,支持4K60P视频录制。采用长江存储闪存与自研主控,达到IP68三防等级,兼容主流相机,集成纠错编码与磨损均衡技术,为专业影像创作提供可靠存储方案。

时间:2026-07-11 15:03
i扫地机器人全球热销 高端市场占有率30%

i扫地机器人全球热销 高端市场占有率30%

杉川机器人全球高端扫地机器人市场占有率达30%,获广东省制造业单项冠军。公司全球出货超千万台,拥有多项专利。其净水循环与空气制水技术实现终生不用加清水、倒污水,突破传统使用瓶颈。

时间:2026-07-11 15:03
荣耀笔记本X Plus系列全新配色定档12月2日

荣耀笔记本X Plus系列全新配色定档12月2日

荣耀笔记本XPlus系列将于12月2日发布,推出浅海蓝新配色,搭配银色品牌标识,主打轻薄机身。该系列首发搭载酷睿第二代英特尔酷睿5处理器,续航提升。荣耀CEO预告明年将全面布局PC领域。同期荣耀300系列也将发布。

时间:2026-07-11 15:03
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜