Nginx实现动态封禁IP的步骤指南

2025-02-25 17:50

本文主要是介绍Nginx实现动态封禁IP的步骤指南,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Nginx实现动态封禁IP的步骤指南》在日常的生产环境中,网站可能会遭遇恶意请求、DDoS攻击或其他有害的访问行为,为了应对这些情况,动态封禁IP是一项十分重要的安全策略,本篇博客将介绍如何通过NG...

1、简述

在日常的生产环境中,网站可能会遭遇恶意请求、DDOS 攻击或其他有害的访问行为。为了应对这些情况,动态封禁 IP 是一项十分重要的安全策略。本篇博客将介绍如何通过 NGINX 实现动态封禁 IP,从配置到自动化的实现步骤。

2、实现方式

NGINX 本身支持简单的基于 IP 的访问控制(如 deny 和 allow 指令),但要实现动态封禁,通常结合以下几种方案:

  • fail2ban:一个常用的自动封禁工具,通过监控日志发现恶意行为并自动修改 NGINX 配置文件。
  • nginx 动态模块:如 ngx_http_limit_req_module 和 ngx_http_limit_conn_module,用于限制请求频率和并发数,结合脚本实现 IP 封禁。
  • 基于 Redis数据库的方案:可以通过 Lua 脚本或第三方模块,从 Redis 或 mysql 等存储中动态加载封禁的 IP 列表。

3、使用 fail2ban 动态封禁

fail2ban 是一种常见的动态封禁工具,通过监控日志文件中的恶意行为自动更新 NGINX 配置。下面是通过 fail2ban 实现动态封禁的步骤。

3.1 安装 fail2ban

sudo apt-get update
sudo apt-get install fail2ban

3.2 配置 NGINX 日志

确保 NGINX 配置中的日志能记录恶意请求。以下是一个简单的日志配置:

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    Access_log  /var/log/nginx/access.log  main;
}

3.3 配置 fail2ban 规则

创建 NGINX 的过滤规则,编辑 /etc/fail2ban/filter.d/nginx-http-auth.conf,加入以下规则来匹配日志中的恶意行为:

[Definition]
failrezWkIcxtLYgex = ^<HOST> -.*"(GET|POST).*HTTP/.*".* 403
ignoreregex =

3.4 设置 fail2ban 的 jail 配置

在 /etc/fail2ban/jail.local 文件中,增加对 NGINX 的监控配置:

[nginx-http-auth]
enabled  = true
port     = http,https
filter   = nginx-http-auth
logpath  = /var/log/nginx/access.log
maxretry = 5
  • logpath:指向 NGINX 的日志文件。
  • maxretry:设置多少次失败后封禁 IP。

3.5 启动 fail2ban

sudo service fail2ban restart

这样,当某个 IP 连续访问 5 次 403 页面时,它将被自动封禁。

4、使用 NGINX 的 limit 模块动态限制

NGINX 自带的 ngx_http_limit_req_module 和 ngx_http_limit_conn_module 可以用于动态限制请求。通过设置请求频率和并发连接数,可以有效抵御恶意爬虫和 DDoS 攻击。

4.1 配置请求频率限制

在 NGINX 配置中加入以下代码来限制每个 IP 的请求频率:

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        location / {
            limit_req zone=one burst=5;
        }
 zWkIcxtLY   }
}
  • limit_req_zone:定义一个共享内存区域,用于记录请求速率。
  • rate=1r/s:每个 IP 限制为每秒最多 1 次请求。

4.2 动态调整限制

要用 Redis 和 Lua 实现动态封禁恶意 IP 的功能,可以借助 Redis 的计数和过期特性。在 Redis 中,可以用 Lua 脚本来动态检测某个 IP 的请求频率,一旦超过设定的阈值,就对该 IP 进行封禁。

以下是一个 Lua 脚本的样例,用于封禁恶意 IP。假设我们会在 Redis 中记录每个 IP 的请求次数,并在达到限制后进行封禁。以下 Lua 脚本实现了上述逻辑,设定了一个限制:IP 在 60 秒内请求 10 次以上会触发封禁,封禁持续 3600 秒(1 小时):

