Nginx端口80默认虚拟主机无法访问,请求匹配错误server_name如何解决
问题根本原因
Nginx匹配server块的优先级规则是先匹配listen指令的精确程度,再在同listen优先级的server块中匹配server_name,你的配置踩了这个规则的坑:
- 你第二份跳转配置的listen指令写的是
listen SERVER-IP:80,属于绑定了具体IPv4地址的监听规则,优先级远高于默认块、OTHER-FQDN块中listen 80(即通配所有IPv4地址的监听规则) - 所有发往该服务器IP 80端口的IPv4请求,都会优先被归类到绑定了
SERVER-IP:80的server组中,这个组目前只有跳转配置对应的server块,哪怕请求的Host是IP、OTHER-FQDN,在该组中没有匹配的server_name时,会默认选中该组的第一个server块(也就是你的跳转块),直接返回301跳转 - 额外补充:301是永久重定向,浏览器会长期缓存该规则,即使后续配置修改,也可能因为浏览器缓存直接跳转,干扰测试结果
匹配规则修复方案
两种方案二选一即可:
- 方案1:统一所有80端口server块的listen规则,都写成
listen 80;和listen [::]:80;,让所有块处于同一listen优先级,此时Nginx会优先匹配server_name,匹配不到才走标了default_server的默认块 - 方案2:如果需要绑定具体IP,在默认块中补充
listen SERVER-IP:80 default_server;,让默认块也加入SERVER-IP:80的监听组,且作为该组的兜底规则
确认请求匹配server块的方法
- 方法1:执行
nginx -T(大写T)命令,会打印所有已加载的配置文件及加载顺序,可直观查看同一监听端口的server块排序、规则差异 - 方法2:给每个server块配置独立的访问日志,例如跳转块加
access_log /var/log/nginx/redirect.access.log;、默认块加access_log /var/log/nginx/default.access.log;,请求后查看对应日志的写入情况即可确定匹配的块 - 方法3:测试时避免使用浏览器(防止301缓存干扰),用curl命令发起请求,示例:
curl -v -H "Host: OTHER-FQDN" http://你的服务器IP,可直接查看返回的状态码、响应头和内容
内容的提问来源于stack exchange,提问作者Aron
相关产品推荐
相关产品推荐

