应配置唯一 default_server 拦截非法 host 请求:在 listen 80/443 后加 default_server,server_name 设为 _,并 return 444;https 需配占位证书;避免多 default_server 或遗漏 default_server 标识。

要拒绝未在 server_name 中定义的空主机头(即没有 Host 头、Host 为空或 Host 值不匹配任何已配置域名的请求),核心是主动拦截,而非依赖默认行为。Nginx 不会自动拒绝非法 Host 请求——它会把这类请求交给第一个能“兜底”的 server 块处理,除非你显式控制。
明确配置 default_server 拦截非法请求
Nginx 匹配虚拟主机时,若请求不含 Host 头(如 HTTP/1.0 请求、扫描器探测、curl -v https://www.php.cn/link/73ba3f47a4cefcb80b3fd2a8122b21f9 Host 值不匹配任何 server_name,它将路由到标记为 default_server 的 server 块。
必须确保:
- 只有一个
listen 80 default_server(同理listen 443 default_server ssl) - 该块放在所有其他
server块之前(或至少确保它被优先加载)
推荐写法:
server {
listen 80 default_server;
server_name _; # 占位用,不参与匹配,仅语义清晰
return 444; # 立即关闭连接,无响应体,最安全
}
⚠️ 注意:
return 444是 Nginx 特有状态码(非 HTTP 标准),作用是直接断开 TCP 连接,比return 403或return 500更彻底,防爬虫、防恶意解析效果更好。
避免常见配置错误
- ❌ 只写
server_name _但没加default_server→ 请求仍可能落到其他server块(按配置顺序第一个匹配的) - ❌ 多个
default_server→nginx -t会报错:“duplicate default_server for 0.0.0.0:80” - ❌ 把兜底块写在其他
server后面且没加default_server→ 它不会生效 - ❌ 用
server_name ""(空字符串)→ 虽然能匹配部分空 Host,但不如default_server+server_name _明确可靠
补充:HTTPS 场景同样需要兜底
HTTP 和 HTTPS 是独立监听端口,需分别配置:
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /path/to/placeholder.crt; # 必须提供有效证书(哪怕自签)
ssl_certificate_key /path/to/placeholder.key;
return 444;
}
没有证书会导致 TLS 握手失败,但 default_server 仍需存在,否则非法 HTTPS 请求可能穿透到业务 server。
可选增强:配合 map 模块做 Host 白名单校验
如果业务复杂、域名多变,可结合 map 提前过滤 Host:
map $host $allowed {
default 0;
"example.com" 1;
"www.example.com" 1;
}
server {
listen 80 default_server;
if ($allowed = 0) {
return 444;
}
# 其余配置...
}
这种方式更灵活,但 if 在 server 块中使用需谨慎;生产环境建议优先用 default_server + return 444 方案,简单、高效、无副作用。
不复杂但容易忽略











