Nginx通过map预定义恶意UA特征并标记,再用if+return在请求入口拦截,高效实现流量清洗;需兼顾空UA、极短UA、工具名裸串等边界情况,并结合日志观察与多层防护避免误杀。

用 Nginx 做流量清洗和 UA 过滤,核心是利用 map、if 和 return 配合正则匹配,在请求进入后端前就拦截恶意 UA,减轻源站压力。关键不是“全量过滤”,而是识别高频、明确的恶意特征并快速拒绝。
识别典型恶意 UA 特征
真实攻击流量的 UA 往往有明显规律,比如:
- 包含扫描器关键词:如
sqlmap、nmap、dirbuster、gobuster、whatweb - 伪装成浏览器但格式异常:如
Mozilla/5.0 () AppleWebKit/537.36(中间空括号)、curl/7.*/libcurl(非交互式工具) - 重复高频、无 Referer、User-Agent 固定且极简:如
python-requests/2.28(未加自定义 header 的爬虫脚本) - 含漏洞利用痕迹:如
WordPress后跟疑似 payload 的路径片段、phpmyadmin+ SQL 注释符
用 map 构建高效 UA 黑名单
避免在 server 或 location 中大量 if ($http_user_agent ~* ...),推荐用 map 提前映射标记,性能更好、逻辑更清晰:
<!-- 写在 http 块中 -->
map $http_user_agent $bad_ua {
default 0;
"~*sqlmap" 1;
"~*nmap" 1;
"~*dirbuster" 1;
"~*gobuster" 1;
"~*whatweb" 1;
"~*nikto" 1;
"~*hydra" 1;
"~*curl/[0-9]" 1;
"~*wget/" 1;
"~*python-requests" 1;
"~*java.*http" 1;
"~*Go-http-client" 1;
"~*masscan" 1;
}之后在 server 或 location 中统一判断:
if ($bad_ua) {
return 403;
}补充策略:UA 空值、过短、或仅含基础标识也需限制
很多自动化工具会省略 UA 或设为空,或只写 Wget、curl,这类也应拦截:
- UA 为空:
if ($http_user_agent = "") { return 403; } - UA 长度小于 10 字符(排除极简但合法的旧设备 UA,可按需调):
if (${http_user_agent} ~ "^.{0,9}$") { return 403; } - UA 仅为已知工具名(无版本/上下文):
if ($http_user_agent ~ "^(curl|wget|httpie|fetch)$") { return 403; }
注意避坑与验证方式
实际部署时容易忽略的点:
-
不要在 if 中嵌套多层正则或使用复杂逻辑:Nginx 的
if是“伪指令”,仅适合简单条件;复杂匹配必须用map -
避免误杀正常流量:某些企业监控系统、合规检测平台也会用
curl或python-requests,建议先log_format记录疑似 UA,观察 1–2 天再启用return 403 -
UA 可被伪造,不能作为唯一防线:配合 IP 频率限制(
limit_req)、Referer 检查、必要时接入 WAF 或 Bot Manager -
验证是否生效:用
curl -H "User-Agent: sqlmap/1.7" https://yoursite.com/测试返回是否为 403;同时检查 Nginx error log 是否出现client denied by rule类提示

















