直接在nginx配置的server块顶层(location前)添加if ($http_user_agent ~* "bytespider|semrush|mj12bot|dataforseo|babbar|aiohttp|gptbot|chatcom|perplexity|cohere") { return 403; }即可生效,需保存后重启nginx。

直接在Nginx配置里加if ($http_user_agent ~* "...")就行
宝塔面板本身不内置全局UA屏蔽,但支持在站点配置文件中用原生Nginx语法拦截。这不是“功能开关”,而是手写规则——只要Nginx版本 ≥ 1.10(宝塔默认满足),if + $http_user_agent 就能生效。
常见错误是把规则塞进location块里,或漏掉~*(大小写不敏感匹配)。实际必须放在server块顶层、location之前,否则可能被覆盖或不触发。
- 规则要写在「网站 → 设置 → 配置文件」中
server { ... }大括号内,靠前位置 -
~*不能写成=~或~,否则小写ua(如baiduspider)会漏判 - 正则里不要用
/包裹,Nginx原生语法不需要分隔符 - 修改后必须点「保存」再手动重启Nginx,仅重载配置(reload)有时不生效
哪些User-Agent字符串该放进规则里
不是所有爬虫都要拦。重点封的是高频、无robots.txt约束、带采集特征的Bot,比如Bytespider(字节系)、semrush、mj12bot,它们常绕过限制扫全站。而Googlebot和Baiduspider是否屏蔽,得看业务需求——封了会影响SEO。
下面这组是实测拦截率高、误伤低的组合(已去重并统一小写处理):
if ($http_user_agent ~* "bytespider|semrush|mj12bot|dataforseo|babbar|aiohttp|gptbot|chatcom|perplexity|cohere") {
return 403;
}
- 排除
Googlebot等主流搜索爬虫,避免收录丢失 - 加入
aiohttp和gptbot是因为大量AI训练采集器伪装成它们 - 别写
curl或python-requests——合法监控、运维脚本也会用,容易自断手脚
为什么不用宝塔防火墙的User-Agent过滤
宝塔免费防火墙的UA过滤本质也是往Nginx里插if规则,但它把逻辑封装了,你没法控制优先级、无法排除白名单、也不显示实际生成的配置。一旦和其他规则(比如CC防护、IP黑名单)冲突,排查起来全是黑盒。
更关键的是:它默认启用“恶意UA库”,但这个库不会自动更新,且对新出现的Bot(比如2025年冒头的perplexity)响应滞后。你粘贴的正则如果没包含它,就等于没拦住。
- 防火墙UI里填的正则,最终会编译成类似
map $http_user_agent $deny_ua的指令,性能略优于if,但差异可忽略 - 若已装防火墙又想精细控制,建议停用它的UA过滤模块,改用纯配置方式
- 注意防火墙自身有缓存,规则添加后可能延迟1–2分钟才生效,Nginx直写则保存即生效(重启后)
测试是否真生效了
别只看日志有没有403,得用真实请求验证。最简单的方法是本地curl模拟:
curl -I -A "Bytespider/1.0" https://your-site.com/
返回HTTP/2 403才算成功。如果返回200,优先检查:nginx -t是否报错、Nginx是否真的重启了、规则是否被其他if或rewrite覆盖。
- 线上验证时,务必用非本机IP发起请求,避免被宝塔的“本地调试”逻辑绕过
- 日志里查
$http_user_agent字段,确认记录的UA和你写的正则能对上(注意空格、转义) - 某些Bot会随机切换UA,单次测试不够,建议用
ab或wrk发10次以上带不同UA的请求交叉验证
Nginx的if语句在server块中的执行顺序很关键,写错位置会导致规则静默失效——这点连很多老运维都会忽略。











