在Nginx中实现动态封禁IP的三种主流方案

 更新时间:2025年11月11日 08:44:42   作者:程序员1970  
在运维和安全实践中,经常需要根据实时情况封禁某些恶意 IP,但传统的Nginx 配置是静态的,一旦写死deny 1.2.3.4;,就必须重启或重载服务才能生效,那么,有没有办法实现动态、实时、可编程的IP封禁呢,所以本文给大家介绍了在Nginx中实现动态封禁IP的三种主流方案

引言

在运维和安全实践中,经常需要根据实时情况封禁某些恶意 IP。但传统的Nginx 配置是静态的——一旦写死 deny 1.2.3.4;,就必须重启或重载服务才能生效。那么,有没有办法在不中断服务的前提下,实现动态、实时、可编程的 IP 封禁呢?

一、方案对比

方案是否需 reload实时性技术栈适用场景
geo + map + 文件是(nginx -s reload秒~分钟级原生 Nginx手动或定时脚本封禁
OpenResty + Lua毫秒级OpenResty(Nginx + Lua)自动化、高并发、API 化管理
fail2ban + 日志分析否(系统级封禁)秒级fail2ban + iptables安全防护、日志驱动型封禁

二、方案一:原生 Nginx + 外部文件(简单可靠)

适用于不需要极高实时性的场景,比如每天批量封禁一批扫描 IP。

1. 创建封禁 IP 列表文件

# /etc/nginx/conf.d/blockips.conf
192.168.1.100 1;
203.0.113.5    1;

格式为:IP 值;,值通常设为 1 表示“命中”。

2. 在 nginx.conf 中配置

http {
    # 从外部文件加载黑名单
    geo $block_ip {
        default 0;
        include /etc/nginx/conf.d/blockips.conf;
    }

    map $block_ip $deny_ip {
        1 "denied";
        0 "";
    }

    server {
        listen 80;

        if ($deny_ip = "denied") {
            return 403;
        }

        location / {
            # 正常业务
        }
    }
}

3. 动态更新方式

  • 修改 blockips.conf
  • 执行平滑重载:
nginx -s reload

✅ 优点:无需额外依赖,配置简单。
⚠️ 缺点:每次更新需 reload,不适合高频操作。

三、方案二:OpenResty + Lua(推荐用于自动化)

如果你需要通过 API 实时封禁 IP(例如 WAF、风控系统调用),OpenResty 是最佳选择。它基于 Nginx,嵌入 Lua 脚本引擎,支持共享内存,无需 reload 即可生效。

1. 安装 OpenResty

# Ubuntu 示例
wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
echo "deb http://openresty.org/package/debian $(lsb_release -sc) openresty" | sudo tee /etc/apt/sources.list.d/openresty.list
sudo apt update && sudo apt install openresty

2. 配置 nginx.conf

http {
    lua_shared_dict ip_blacklist 10m;  # 共享内存存储黑名单

    server {
        listen 80;

        # 【核心】访问前检查 IP
        access_by_lua_block {
            local ip = ngx.var.remote_addr
            if ngx.shared.ip_blacklist:get(ip) then
                ngx.log(ngx.WARN, "Blocked IP: ", ip)
                ngx.exit(403)
            end
        }

        # 动态封禁接口(建议加 IP 白名单保护)
        location = /ban {
            content_by_lua_block {
                local args = ngx.req.get_uri_args()
                local ip = args.ip
                local seconds = tonumber(args.seconds) or 3600

                if not ip or not ip:match("^%d+%.%d+%.%d+%.%d+$") then
                    ngx.status = 400
                    ngx.say("Invalid or missing 'ip'")
                    return
                end

                ngx.shared.ip_blacklist:set(ip, true, seconds)
                ngx.say("Banned ", ip, " for ", seconds, "s")
            }
        }

        # 解封 & 查询接口
        location / { echo "Hello! Your IP: $remote_addr"; }
    }
}

3. 使用示例

# 封禁 IP 5 分钟
curl "http://your-server/ban?ip=1.2.3.4&seconds=300"

# 测试是否被封
curl http://your-server/  # 返回 403

✅ 优点:毫秒级生效、支持 TTL 自动过期、可集成到自动化系统。
🔐 安全提示:务必限制 /ban 接口的访问来源!

四、方案三:fail2ban + Nginx 日志(自动防御)

适用于防御暴力 破解、高频 404 扫描等行为。fail2ban 会监控日志,自动封禁异常 IP。

1. 确保 Nginx 记录详细日志

log_format main '$remote_addr - $remote_user [$time_local] "$request" $status ...';
access_log /var/log/nginx/access.log main;

2. 创建过滤器 /etc/fail2ban/filter.d/nginx-bad-request.conf

[Definition]
failregex = ^<HOST> -.*"(GET|POST).*" 404 .*
ignoreregex =

3. 配置 jail(/etc/fail2ban/jail.local)

[nginx-bad-request]
enabled  = true
port     = http,https
filter   = nginx-bad-request
logpath  = /var/log/nginx/access.log
maxretry = 10      # 10 次失败
findtime = 600     # 在 10 分钟内
bantime  = 3600    # 封 1 小时
action   = iptables-multiport[name=nginx, port="http,https"]

4. 启动并查看状态

sudo systemctl start fail2ban
sudo fail2ban-client status nginx-bad-request

✅ 优点:全自动、成熟稳定、社区支持好。
⚠️ 注意:默认使用 iptables 封禁,影响整个服务器,非仅 Nginx。

五、如何选择?

  • 只想偶尔手动封几个 IP? → 用 方案一(原生 Nginx)。
  • 需要程序自动封禁、支持 API 调用? → 用 方案二(OpenResty)。
  • 想自动防御扫描、爆破? → 用 方案三(fail2ban)。

进阶技巧:可让 fail2ban 调用 OpenResty 的 /ban 接口,实现“仅封 Nginx + 自动过期”的完美组合。

以上就是在Nginx中实现动态封禁IP的三种主流方案的详细内容,更多关于Nginx动态封禁IP的资料请关注脚本之家其它相关文章!

相关文章

  • nginx热部署的原理分析:nginx -s reload

    nginx热部署的原理分析:nginx -s reload

    这篇文章主要介绍了nginx热部署的原理分析:nginx -s reload,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • 使用nginx进行负载均衡的搭建全过程

    使用nginx进行负载均衡的搭建全过程

    负载均衡用于从“upstream”模块定义的后端服务器列表中选取一台服务器接受用户的请求,下面这篇文章主要给大家介绍了关于使用nginx进行负载均衡的搭建全过程,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • 文件上传到服务器文件名中文乱码问题

    文件上传到服务器文件名中文乱码问题

    上传附件到部署服务器,但是上传到服务器出现文件名中文乱码,中文变成(?)问号,而且在本地测试是正常的,通过打印日志发现,下面fileName乱码,本文给大家讲解文件上传到服务器文件名中文乱码问题解决方案,感兴趣的朋友一起看看吧
    2024-02-02
  • Nginx常用命令和部署详解以及实战案例示范

    Nginx常用命令和部署详解以及实战案例示范

    这篇文章主要介绍了Nginx的常用命令和在不同环境下的部署方法,包括在CentOS和Docker中部署Nginx,并详细说明了如何配置Nginx以实现实时刷新数据和数据分析系统的场景,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • 在Docker中实现Nginx平滑重启的几种方法

    在Docker中实现Nginx平滑重启的几种方法

    关于平滑重启的意思,就是指已经连接到nginx的请求将继续使用旧的配置,待客户端服务完成后,旧的工作进程将关闭,下次请求将采用新的配置,本文给大家介绍了在Docker中实现Nginx平滑重启的几种方法,需要的朋友可以参考下
    2025-09-09
  • Nginx服务器配置HTTPS nginx.config 配置文件(教程)

    Nginx服务器配置HTTPS nginx.config 配置文件(教程)

    下面小编就为大家分享一篇Nginx服务器配置HTTPS nginx.config 配置文件(教程),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • Nginx中Lua脚本实现动态黑名单自动封禁机制

    Nginx中Lua脚本实现动态黑名单自动封禁机制

    本文主要介绍了Nginx中Lua脚本实现动态黑名单自动封禁机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-04-04
  • Linux部署Nginx详细图文教程

    Linux部署Nginx详细图文教程

    这篇文章主要给大家介绍了关于Linux部署Nginx的相关资料,Nginx 是一个高性能的HTTP和反向代理web服务器,Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,需要的朋友可以参考下
    2024-01-01
  • Nginx服务器上搭建图片缓存服务的基本配置解析

    Nginx服务器上搭建图片缓存服务的基本配置解析

    这篇文章主要介绍了Nginx服务器上搭建图片缓存服务的基本配置解析,分别介绍了通过proxy_store模块和proxy_cache模块两种方式的配置,需要的朋友可以参考下
    2016-04-04
  • Nginx出现403错误,应该如何解决

    Nginx出现403错误,应该如何解决

    这篇文章主要介绍了Nginx出现403错误,应该如何解决?具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03

最新评论