-- Lua 脚本实现动态封禁恶意IP
local ip = KEYS[1]                -- 传入的 IP 地址
local max_requests =python tonumber(ARGV[1]) -- 最大请求次数
local ban_time = tonumber(ARGV[2])     -- 封禁持续时间
local expire_time = tonumber(ARGV[3])  -- IP 计数的过期时间

-- 构建 Redis 键
local ip_key = "ip:" .. ip
local ban_key = "ban:" .. ip

-- 检查 IP 是否已封禁
if redis.call("EXISTS", ban_key) == 1 then
    return {false, "IP 已封禁"}
end

-- 增加 IP 请求计数
local count = redis.call("INCR", ip_key)

-- 如果是首次请求,设置请求计数的过期时间
if count == 1 then
    redis.call("EXPIRE", ip_key, expire_time)
end

-- 检查请求次数是否超过最大请求限制
if count > max_requests then
    -- 达到限制,封禁 IP 并设置封禁时间
    redis.call("SET", ban_key, "1")
    pythonredis.call("EXPIRE", ban_key, ban_time)
    return {false, "已达请求限制,IP 已封禁"}
end

-- 如果请求未超限,返回当前请求计数
return {true, count}

要在 Redis 中执行这个 Lua 脚本,你可以通过 Redis 客户端执行 EVAL 命令。假设 IP 地址是 192.168.0.1,请求限制为 10 次,封禁时间为 3600 秒,计数过期时间为 60 秒:

EVAL "<LUA_SCRIPT>" 2 192.168.0.1 10 3600 60

5、总结

通过以上方法,可以实现 NGINX 下的动态封禁 IP,从而有效保护网站免受恶意攻击。在实际应用中,可以根据需求选择 fail2ban 或 NGINX 自带的模块,甚至结合数据库方案实现更复杂的动态封禁机制。

这篇博客为初学者提供了 NGINX 实现动态封禁 IP 的思路和具体配置示例。你可以根据业务场景灵活调整参数,提升系统安全性。

到此这篇关于Nginx实现动态封禁IP的步骤指南的文章就介绍到这了,更多相关Nginx动态封禁IP内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于Nginx实现动态封禁IP的步骤指南的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153541

相关文章

Java中实现订单超时自动取消功能(最新推荐)

《Java中实现订单超时自动取消功能(最新推荐)》本文介绍了Java中实现订单超时自动取消功能的几种方法,包括定时任务、JDK延迟队列、Redis过期监听、Redisson分布式延迟队列、Rocket... 目录1、定时任务2、JDK延迟队列 DelayQueue(1)定义实现Delayed接口的实体类 (

将java程序打包成可执行文件的实现方式

《将java程序打包成可执行文件的实现方式》本文介绍了将Java程序打包成可执行文件的三种方法:手动打包(将编译后的代码及JRE运行环境一起打包),使用第三方打包工具(如Launch4j)和JDK自带... 目录1.问题提出2.如何将Java程序打包成可执行文件2.1将编译后的代码及jre运行环境一起打包2

Vue3中的动态组件详解

《Vue3中的动态组件详解》本文介绍了Vue3中的动态组件,通过`component:is=动态组件名或组件对象/component`来实现根据条件动态渲染不同的组件,此外,还提到了使用`markRa... 目录vue3动态组件动态组件的基本使用第一种写法第二种写法性能优化解决方法总结Vue3动态组件动态

Nginx启动失败:端口80被占用问题的解决方案

《Nginx启动失败:端口80被占用问题的解决方案》在Linux服务器上部署Nginx时,可能会遇到Nginx启动失败的情况,尤其是错误提示bind()to0.0.0.0:80failed,这种问题通... 目录引言问题描述问题分析解决方案1. 检查占用端口 80 的进程使用 netstat 命令使用 ss

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

MySQL8.0设置redo缓存大小的实现

《MySQL8.0设置redo缓存大小的实现》本文主要在MySQL8.0.30及之后版本中使用innodb_redo_log_capacity参数在线更改redo缓存文件大小,下面就来介绍一下,具有一... mysql 8.0.30及之后版本可以使用innodb_redo_log_capacity参数来更改

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满