关键在于显式配置listen 80 default_server和listen 443 ssl default_server分别接管HTTP/HTTPS未匹配请求,server_name在其中无效,必须配有效证书(HTTPS)并返回444静默断连。

要让 Nginx 正确拦截所有未明确配置的域名请求(比如恶意解析、IP 直连、错填 Host 头),关键不是靠 server_name 过滤,而是用 default_server 主动接管“没人认领”的请求。它才是真正起作用的兜底机制。
必须在 listen 指令中显式加 default_server
default_server 不是独立指令,必须写在 listen 后面,否则 Nginx 会报错或不生效:
- ✅ 正确:
listen 80 default_server; - ✅ HTTPS 同样适用:
listen 443 ssl http2 default_server; - ❌ 错误:
default_server;单独一行(语法错误) - ❌ 错误:同一端口写两个
default_server(Nginx reload 会失败)
HTTP 和 HTTPS 需分别配置
80 和 443 是两个独立端口,各自需要一个 default_server:
- HTTP 请求走 80 端口,由
listen 80 default_server拦截 - HTTPS 请求走 443 端口,必须额外配
listen 443 ssl default_server - IPv4 和 IPv6 也需分开声明,例如
listen [::]:80 default_server; - HTTPS 的
default_server必须带有效证书(哪怕自签名),否则 TLS 握手阶段就可能失败或暴露默认站点
server_name 在 default_server 中基本无作用
只要标记了 default_server,Nginx 就会把未匹配请求交给它,完全不看 server_name 是否吻合:
- 写
server_name _;是惯例,语义清晰,但不是必需 - 写
server_name example.com;也照样响应bad.com - 真正决定兜底行为的是
listen ... default_server,不是server_name
推荐返回 444 或 403,避免信息泄露
兜底 server 块里不要返回真实内容,防止暴露服务器结构或主站信息:
-
return 444;:Nginx 特有状态码,直接断开 TCP 连接,最安静、最安全 -
return 403;:返回禁止访问,客户端能看到 HTTP 响应,适合调试时用 - 避免
return 301重定向到主站——这等于帮攻击者确认 IP 有效且可访问 - 不要留空或不做处理,否则可能被第一个 server 块意外接管,行为不可控


















