应使用 map 在 http 块预定义 $blocked_ua 变量,再在 location 中用 if($blocked_ua) return 403;配合 limit_req 基于 ip 限流,并分层叠加 ua 拦截、速率限制、路径防护与日志封禁。

在 location 块中直接用 if ($http_user_agent ~* "...") 拦截爬虫,**基本无效且危险**——Nginx 的 if 在 location 内是伪指令,容易被 proxy_pass、try_files 跳过,官方明确建议避免。
必须用 map 预定义变量,在 location 中安全判断
真正可靠的做法:把 UA 匹配逻辑移到 http 块顶层,用 map 编译成布尔变量,再在 location 里轻量引用。
- 在
http块开头添加(注意空格和分号):
default 0;
~* (sqlmap|nikto|gobuster|nuclei) 1;
~* (python-requests|curl|wget|httpie) 1;
~* (scanner|crawler|exploit|pentest) 1;
~* (^$|^\s*$|^-$) 1;
}
- 在目标
location中启用(紧贴location / {下方,不要放在try_files或proxy_pass后面):
return 403 "Access denied."; # 带提示便于日志识别
}
- 白名单要后置:如需放行 Bingbot,在
map中加一行~* Bingbot 0;,且放在所有黑名单规则之后 - 空 UA 必须单独处理:
~* (^$|^\s*$|^-$),不能靠正则~*模糊匹配
光封 UA 不够,高频请求得靠 limit_req
封 User-Agent 只能挡住“懒爬虫”;真正耗资源的是每秒几十次的自动化脚本。这时核心防线是 limit_req,它基于 IP 实施漏桶限流,硬性掐断流量。
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
- 在
http块定义限流区(推荐用$binary_remote_addr节省内存):
- 在关键
location(如/api/或/)启用:
limit_req zone=ip_limit burst=10 nodelay;
if ($blocked_ua) { return 403 "Access denied."; }
# 后续 proxy_pass 或 try_files
}
-
burst=10允许短时突发,nodelay避免排队延迟,适合防刷场景 - 登录接口可更严格:
rate=3r/s burst=0,彻底禁止连试
robots.txt 是君子协议,不能当防护手段
它只对守规矩的爬虫有效。恶意爬虫会直接忽略 /robots.txt,照样请求 /admin 或 /wp-login.php。你可以配置它引导规范爬虫,但别依赖它挡攻击。
- 示例配置(放在 server 块内):
default_type text/plain;
return 200 "User-Agent: Baiduspider\nDisallow: /\nUser-Agent: *\nDisallow: /";
}
- 顺序必须从具体到泛化(如
Baiduspider在*前),否则*会提前截断匹配 - 每行末尾不能有多余空格,
Disallow:后必须跟一个空格再写路径
补充建议:组合使用效果更稳
单一手段易被绕过,生产环境建议分层叠加:
- 第一层:用
map + if($blocked_ua)快速拦截已知恶意 UA 和空 UA - 第二层:用
limit_req控制单 IP 请求速率,防高频自动化行为 - 第三层:对敏感路径(如
/login、/wp-admin)加 IP 白名单或基础认证 - 第四层:记录访问日志,配合 Fail2Ban 或自研脚本动态封禁异常 IP










