Nginx封禁IP的三种高效方法

更新日期: 2025-12-02 阅读: 15 标签: ip

还在用vim手动添加deny 1.2.3.4;,然后执行nginx -s reload吗?这种方法不仅效率低,还容易出错、漏掉该封的IP、重启服务时还会影响正常访问……

别担心!本文介绍三种真正"动态"、不需要复杂开发、可以在生产环境中使用的Nginx封IP方案,都包含完整配置和简单命令操作。让你的防护能力秒级生效,运维效率大幅提升!


方案一:OpenResty + Redis 毫秒级动态封禁

特点: 实时生效、不需要reload、支持自动解除封禁

1. 安装OpenResty和Redis

# Ubuntu系统示例
sudo apt install redis-server -y

# 安装OpenResty
wget -O - https://openresty.org/package/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/openresty-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/openresty-archive-keyring.gpg] http://openresty.org/package/debian $(lsb_release -sc) openresty" | sudo tee /etc/apt/sources.list.d/openresty.list
sudo apt update && sudo apt install -y openresty

2. 配置/etc/openresty/nginx.conf

worker_processes auto;
events { worker_connections 1024; }

http {
    server {
        listen 80;

        location / {
            access_by_lua_block {
                local redis = require "resty.redis"
                local red = redis:new()
                red:set_timeout(1000)
                local ok, err = red:connect("127.0.0.1", 6379)
                if not ok then return end

                local ip = ngx.var.remote_addr
                if red:get("blacklist:" .. ip) ~= ngx.null then
                    ngx.exit(403)
                end
                red:close()
            }
            proxy_pass http://127.0.0.1:8080;
        }
    }
}

3. 动态封禁和解封IP(一行命令)

# 封禁IP 1小时
redis-cli SETEX blacklist:1.2.3.4 3600 "abuse"

# 解除封禁
redis-cli DEL blacklist:1.2.3.4


方案二:fail2ban + Nginx日志——自动分析恶意行为

特点: 自动封禁、防止爆破攻击、安装即用

1. 安装fail2ban

sudo apt install fail2ban -y

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

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

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

[nginx-bad]
enabled = true
port = http,https
filter = nginx-bad
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 3600
action = iptables-multiport[name=nginx, port="80,443"]

4. 启动服务

sudo systemctl restart fail2ban

注意: 默认使用iptables封禁IP。如果想只用Nginx,请看方案三。


方案三:Shell脚本 + 文件监听——最简原生Nginx封禁

特点: 不依赖其他软件、只用Nginx、运维只需要编辑文本文件

核心思想:

  1. 维护一个纯文本黑名单文件:/etc/nginx/blacklist.txt(每行一个IP)

  2. 用Shell脚本自动转换成deny配置并重新加载

  3. 通过inotifywait监听文件变化,修改后立即生效

第一步:安装inotify-tools(监听文件变动)

sudo apt install inotify-tools -y

第二步:创建黑名单目录和初始文件

sudo mkdir -p /etc/nginx/dynamic
echo "# 黑名单IP,每行一个,如:1.2.3.4" | sudo tee /etc/nginx/blacklist.txt
sudo touch /etc/nginx/dynamic/blacklist.conf

第三步:编写转换脚本/usr/local/bin/gen_nginx_blacklist.sh

#!/bin/bash
INPUT="/etc/nginx/blacklist.txt"
OUTPUT="/etc/nginx/dynamic/blacklist.conf"

# 清空输出文件
echo "# Auto-generated from blacklist.txt. DO NOT EDIT." > "$OUTPUT"

