Nginx 实现动态封禁IP,详细教程来了

:2024年11月14日 Java面试那些事儿
分享到:

使用 Nginx 实现动态封禁 IP,防止恶意爬虫、暴力破解和 SQL 注入等攻击,可采用两种方案:操作系统层面的拦截(iptables)或 Web 服务器层面的拦截(Nginx + Lua)。

聊一个我最近处理的技术难题——如何用 Nginx 实现动态封禁 IP,防止一些讨厌的爬虫或者恶意用户对你的网站进行恶意攻击。

想必大家也遇到过那些爬虫一遍又一遍疯狂请求服务器,吃掉了大量的带宽资源,或者有些恶意用户尝试用暴力破解方式登陆,着实让人头疼。

幸好,Nginx 和 Lua 结合 Redis,给我们提供了一个既高效又灵活的方案。

1. 背景与需求

有时候,你的服务器会遭遇一些恶意的攻击,常见的就是爬虫、暴力破解、SQL 注入,甚至 DDoS 攻击。

这些行为不仅增加了服务器负担,还可能导致资源浪费,甚至直接造成服务中断。解决这些问题的一种方式就是通过 IP 封禁,尤其是对于那些恶意访问频繁的 IP 地址。封禁的策略应该是动态的,可以随时添加和移除 IP,同时还要控制封禁的时长,以避免误伤正常用户。

我们希望通过以下几个步骤来实现这个目标:

  1. 封禁爬虫与恶意用户请求:识别并封禁那些频繁请求且行为恶意的 IP 地址。

  2. 建立动态 IP 黑名单:这个黑名单需要能动态更新,支持实时封禁。

  3. 封禁失效时间设置:封禁的 IP 不可能永远存在黑名单中,我们需要设置一个失效时间,自动解封。

2. 方案设计

解决这个问题的方案有好几种,每种方法都有其优缺点。

我们可以从操作系统、Web 服务器或应用层面入手,选择适合的技术栈。下面我们分析一下每种方案。

方法 1:操作系统层面的拦截(iptables)

iptables 是 Linux 系统自带的防火墙工具,通过它可以轻松封禁 IP。不过,这种方式的缺点是操作繁琐且不灵活。每当需要动态封禁某个 IP 时,我们得手动去操作,不太适合自动化管理。而且,这样的封禁是全局生效的,一旦添加了黑名单中的 IP,它就完全无法访问服务器,除非手动移除。

方法 2:Web 服务器层面的拦截(Nginx + Lua)

这种方法是我们今天的重点,利用 Nginx 的 Lua 模块配合 Redis,可以非常灵活地动态封禁 IP。Nginx 负责处理请求,Lua 脚本在请求到来时判断 IP 是否需要封禁,而 Redis 则用来存储 IP 黑名单和封禁时长。

这个方法的优点是:

  • 动态封禁:我们可以设置一个超时机制,自动解封被封禁的 IP。

  • 分布式管理:通过 Redis 存储黑名单,可以在多台服务器间共享数据,方便管理。

  • 灵活性:可以对封禁策略进行动态调整,甚至支持高级的 IP 限制和行为监控。

缺点是:我们需要了解 Nginx 配置、Lua 脚本编写以及 Redis 的使用。

方法 3:应用层面的拦截(代码实现)

这种方法通过在应用层直接判断 IP 是否在黑名单中来控制访问。实现起来简单直观,但性能不如前两者。每当一个请求到来时,代码会去查询黑名单,这对于高并发场景可能会带来一定的性能压力。

3. Nginx + Lua + Redis 方案实现

接下来,我们深入讲解如何通过 Nginx 配合 Lua 脚本以及 Redis 实现动态 IP 封禁。首先,我们需要确保系统已经安装了 Lua 和 Redis,并且 Nginx 已经配置了 Lua 模块。

djEvbXU5ekRaMEZXZF9XR0ZjVUZGMHZyVWUxcmNVOHlULWtRcmVoTURpbW4yQWRZa1g5X0dEblRXYmhVYmI4aU1rRUVFWHZyRVoyVmpSMDF2YWRzS3pNVWxfNl9ya2oxaXk1bVZqR01XNzhoSjQ9.jpg

Nginx 配置

首先,在 Nginx 配置文件中,我们需要启用 Lua 模块,并且指定 Lua 脚本来处理访问控制。修改 nginx.conf 配置文件,在需要处理请求的 location 块中添加 Lua 脚本调用。

http {
    lua_shared_dict limit_req_zone 10m;  # 用来存放 Redis 连接池
    server {
        listen 80;
        location / {
            set $limit 0;
            access_by_lua_file /etc/nginx/lua/access_limit.lua;  # 引用 Lua 脚本
        }
    }
}

