ip_hash本身不防爬虫,需叠加IP拦截、每IP限流(limit_req_zone)和并发连接限制(limit_conn_zone)三重防护,防止恶意流量集中压垮单台后端。

在 ip_hash 负载均衡模式下,Nginx 会将同一客户端 IP 的请求始终转发到同一个后端服务器。这虽能实现会话保持,但也带来风险:恶意爬虫一旦被 hash 到某台后端,就可能持续压垮该节点,造成单点过载甚至服务不可用。因此,不能只依赖 ip_hash,而需叠加访问控制与限流策略,在流量入口层拦截或压制恶意行为。
1. 在 ip_hash 前先做 IP 层拦截
恶意爬虫常使用固定或少量 IP 发起高频请求。可在 upstream 外、server 或 location 块中,用 ngx_http_access_module 直接拒绝已知恶意 IP:
- 在
http块中引入黑名单文件:include /etc/nginx/conf.d/blacklist.conf; -
blacklist.conf内容示例:deny 203.154.128.0/18;<br>deny 192.168.100.42;<br>deny 2a02:598::/32;
- 规则按顺序匹配,
deny all放最后可实现白名单兜底(慎用)
2. 对每个 IP 实施独立限流(关键)
ip_hash 不影响 limit_req_zone 的生效——它仍基于 $binary_remote_addr 统计,且限流发生在代理前。这是防止单 IP 挤爆后端的核心手段:
- 定义限流区域(放在
http块):limit_req_zone $binary_remote_addr zone=anti_crawler:10m rate=5r/s; - 在
location中启用(紧贴proxy_pass前):limit_req zone=anti_crawler burst=10 nodelay; - rate 建议设为 1–10 r/s(登录页可更低,公开 API 可略高),burst 控制瞬时突增容忍度
3. 限制单 IP 并发连接数
爬虫常建大量长连接(如 HTTP/1.1 keepalive 或扫描器),用 limit_conn 可直接卡死连接池:
- 定义连接限制区域:
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m; - 在 location 中应用:
limit_conn conn_per_ip 3;(允许最多 3 个并发连接) - 搭配
limit_conn_status 429;返回标准限流响应,便于前端识别
4. 配合真实 IP 识别与日志审计
若 Nginx 前有 CDN 或 LB,$remote_addr 会变成代理 IP。必须启用 realip 模块并配置可信来源,否则限流和拦截失效:
- 确认编译含
--with-http_realip_module - 在 server 块中设置:
set_real_ip_from 10.0.0.0/8;<br>set_real_ip_from 172.16.0.0/12;<br>real_ip_header X-Forwarded-For;<br>real_ip_recursive on;
- 在 access_log 中记录真实 IP:
log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
ip_hash 本身不防爬虫,它只是路由策略。真正起防护作用的是前置的 IP 拦截、每 IP 请求频次控制、并发连接数限制,三者组合才能避免恶意流量集中打穿单台后端。配置上线前务必用 ab 或 wrk 模拟验证效果,防止误伤正常用户。


