# 读取blacklist.txt,跳过注释和空行,生成deny规则
while IFS= read -r line; do
    line=$(echo "$line" | xargs)  # 去除前后空格
    if [[ -n "$line" && "$line" != \#* ]]; then
        echo "deny $line;" >> "$OUTPUT"
    fi
done < "$INPUT"

# 测试配置并重新加载
nginx -t && systemctl reload nginx

赋予执行权限:

sudo chmod +x /usr/local/bin/gen_nginx_blacklist.sh

第四步:在Nginx配置中引入黑名单

server {
    listen 80;
    include /etc/nginx/dynamic/blacklist.conf;  # 关键配置!

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

第五步:启动监听服务(后台运行)

# 直接运行
nohup inotifywait -m -e modify,move,create,delete /etc/nginx/blacklist.txt \
  --format '%f' | while read file; do
    echo "[$(date)] blacklist.txt changed, regenerating..."
    /usr/local/bin/gen_nginx_blacklist.sh
done &

更推荐的方法:创建systemd服务

创建服务文件/etc/systemd/system/nginx-blacklist.service:

[Unit]
Description=Nginx Blacklist Monitor
After=network.target

[Service]
Type=simple
ExecStart=/bin/bash -c 'inotifywait -m -e modify,move,create,delete /etc/nginx/blacklist.txt --format "%f" | while read file; do /usr/local/bin/gen_nginx_blacklist.sh; done'
Restart=always
User=root

[Install]
WantedBy=multi-user.target

启动服务:

sudo systemctl daemon-reload
sudo systemctl enable nginx-blacklist
sudo systemctl start nginx-blacklist

使用方法

运维人员只需要编辑/etc/nginx/blacklist.txt文件:

# 示例内容
1.2.3.4
5.6.7.8
192.168.100.50

保存文件后,3秒内自动封禁!不需要执行任何命令!

优点:

  • 只需要一个文本文件和一个Shell脚本

  • 完全兼容原生Nginx

  • 操作简单,维护方便


实际应用建议

场景一:高并发网站api网关

如果网站访问量大,需要快速响应,推荐使用方案一(OpenResty + Redis)。

额外优化:

  1. 使用Redis集群提高可用性

  2. 设置白名单,避免误封

  3. 添加监控,记录封禁日志

场景二:WordPress或内容管理系统

如果运行WordPress等CMS系统,经常遇到暴力破解,推荐方案二(fail2ban)。

优化配置:

[wordpress-login]
enabled = true
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 300
bantime = 86400

场景三:简单网站或传统运维环境

如果不想安装新软件,习惯用文本文件管理,推荐方案三(Shell脚本)。

高级用法:

  1. 添加IP段封禁功能

  2. 集成到现有运维系统

  3. 添加邮件通知功能


安全注意事项

1. 避免误封

  • 设置管理IP白名单

  • 定期检查黑名单

  • 设置封禁时间,不要永久封禁

2. 监控和日志

  • 记录所有封禁操作

  • 监控封禁效果

  • 定期分析封禁原因

3. 性能考虑

  • 黑名单不宜过大

  • 定期清理过期记录

  • 考虑使用内存缓存


三种方案对比

特性方案一(OpenResty+Redis)方案二(fail2ban)方案三(Shell脚本)
生效速度毫秒级分钟级秒级
是否需要reload不需要不需要需要
安装复杂度中等简单简单
维护难度中等简单简单
适用场景高并发、API网关防爆破、CMS系统简单网站、传统运维

如何选择?

  1. 高并发、API网关、需要快速响应:选方案一(OpenResty + Redis)

  2. 防止暴力破解、WordPress等中小型网站:选方案二(fail2ban)

  3. 不想装新软件、只要原生Nginx、习惯用文件管理:选方案三(Shell脚本 + 文件监听)


写在最后

封禁IP不应该是费时费力的体力活!无论你是技术高手还是初级运维,总有一种方案能帮你告别手动reload,把时间花在更有价值的事情上。

根据实际需求和环境选择合适的方法,让安全防护变得更简单、更高效。记得定期检查和优化配置,确保既能有效防护,又不会影响正常用户访问。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13256

node.js监听不同ip地址的差异

IP地址一共分为A~E5类,它们分类的依据是其net-id所占的字节长度以及网络号前几位。127.0.0.1:回环地址。该地址指电脑本身,主要预留测试本机的TCP/IP协议是否正常。只要使用这个地址发送数据,则数据包不会出现在网络传输过程中。

子网掩码的概念、规则

子网掩码(subnet mask)又叫网络掩码、地址掩码、子网络遮罩,它是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。子网掩码的设定必须遵循一定的规则

nginx 对同一 ip 访问请求速率限制

模块ngx_http_limit_req_module,所述ngx_http_limit_req_module模块(0.7.21)用于限制每一个定义的键值的请求的处理速率,特别是从一个单一的IP地址的请求的处理速率。使用“漏桶”方法进行限制。

vue-cli启动本地服务,局域网下通过ip访问不到的原因

新开发了一个vue-cli项目,想通过手机查看效果,发现访问不到,ip地址和端口号都没错但是手机访问不到,在本机电脑浏览器输入ip端口号一样访问不到,只能通过localhost:8080访问到,同一局域网下其他的手机和电脑并不能通过ip地址访问调试

Js正则表达式验证IP地址

正则验证合法_有效的IP地址(ipv4/ipv6),不墨迹直接上代码,正则表达式:/^*****$/,JS函数方法:

前端Js获取本网IP和外网IP方法总汇

我们应该知道一台电脑需要两个ip才可以上网,一个是本地的内网ip(本地ip),另一个就是外网ip(公网ip)。值得说明的是:外网ip具有世界范围的唯一性

利用宝塔面板计划任务shell脚本扫描恶意IP

我们需要找到恶意ip,可以利用脚本分析在一分钟单个IP访问的频率,超过一定的频率(一般来正常的访问,一分钟内应该不超过60次,你可以设置为更小),即认定为恶意IP。宝塔面板的shell脚本如下:

js获取本地ip地址和外网IP地址

分享一个js获取ip地址的代码,可用于获取本地ip地址与外网ip地址,有需要的朋友参考下。获取外网ip发现比较全而好的前端获取客户端IP的方法基本都是通过三方接口。也就是调用别人写好的接口。

IPv4 子网查询

A类:1.0.0.0~126.255.255.255,默认子网掩码/8,即255.0.0.0 (其中127.0.0.0~127.255.255.255为环回地址,用于本地环回测试等用途);B类:128.0.0.0~191.255.255.255,默认子网掩码/16,即255.255.0.0;

一文聊透 IP 地址的那些事

IP 地址,是一个大家都耳熟能详的名词。 以生活举例,IP 在互联网中的作用就像是寄件时的收件人地址和寄件人地址,收件人地址让信件可以被正确送达,寄件人地址则让收到信的人可以回信。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!