Nginx拒绝未绑定域名访问的核心是配置default_server接管无匹配请求:在80和443端口分别设置listen ... default_server的server块,server_name _,并return 444断开连接;HTTPS需配有效证书,确保TLS握手阶段即拦截。

要让 Nginx 拒绝所有未明确配置的域名访问(比如别人把 bad.com 或 xxx.123.attacker.net 解析到你的服务器 IP),核心不是靠 server_name 过滤,而是用 listen ... default_server 主动接管“没人认领”的请求。只要配置得当,恶意解析、IP 直连、错填 Host 头的请求都会被统一拦截。
关键原理:default_server 才是真正的“守门人”
Nginx 匹配请求时,先看 Host 请求头和各 server 块的 listen 地址+端口是否一致,再比对 server_name。但一旦没有 server 显式匹配成功,Nginx 就会把请求交给该端口上标记了 default_server 的那个块——它不看 server_name 是否吻合,只认这个标记。所以:
-
server_name _或留空只是习惯写法,语义上表示“不关心域名”,但不是必须 - 即使写成
server_name example.com,只要加了default_server,它照样响应unknown.org - 同一端口(如
80或443)只能有一个default_server,多了会报错 - 没写
default_server时,Nginx 默认选该端口第一个server块——行为不可控,务必显式声明
HTTP 端口(80)的标准拦截配置
这是最基础也最关键的一步。新建一个独立配置文件(如 /etc/nginx/conf.d/default-block.conf),内容如下:
server {
listen 80 default_server;
server_name _;
return 444;
}
说明:
-
return 444是 Nginx 特有的非标准状态码,直接断开 TCP 连接,不发任何响应体,对扫描器和恶意请求最“干净” - 也可改用
return 403(拒绝访问)或return 404(资源不存在),适合需要日志记录的场景 - 避免用
rewrite或return 301跳转——这等于帮攻击者确认你的 IP 是活的,还可能暴露主站域名
HTTPS 端口(443)必须单独配置
HTTPS 在 TLS 握手阶段就要选证书,Host 头还没传过来。如果客户端不支持 SNI,或所请求域名没对应证书,Nginx 只能按 default_server + 该块里的证书来应答。因此:
- 443 端口同样要加
default_server,且不能遗漏 - 该
server块必须包含有效的ssl_certificate和ssl_certificate_key;建议用泛域名证书、自签名证书,或 Let’s Encrypt 的通配符证书 - 配置示例:
server {
listen 443 ssl http2 default_server;
server_name _;
ssl_certificate /path/to/wildcard.crt;
ssl_certificate_key /path/to/wildcard.key;
return 444;
}
验证是否生效的实用方法
别只信配置文件,动手测才放心:
- 用
curl模拟非法 Host:curl -H "Host: fake.example" http://your-server-ip/curl --resolve "evil.com:443:your-server-ip" https://evil.com/ - 检查 Nginx 错误日志:
tail -f /var/log/nginx/error.log,看是否有 “no server matching the request” 类警告 - 运行
nginx -t确保语法无误,再nginx -s reload生效 - 特别注意:若已有其他
server块在 80 或 443 端口漏写了default_server,新配置可能不生效——逐个检查监听行











