推荐使用 map 指令实现 User-Agent 黑名单,需在 http 块顶层定义映射变量 $blocked_ua,匹配恶意 UA 返回 1 并在 location 中用 if 判断后 return 403,避免 if 在 location 外误用。

在 Nginx 中,可以通过 map 指令或 if + return 组合来禁止特定 User-Agent 的请求访问,但推荐使用 map 方式——它更高效、更安全,避免 if 在 location 外误用带来的隐患。
使用 map 实现 User-Agent 黑名单(推荐)
在 http 块中定义一个映射变量,将匹配的 User-Agent 映射为 1,其余为 0;再在 server 或 location 中根据该变量拒绝请求:
http {
# 定义黑名单 User-Agent 匹配规则(支持正则)
map $http_user_agent $blocked_ua {
default 0;
~* (sqlmap|nikto|wget|curl|masscan|nmap|Go-http-client) 1;
~* python-requests/.*$ 1;
~* ZmEu 1; # 常见扫描器
~* Sogou web spider 0; # 白名单示例:允许搜狗爬虫
}
<pre class="brush:php;toolbar:false;">server {
listen 80;
server_name example.com;
# 在 location 中拦截
location / {
if ($blocked_ua) {
return 403 "Access denied.";
}
# 其他配置...
try_files $uri $uri/ =404;
}
}
}
注意:map 必须写在 http 块顶层,不能放在 server 或 location 内;if 虽不推荐在 location 外使用,但在 location 内配合 $blocked_ua 这类 map 变量是安全且常见的做法。
纯 location + if 的简易方式(适合临时或简单场景)
若只需在某个目录(如 /admin)下限制,可直接在对应 location 中判断:
location ^~ /admin/ {
if ($http_user_agent ~* "(sqlmap|nikto|curl|wget)") {
return 403;
}
# 正常代理或静态服务配置
proxy_pass http://backend;
}⚠️ 注意:if 在 location 内仅用于简单条件判断(如变量匹配、return/rewrite),不要在里面嵌套 proxy_pass 等指令,否则可能引发意外行为。
验证与调试技巧
- 用 curl 模拟请求测试:
curl -H "User-Agent: sqlmap/1.0" http://example.com/admin/应返回 403 - 开启 Nginx 错误日志(
error_log /var/log/nginx/error.log notice;),观察是否有 map 解析错误 - User-Agent 字符串区分大小写,正则中加
i标志可忽略大小写(Nginx 默认~*就是忽略大小写的) - 避免过度拦截主流爬虫(如 Googlebot),否则影响 SEO;建议先记录再拦截:
log_if $blocked_ua;配合自定义日志格式分析流量
补充:屏蔽空 User-Agent 或非常规格式
有些扫描器会发空 UA 或只含空格,可一并拦截:
map $http_user_agent $blocked_ua {
default 0;
"" 1; # 完全为空
"~^\s*$" 1; # 只有空白字符
~* (sqlmap|...) 1;
}这样能覆盖更多异常请求,提升基础防护水位。










