Nginx限流防爬核心是提升扫描成本而非彻底封堵,需分路径与IP双维度限速、配合日志调优及基础识别联动。

直接用限流限速防高频爬虫,核心不是“堵死”,而是让扫描成本变高、效率变低——Nginx 的 limit_req 模块就是最轻量又有效的手段。关键在于分场景设限、叠加维度控制,并配合日志验证,而不是靠单一规则硬扛。
按敏感路径单独限速,不伤正常流量
爬虫最爱扫 /admin/、/wp-login.php、/api/v1/auth 这类高价值路径,全站统一限速反而影响首页或静态资源加载。应该在 http 块中定义路径级限速区:
-
配置示例:
limit_req_zone $uri zone=per_uri:10m rate=5r/s;—— 每个 URI 独立计数,/login 和 /api/user 不互相干扰 -
精准启用:在 location 中只对风险路径启用,比如
location = /wp-login.php { limit_req zone=per_uri burst=3 nodelay; } - burst 和 nodelay 要搭配用:burst=3 允许用户点错两次再输密码,nodelay 让超限请求立刻返回 503,不给爬虫试探节奏
叠加 IP 级限速,封住“扫多个路径”的行为
单靠路径限速挡不住换着 URL 扫的爬虫。同一 IP 在短时间内访问多个敏感路径,说明它在探测而非真实使用。这时要加一层 IP 维度控制:
-
定义双 zone:
limit_req_zone $binary_remote_addr zone=per_ip:10m rate=10r/s;+limit_req_zone $uri zone=per_uri:10m rate=5r/s; -
组合生效:在
location ^~ /api/块里同时写两行limit_req,任一触发即拒绝,实现“单 IP 总量 + 单路径频次”双保险 - 注意内存分配:10MB zone 够支撑数万个不同 IP 或 URI,小站点用 5m 也够用
从日志里找真实攻击特征,动态调优
上线后别只看配置有没有报错,要真看它拦住了谁:
-
加日志变量:在
log_format里加入$limit和$limit_rate,能直接看到哪次请求被哪个 zone 拦截 -
先宽松后收紧:初始用
rate=10r/s + burst=20,观察 24 小时 access_log 中被限的是否含真实用户(比如登录页被限太多,就单独提高该 location 的 burst) -
避开公开资源:不要对
/static/、/images/、/favicon.ico限速,否则 CDN 预热和浏览器并发加载会异常
配合基础识别,提升拦截精度
限流是行为层防御,可以和简单识别联动,减少误伤:
-
UA 黑名单兜底:用
map匹配已知恶意 UA(如Scrapy、Apache-HttpClient),匹配到直接return 444(静默断连) -
IP 黑名单前置:把已确认的扫描 IP 段(如 AhrefsBot、MJ12bot 的网段)用
deny放在 server 或 http 块最前,省去后续解析开销 - 不依赖 Referer 或 Cookie:这些头容易伪造,仅作辅助,主防线始终是速率+路径+IP 三重控制


















