方向基本对了,但顺序应该反过来——源站 IP 白名单是地基,限速和封 UA 只是补刀,先把源站 IP 藏住再谈别的,否则白名单就是纸糊的。
先说你现在的方案。limit_req 建议把 zone、burst、nodelay 一起用,比如 limit_req_zone $binary_remote_addr zone=spider:10m rate=60r/m;,配 limit_req zone=spider burst=10 nodelay;,超限直接 return 444; 而不是 503,nginx 会直接关连接不返回响应体,1核2G 的机器上这区别很大。再叠一层 limit_conn 按 IP 限并发,单 IP 给 20 连接足够,能卡住那种一口气开几百个连接的扫描器。
再说源站白名单,很多人栽在这步。光是配 CDN 回源 IP 白名单不够,得先确认真实 IP 没漏出去:查一遍历史 DNS 解析记录、Censys/Shodan 上有没有你的 IP、SSL 证书透明日志、以及 CDN 有没有开回源鉴权(阿里云/腾讯云/CF 都有)。做完这些建议直接把源站 IP 换掉,白名单才成立。
正经蜘蛛别只按 UA 放,UA 分分钟能伪造。百度、谷歌、Bing 都有官方 IP 段 JSON 列表,用 ngx_http_realip_module 配 set_real_ip_from 更靠得住,robots.txt 里再给个 crawl-delay,Google 不认但 Bing 认。另外你这配置建议顺手开 fastcgi_cache 或 proxy_cache,把列表页缓存 30 到 60 秒,爬虫狂扫翻页参数时压根打不到 PHP,比限速治本得多。
坑就一个:limit_req 别全局一刀切,登录、后台、搜索接口单独开个 zone 放宽阈值,不然正常用户手一抖就喜提 444。另外阿里云的基础 DDoS 防护和按量付费 WAF 小站也能白嫖一层,值得挂上。