在现代 web 应用中,保护服务器免受高频率访问的攻击是非常重要的。高频率的请求可能会给服务器带来巨大的压力,甚至导致服务宕机。本文将介绍如何结合 Nginx、Lua 脚本和 Redis 实现自动封禁访问频率过高的 IP 地址。

环境准备

在开始之前,请确保已安装以下组件:

  1. Nginx:作为反向代理服务器。
  2. Lua 模块:需要在 Nginx 中编译或安装 ngx_http_lua_module
  3. Redis:作为数据存储,用于记录访问频率。

方案概述

我们将通过 Lua 脚本和 Redis 实现以下功能:

  1. 记录每个 IP 的访问频率。
  2. 设置阈值,当某个 IP 的访问次数超过此阈值时,将其加入黑名单。
  3. 每次请求时检查该 IP 是否在黑名单中。

Redis 数据结构

在 Redis 中,我们可以使用 INCR 命令来增加访问计数,并使用 EXPIRE 命令设置过期时间。具体的数据结构如下:

  • 访问计数存储:ip:<client_ip>,值为该 IP 的请求次数。
  • 黑名单存储:blocked_ip:<client_ip>,值为 1(表示被封禁)。

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秒

-- 连接 Redis
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
    ngx.say("failed to connect to Redis: ", err)
    return
end

-- 检查是否被封禁
local blocked_res, err = red:get("blocked_ip:" .. client_ip)
if blocked_res == "1" then
    ngx.exit(ngx.HTTP_FORBIDDEN)  -- 如果被封禁,返回403
end

-- 记录访问次数
local count, err = red:incr("ip:" .. client_ip)
if not count then
    ngx.say("failed to increment IP counter: ", err)
    return
end

-- 设置过期时间
if count == 1 then
    red:expire("ip:" .. client_ip, expire_time)
end

-- 检查访问次数是否超过阈值
if count > max_requests then
    red:set("blocked_ip:" .. client_ip, 1)
    red:expire("blocked_ip:" .. client_ip, 300)  -- 封禁300秒
end

-- 关闭 Redis 连接
red:close()

Nginx 配置

接下来,我们需要在 Nginx 配置文件中使用此 Lua 脚本。

http {
    lua_shared_dict limit_dict 10m;  # 定义共享内存字典

    server {
        listen 80;
        server_name example.com;

        location / {
            access_by_lua_block {
                -- 在此使用上述的 Lua 脚本
            }
            proxy_pass http://backend;
        }
    }
}

运行原理

  1. 当用户请求到达 Nginx 时,access_by_lua_block 会调用 Lua 脚本。
  2. Lua 脚本会检查 IP 是否被封禁,若被封禁,则返回 403。
  3. 否则,记录访问次数并判断是否超过设定的阈值。
  4. 超过阈值后,该 IP 将被加入 Redis 黑名单。

总结

通过结合 Nginx、Lua 和 Redis,我们实现了一个简单而有效的 IP 封禁机制。这种方案不仅提高了服务器的安全性,还能有效防止恶意攻击。在实际应用中,你可以根据具体的场景和需求调整访问频率的限制和封禁策略。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部