排查泛解析错误需先确认“谁真正响应请求”,通过nginx -T查配置加载顺序、default_server标记及server_name匹配逻辑,验证通配符规则与兜底块冲突。

排查 server_name 泛解析指向错误,核心是弄清“谁真正响应了请求”,而不是“谁写了泛域名”。Nginx 不报错、不警告(除非有重复定义),而是静默按优先级把请求交给某个 server 块——结果就是你访问 api.example.com,却打开默认页或测试站。
看实际生效的配置结构
用 nginx -T 输出合并后完整配置,直接定位你的泛域名是否被加载、在哪、是否被覆盖:
-
nginx -T 2>/dev/null | grep -A 15 "server_name.*\*.example\.com"—— 查找泛域名配置是否存在、上下文是否完整(比如有没有漏listen) -
nginx -T 2>/dev/null | grep "listen.*80" -A 3—— 列出所有监听 80 的server块,注意顺序和default_server标记 - 重点检查:同一端口下是否多个块都写了
*.example.com?后加载的那个会被静默忽略(日志里可能有conflicting server name警告)
验证泛域名匹配是否真生效
Nginx 的泛域名只支持最左通配(*.example.com)或最右通配(example.*),不支持中间或双星。常见失效场景:
-
*.example.com不匹配example.com(顶级域需单独写) -
*.example.com不匹配www.example.com?其实它能匹配——但如果你另有一个server_name www.example.com的精确块,且排在前面,那请求就会被它截走 - 用
curl -H "Host: test.example.com" http://127.0.0.1绕过 DNS 直连,观察返回内容和响应头,确认是否进对了块
检查兜底逻辑是否抢了流量
没设 default_server 并不安全。Nginx 会把第一个定义的 server 块当作隐式兜底——IP 直接访问、Host 头缺失或非法时,必然落到它身上:
- 搜索所有监听 80 的块:
nginx -T 2>/dev/null | awk '/^server {/,/^}/ {if (/listen.*80/) print FILENAME ":" NR; if (/server_name/) print " " $0}' - 确保兜底配置(如
99-default.conf)明确带default_server,且server_name尽量空或写成"",避免意外匹配 - 在疑似“吃掉”泛域名请求的兜底块里加
return 444;或access_log /var/log/nginx/catch-all.log;,再发请求看日志是否有记录
用日志和响应头确认路由路径
别依赖文件名或目录位置。真实请求才说明问题:
- 临时把泛域名配置改名为
00-api.conf(让它最先加载),重启 Nginx;如果原来 404 的子域名突然正常,说明是加载顺序或兜底冲突 - 在目标
server块里加add_header X-Handled-By "api-server";,用curl -I检查响应头是否出现 - 在
log_format中加入$host和$server_name,对比访问日志里的实际 Host 和匹配到的 server_name 值











