应配置 default_server 拦截 ip 访问:在 http 块顶部添加监听 80/443 的 server,server_name _,return 444;业务 server 必须明确指定域名,禁用 ip 或空 server_name;验证后重载 nginx。

直接用 IP 访问服务器存在安全风险,比如他人把未备案域名解析到你的 IP,可能引发监管问题或流量被劫持。Nginx 本身默认允许 IP 访问,需要主动配置“兜底 server”来拦截这类请求。
添加一个 default_server 拦截块
这是最常用、最可靠的方式:在 /etc/nginx/conf.d/ 或 /etc/nginx/nginx.conf 的 http 块内,最顶部(所有其他 server 前)添加一个专门处理“无匹配域名”的 server:
- 监听 80 和 443 端口,并标注
default_server -
server_name _;表示匹配任意无效或空的 Host 头 - 用
return 444;直接断开连接(浏览器显示空白或 ERR_EMPTY_RESPONSE),比 403/404 更干净,不暴露服务信息
示例配置:
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
ssl_certificate /path/to/your/cert.pem;
ssl_certificate_key /path/to/your/key.pem;
return 444;
}
注意:如果只配了 HTTP,HTTPS 请求会 fallback 到其他 server;所以建议同时监听 443 并提供有效证书,否则可能返回 400 错误。
确保业务 server 明确指定域名
你真正提供服务的 server 块里,server_name 必须写具体域名,不能留空或写 IP:
- ✅ 正确:
server_name example.com www.example.com; - ❌ 错误:
server_name 192.168.1.100;或server_name ""; - 多个域名用空格分隔,支持通配符如
*.example.com(需对应证书)
验证和生效
配置完成后必须严格检查并重载:
- 运行
sudo nginx -t确认语法无误 - 执行
sudo systemctl reload nginx(或nginx -s reload) - 测试:
curl -I http://你的服务器IP应无响应或返回空;curl -H "Host: example.com" http://你的IP也不应命中业务站点(除非你显式允许)
补充说明:为什么不用 if + $host 判断?
有人尝试在业务 server 内用 if ($host != "example.com") { return 403; },但这种方式有缺陷:
- HTTP/HTTPS 协议层 Host 头可被伪造,不如 default_server 从连接入口拦截彻底
- if 在 location 外使用有性能和逻辑限制,Nginx 官方不推荐用于访问控制
- 无法覆盖 HTTPS SNI 未匹配或空 Host 的情况
default_server 方案简单、高效、符合 Nginx 设计逻辑,是生产环境首选。











