关键在于listen指令必须显式声明default_server,而非server_name配置;http和https端口需分别设置ipv4/ipv6监听,配合return 444静默断连。

要让 Nginx 正确处理未定义域名(比如用 IP 直接访问、输错域名、恶意解析)的请求,关键不是靠 server_name 写什么,而是靠 listen 指令是否带 default_server 标志——这是唯一决定“兜底行为”的配置项。
default_server 是触发未定义域名处理的核心
Nginx 在收到请求时,先看 Host 头,再逐个匹配 server 块。但匹配的前提是:该 server 必须在对应端口上声明了 default_server。没有它,哪怕 server_name _; 写得再标准,也不会自动兜底。
- 同一端口只能有一个
default_server,多了会报错或忽略后几个 -
server_name的值(包括_、空、example.com)在此场景下完全不参与匹配逻辑 - IPv4 和 IPv6 需分别声明:
listen 80 default_server;和listen [::]:80 default_server;
HTTP 和 HTTPS 必须分开配置 default_server
HTTP 可直接基于 Host 头做路由;HTTPS 则在 TLS 握手阶段就需选定证书,依赖 SNI 字段。若客户端不发 SNI(如老旧工具或扫描器),或 Host 不匹配任何 server_name,且没配 default_server,Nginx 可能返回默认证书、连接中断,甚至泄露站点信息。
- HTTP 示例:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
} - HTTPS 示例:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_certificate /path/to/default.crt;
ssl_certificate_key /path/to/default.key;
return 444;
}
server_name _; 只是语义习惯,不是功能必需
server_name _; 是社区常用写法,表示“无特定名称”,便于人眼识别这是兜底块。但它本身不赋予任何特殊能力——删掉这行,只要 listen ... default_server; 还在,照样生效。
- 写成
server_name example.com;也完全没问题,只要加了default_server - 真正阻止非法访问的是
return 444(静默关闭 TCP 连接),不是server_name的内容 - 若想返回可读错误,可用
return 403或return 444,后者更彻底,不发任何响应体
避免常见配置陷阱
很多问题其实源于配置加载顺序或遗漏细节:
- 确保 default_server 配置文件被第一个加载(例如命名为
00-default.conf),否则可能被其他server块抢先匹配 - 不要只配
listen 80;却漏掉[::]:80,IPv6 请求可能绕过 default_server - 检查是否有多个
server块都写了listen 80;但没标default_server,这时 Nginx 会选第一个作为隐式兜底,行为不可控 - 修改后务必执行
nginx -t验证语法,并用nginx -s reload生效











