nginx可通过include指令加载第三方ip黑名单文件实现近似自动集成,需将firehol等源预处理为deny语句格式(如deny 198.51.100.0/24;),在server或location块中引入,并配合real_ip_module还原真实ip,再通过脚本自动化拉取、转换与重载。

Nginx 本身不提供“第三方反爬虫黑名单”的自动集成能力,但可以通过 include 指令加载外部 IP 黑名单文件,配合日志分析、开源项目(如 fail2ban)、或社区维护的黑名单源(如 FireHOL IP lists),实现近似“引入第三方黑名单”的效果。关键在于:把第三方提供的 IP 列表,转换成 Nginx 可识别的 deny 语句,并安全引入配置中。
黑名单文件需符合 Nginx 语法规范
第三方原始数据(如 CSV、纯 IP 列表、CIDR 格式)不能直接被 Nginx 加载。必须预处理为标准格式:
- 每行一条
deny指令 - 支持 IPv4(如
deny 198.51.100.42;)、IPv6(如deny 2001:db8::/32;)和 CIDR 网段 - 结尾必须有分号
; - 注释用
#开头(Nginx 会忽略)
示例 /etc/nginx/conf.d/anti-crawler-blacklist.conf:
# Generated from FireHOL level3 list — 2026-07-20 deny 198.51.100.0/24; deny 203.0.113.64/27; deny 2001:db8:abcd::/48;
在 server 或 location 块中正确引入
include 必须放在实际生效的上下文中,且顺序不能错:
- 若用于封禁所有请求(如全站爬虫拦截),放在
server { }的根location / { }内 - 若只针对 PHP 接口(如 ThinkPHP 入口),必须放在
location ~ \.php$ { }块内(因 rewrite 后流量都走这里) - 不要放在
http { }全局块——deny指令不支持在 http 层直接生效
正确写法示例:
server {
listen 80;
server_name example.com;
location / {
include /etc/nginx/conf.d/anti-crawler-blacklist.conf;
# 后续其他配置(如 root、index)...
}
location ~ \.php$ {
include /etc/nginx/conf.d/anti-crawler-blacklist.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
# ...
}
}
自动化更新黑名单文件(避免手动维护)
靠人工复制粘贴不可持续。推荐用脚本定期拉取并转换:
- 下载源(如
https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level3.netset) - 过滤空行、注释、非 IP 行,转成
deny x.x.x.x/y;格式 - 写入目标文件后,执行
nginx -t && nginx -s reload
一个最小可行 Shell 脚本片段:
curl -s https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level3.netset | \ grep -E '^[0-9]+|[0-9a-f:]' | \ sed 's/^/deny /; s/$/;/' > /etc/nginx/conf.d/anti-crawler-blacklist.conf nginx -t && nginx -s reload
注意真实客户端 IP 地址问题
如果网站经 CDN(如 Cloudflare)或 HTTPS 反向代理,$remote_addr 是代理 IP,不是访客真实 IP。必须:
- 启用
real_ip_module - 配置
set_real_ip_from指定可信代理网段 - 设置
real_ip_header X-Forwarded-For或CF-Connecting-IP(Cloudflare)
否则黑名单对真实爬虫无效。
补充建议:别只依赖 IP 封禁
IP 黑名单易被绕过(动态代理、IP 池)。建议组合使用:
-
limit_req对未授权 IP 限速(如limit_req zone=anti_crawl burst=5 nodelay;) -
geo+if实现更灵活的变量控制(适合规则多、需复用场景) - 结合 UA 过滤(如
if ($http_user_agent ~* "Scrapy|AhrefsBot") { return 403; })增强识别
配置生效后,可用 curl -H "X-Forwarded-For: 198.51.100.10" http://example.com/ 测试是否拦截。











