最简单有效的方法是在nginx配置中用if判断ua,需将规则正确插入各location块(含静态资源和php块),推荐用map预定义变量或~*匹配关键词,避免误杀并确保全路径生效。

直接在Nginx配置里用if判断UA最简单有效
宝塔面板本身不提供“UA黑名单”图形化开关,想精准拦截特定爬虫(比如 python-requests、Go-http-client、masscan),必须手动改站点的Nginx配置。这不是功能缺失,而是Nginx原生就支持这种轻量级过滤,比用防火墙规则或WAF插件更底层、更省资源。
关键点:Nginx的 if 指令在 location 块内使用是安全的,但不能嵌套在 if 里再写 if —— 宝塔自动生成的配置常把 location / 放在最后,你得把规则加进去,而不是塞到server顶层。
匹配UA字符串要区分大小写和边界,避免误杀
Nginx默认的 $http_user_agent 是原始字符串,正则匹配时要注意:~ 是大小写敏感,~* 是忽略大小写;用 ^ 和 $ 锚定整串容易漏掉变体,而只用 .*xxx.* 又可能误伤正常流量(比如屏蔽 curl 会干掉运维调试请求)。
- 推荐用
~*+ 关键字片段,例如屏蔽所有含sqlmap的UA:if ($http_user_agent ~* "sqlmap") { return 403; } - 若要严格匹配完整UA(如某些扫描器固定发送
masscan/1.0),可用^masscan/1\.0$,注意点号要转义 - 多个关键词用
|连接,如~* "(python-requests|Go-http-client|ZmEu)"——ZmEu是常见恶意UA的Base64解码前缀 - 不要写
if ($http_user_agent = "xxx"),=是精确字符串匹配,几乎没用,因为UA极少完全一致
放在哪个location块里决定拦截范围和性能影响
规则位置错了,要么不生效,要么拖慢全站。宝塔默认生成的配置中,静态文件(js/css/img)通常由独立的 location ~ .*\.(js|css|png|jpg|gif|pdf)$ 处理,UA判断如果只放在 location / 里,对这些静态资源就无效 —— 而恶意爬虫往往专扫CSS/JS路径做指纹识别。
- 最稳妥的做法:把UA判断放到
server块开头,用map预定义变量(推荐,性能最好) - 快速上线做法:复制一份UA判断代码,分别粘贴进每个
location块(包括location /、静态资源location、PHP location) - 千万别只加在
location ~ \.php$里——静态资源访问不走PHP,这条规则等于没设 - 注意:若站点启用了SSL,HTTP和HTTPS的server块都要加,宝塔会为它们生成两个独立配置
验证是否生效以及常见失效原因
改完配置点“重载Nginx”,别点“重启”。然后用curl模拟恶意UA测试:curl -I -H "User-Agent: sqlmap/1.7.2" https://yoursite.com,看返回是不是 403 Forbidden。不是?大概率是下面几个坑:
- 宝塔自动备份了旧配置,但你编辑的是备份文件(文件名带
.bak或时间戳),实际加载的还是原版 - 规则写在了
include的外部文件里(如enable-php.conf),而该文件被宝塔更新覆盖了 - 浏览器或CDN缓存了301/302跳转,导致你以为403没触发,其实真实请求已返回403,只是被缓存掩盖
- 某些爬虫会随机更换UA或伪造Referer,单靠UA拦截不够,得配合IP频次限制(
limit_req)才真正有效
真正麻烦的从来不是写几行if,而是确认它在所有路径、所有协议、所有缓存层级下都稳定生效——这点很容易被忽略。