Lua 脚本实现(access_limit.lua)

接下来我们实现 access_limit.lua 脚本,主要完成以下几个任务:

  1. 连接 Redis。

  2. 获取请求中的客户端 IP 地址。

  3. 判断该 IP 是否在黑名单中。

  4. 如果不在黑名单中,则记录访问次数;如果在黑名单中,则拒绝请求。

local redis = require "resty.redis"  -- 引入 Redis 库
local red = redis:new()  -- 创建 Redis 对象
red:set_timeout(1000)  -- 设置连接超时时间为 1 秒
-- 连接到 Redis 服务器
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
    ngx.log(ngx.ERR, "failed to connect to Redis: ", err)
    return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
-- 获取客户端 IP 地址
local client_ip = ngx.var.remote_addr
-- 检查该 IP 是否在黑名单中
local res, err = red:get("blacklist:" .. client_ip)
if res == "1" then
    ngx.log(ngx.ERR, "IP " .. client_ip .. " is blacklisted")
    return ngx.exit(ngx.HTTP_FORBIDDEN)
end
-- 如果 IP 不在黑名单中,则统计访问次数
local visits, err = red:get("visits:" .. client_ip)
if visits == ngx.null then
    visits = 0
end
visits = visits + 1
-- 如果访问次数超过设定阈值,则加入黑名单
if visits > 10 then  -- 设定的阈值为 10 次请求
    red:set("blacklist:" .. client_ip, 1)
    red:expire("blacklist:" .. client_ip, 3600)  -- 设置封禁时长为 1 小时
end
-- 更新访问次数
red:set("visits:" .. client_ip, visits)
red:expire("visits:" .. client_ip, 60)  -- 设置过期时间为 1 分钟

这个脚本通过 Redis 存储访问数据并动态判断是否需要封禁 IP。如果某个 IP 在短时间内超过了访问次数限制(比如 10 次),它就会被封禁 1 小时。

Redis 配置与连接

在这段 Lua 脚本中,我们通过 resty.redis 模块连接 Redis 服务器。Redis 在这里充当了一个缓存的角色,用来存储每个 IP 的访问次数和黑名单信息。使用 Redis 的好处是它具有高性能、易于扩展且支持分布式管理。

4. 方案总结

通过 Nginx + Lua + Redis,我们可以高效地实现 IP 封禁策略。这个方案的优点在于:

  • 配置简单,且无需改变业务代码。

  • 适合高并发的场景,对性能影响较小。

  • 支持动态配置,封禁时长可以灵活调整。

  • Redis 支持分布式管理,可以扩展到多台服务器。

此外,Redis 还可以用于实现更多高级功能,例如 IP 访问频率限制、暴力破解防护等。

5. 扩展与高级功能

除了基本的封禁功能,Nginx + Lua + Redis 还可以扩展为更强大的安全防护系统。例如:

  • 异常检测与自动封禁:通过分析访问日志,检测异常访问模式,自动封禁异常 IP。

  • 白名单机制:对于一些可信的 IP,可以设置白名单,让它们绕过封禁规则。

  • 验证码验证:对频繁访问的 IP 提供验证码验证,进一步阻止恶意访问。

  • 数据统计与分析:记录封禁的数据,通过分析日志来优化封禁策略。

总之,Nginx 与 Lua 脚本的结合,使得动态封禁 IP 成为一个简单而灵活的解决方案,不仅能有效防止恶意访问,还可以根据需要进行扩展与优化。

原文来源:https://mp.weixin.qq.com/s/exNdmfbyX48QoDtdVLdOtQ

[我要纠错]
文:宋聪乔&发表于江苏
关键词: 一个 最近 处理 技术 难题

来源:本文内容搜集或转自各大网络平台,并已注明来源、出处,如果转载侵犯您的版权或非授权发布,请联系小编,我们会及时审核处理。
声明:江苏教育黄页对文中观点保持中立,对所包含内容的准确性、可靠性或者完整性不提供任何明示或暗示的保证,不对文章观点负责,仅作分享之用,文章版权及插图属于原作者。

点个赞
0
踩一脚
0

您在阅读:Nginx 实现动态封禁IP,详细教程来了

Copyright©2013-2024 JSedu114 All Rights Reserved. 江苏教育信息综合发布查询平台保留所有权利

苏公网安备32010402000125 苏ICP备14051488号-3技术支持:南京博盛蓝睿网络科技有限公司

南京思必达教育科技有限公司版权所有   百度统计

最热文章
最新文章
  • 卡尔蔡司镜片优惠店,镜片价格低
  • 苹果原装手机壳