1. 问题背景

在配置 Nginx 反向代理时,遇到以下问题:

  • “串台”现象:访问未配置的域名或直接访问 IP 地址时,Nginx 会显示某个已存在网站的页面。
  • 异常重定向:HTTP 请求被错误地重定向到其他网站的 HTTPS 页面。

原因分析

这是 Nginx 的 Default Server (默认服务器) 机制导致的。

  • 当请求的 Host 头无法匹配任何 server_name 时,Nginx 会将请求交给默认服务器处理。
  • 如果没有显式设置 default_server,Nginx 会默认使用加载顺序中的第一个配置文件作为默认服务器。

2. 解决方案:创建“兜底”配置

通过创建一个优先级最高的默认服务器,拦截所有未匹配的请求,并直接断开连接。

2.1 创建配置文件

新建文件 /etc/nginx/conf.d/00-default.conf00 前缀确保优先加载):

server {
    # 1. 监听 80 端口,并标记为默认服务器
    listen 80 default_server;
    listen [::]:80 default_server;

    # 2. 监听 443 端口,并标记为默认服务器
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    # 3. 匹配所有域名
    server_name _;

    # 4. SSL 证书配置 (必须有,否则 443 监听会报错)
    # 使用自签名证书,因为此站点仅用于拦截
    ssl_certificate /etc/pki/nginx/server.crt; 
    ssl_certificate_key /etc/pki/nginx/private/server.key;

    # 5. 核心动作:直接断开连接
    # 444 是 Nginx 特有代码,不返回任何 Header 和 Body,直接关闭 TCP 连接
    return 444; 
}

2.2 生成自签名证书

由于该“兜底”站点没有真实域名,无法申请 Let's Encrypt 证书,因此需要生成自签名证书以开启 SSL 监听。

# 创建私钥存放目录
sudo mkdir -p /etc/pki/nginx/private

# 生成有效期 10 年的自签名证书
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
  -keyout /etc/pki/nginx/private/server.key \
  -out /etc/pki/nginx/server.crt \
  -subj "/C=CN/ST=State/L=City/O=Organization/CN=localhost"

2.3 重载配置

# 检查配置语法
sudo nginx -t

# 重载 Nginx
sudo systemctl reload nginx

3. 效果验证

配置生效后:

  • 正常访问http://your-domain.com -> 正常进入对应网站。
  • 非法访问http://IP地址http://未知域名 -> 浏览器显示“无法连接”或“未发送任何数据”。
  • HTTPS 非法访问https://IP地址 -> 连接直接断开(不会显示证书错误页)。

4. 知识点补充

  • default_server:Nginx 的指令参数,用于指定当所有 server_name 都不匹配时,由哪个 server 块来处理请求。
  • return 444:Nginx 非标准状态码。相比于 return 403 (Forbidden) 或 return 404 (Not Found),444 更节省服务器资源,且能更好地隐藏服务器信息。
  • conf.d/ vs default.d/

    • conf.d/:存放完整的网站配置(server 块)。
    • default.d/:存放可复用的配置片段(如 PHP 处理逻辑),供 server 块内部引用。