在Web服务器的日常运维中,安全防护是重中之重。恶意爬虫、CC攻击、暴力破解等行为不仅消耗服务器资源,还可能泄露敏感数据。Nginx 作为高性能的Web服务器和反向代理,提供了灵活且强大的访问控制机制。
本文将详细介绍如何在 Nginx 中配置 IP 黑名单,实现对恶意IP的一键封禁。
一、为什么需要IP黑名单?
- 阻止暴力破解:封禁尝试登录后台或SSH的异常IP。
- 提升服务器性能:减少无效请求对带宽和CPU的占用。
二、基础配置:使用 deny 指令
Nginx 原生支持通过 deny 指令拒绝特定IP或IP段的访问。
1. 单个IP封禁
server {
listen 80;
server_name test.xxx.com;
location / {
deny 192.168.1.100;
allow all;
proxy_pass http://172.17.251.77:16050;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
解释:
- 禁止 IP 地址为 192.168.1.100 的客户端访问该站点,如果该 IP 尝试访问,会收到 403 Forbidden 错误。
- 除了上面被 deny 的 IP 外,其他所有 IP 都可以访问。
- 注意:Nginx 的 allow/deny 规则是按顺序执行的。先匹配到哪条就用哪条。这里先拒绝 192.168.1.100,再允许其余所有。
2. IP段封禁
deny 192.168.1.0/24; # 封禁整个C段
deny 10.0.0.0/8; # 封禁A段
“⚠️ 注意:allow 和 deny 的顺序很重要,Nginx 按顺序匹配,一旦匹配成功即停止。通常先写 deny,最后写 allow all。
三、进阶方案:独立黑名单文件(推荐)
当需要封禁大量IP时,将IP列表放入独立文件更便于管理。
1. 创建黑名单文件
sudo vim /etc/nginx/blacklist.conf
内容示例:
deny 45.33.32.156;
deny 185.220.101.0/24;
deny 23.129.64.0/24;
# 添加更多恶意IP...
2. 在主配置中引入
server {
listen 80;
server_name test.xxx.com;
location / {
include /etc/nginx/blacklist.conf;
allow all;
proxy_pass http://172.17.251.77:16050;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
3. 重载配置
sudo nginx -t # 测试配置语法
sudo nginx -s reload # 重载生效
四、自动化封禁:结合 Fail2Ban
手动维护黑名单效率低下,推荐使用 Fail2Ban 自动分析日志并动态更新Nginx黑名单。
1. 安装 Fail2Ban
# Ubuntu/Debian
sudo apt install fail2ban
# CentOS/RHEL
sudo yum install fail2ban
2. 创建Nginx过滤规则
创建 /etc/fail2ban/jail.d/nginx-botsearch.conf:
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
findtime = 600
3. 定义过滤规则
创建 /etc/fail2ban/filter.d/nginx-botsearch.conf:
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*(wp-admin|wp-login|phpmyadmin|\.env|\.git|/admin|/login).*" 404
^<HOST> -.*"(GET|POST|HEAD).*(eval$|base64_decode|<script|union.*select).*"
ignoreregex =
4. 配置Fail2Ban动作(调用Nginx)
编辑 /etc/fail2ban/action.d/nginx-block.conf,确保包含:
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = echo "deny <ip>;" >> /etc/nginx/blacklist.conf && nginx -s reload
actionunban = sed -i "/deny <ip>;/d" /etc/nginx/blacklist.conf && nginx -s reload
“💡 提示:生产环境建议使用 ipset 或防火墙(如 iptables/firewalld)配合,避免频繁重载Nginx。
5. 启动服务
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo fail2ban-client status nginx-botsearch
五、高性能方案:使用 geo 模块 + map
对于超高并发场景,可使用 geo 模块实现高效IP匹配。
http {
geo $block_ip {
default 0;
45.33.32.156 1;
185.220.101.0/24 1;
# 可include外部文件
include /etc/nginx/geo_block.conf;
}
map $block_ip $block_reason {
0 "";
1 "Blocked by IP blacklist";
}
server {
if ($block_ip) {
return 403 "Access denied: $block_reason";
}
location / {
# 正常业务逻辑
}
}
}
六、验证与监控
1. 测试封禁效果
curl -H "X-Forwarded-For: 45.33.32.156" http://example.com
# 应返回 403 Forbidden
2. 查看实时日志
tail -f /var/log/nginx/access.log | grep "403"
3. 监控黑名单数量
wc -l /etc/nginx/blacklist.conf
七、最佳实践建议
- 定期更新黑名单:结合威胁情报源(如 AbuseIPDB)自动同步恶意IP。
- 日志轮转:避免日志过大影响Fail2Ban分析效率。
- 备份配置:修改前备份
nginx.conf 和黑名单文件。
八、扩展:动态API封禁(高级)
如需通过API动态添加/删除IP,可结合 Lua 模块(OpenResty)实现:
-- access_by_lua_file
local ip = ngx.var.remote_addr
local blocked = redis.get("blacklist:" .. ip)
if blocked then
ngx.exit(403)
end
结语
通过合理配置Nginx IP黑名单,可以有效构筑第一道安全防线。结合自动化工具如Fail2Ban,更能实现“无人值守”的智能防护。记住:安全是一个持续的过程,定期审查日志、更新规则、优化策略,才能让您的网站坚如磐石。
该文章在 2026/4/1 15:42:33 编辑过