关键是要用return 444配合listen 80 default_server和listen [::]:80 default_server显式声明兜底,立即关闭连接、不响应、不日志、不消耗资源,ipv4/ipv6需分别配置,且不可重复或单独写default_server。

要让 Nginx 安全又高效地拦截未匹配的请求(比如输错域名、直接用 IP 访问、Host 头为空),关键不是“拦住”,而是“快速断开”——不响应、不日志、不消耗资源。最推荐的做法是用 444 状态码,它会让 Nginx 立即关闭连接,不发任何响应体,也不记录 access log(可选),从协议层就终止请求。
default_server 必须显式声明在 listen 指令上
兜底行为依赖 default_server 修饰符,它不是独立指令,必须和 listen 绑定:
- ✅ 正确:
listen 80 default_server;或listen 443 ssl http2 default_server; - ❌ 错误: 单独写
default_server;(Nginx 启动会报错) - ⚠️ 注意:IPv4 和 IPv6 是分开的端口维度,
listen [::]:80也要单独加default_server
用 444 精准切断连接,避免无效响应
返回 444 比返回 404 或重定向更彻底——不构造响应头、不写 body、不触发日志(除非你显式开启 error_log),CPU 和带宽零浪费:
- 配置示例:
server {<br> listen 80 default_server;<br> listen [::]:80 default_server;<br> return 444;<br>} - 不写
server_name或写成server_name "";都不影响兜底生效 - 如果需要记录异常访问,可在该 server 块中启用
error_log /var/log/nginx/default_error.log warn;,但不要开access_log
防止默认主机被意外绕过
常见错误会导致兜底失效,需主动规避:
- 不要依赖
server_name _;或server_name "";当作兜底——它们只是普通 server,没加default_server就不会生效 - 检查所有
listen 80的 server 块,确保只有一个含default_server;重复会导致 reload 失败 - 若使用泛域名(如
server_name *.example.com;),它仍属于“匹配成功”,不会落到 default_server,无需额外处理
配合全局参数减少哈希开销
当虚拟主机数量多时,server_name 匹配本身有哈希计算成本。可通过调优降低这部分消耗:
- 在
http块中增大哈希桶大小:server_names_hash_bucket_size 512; - 扩大哈希表容量:
server_names_hash_max_size 4096; - 这两项能显著减少因哈希冲突导致的匹配延迟,尤其在上百个域名共存时效果明显











