You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx多域名配置无效子域名catch-all块报重复default_server错误

问题根因

两个异常的核心触发原因:

  • 重复default_server启动报错:Nginx同一监听端口(含对应IPv4/IPv6地址)全局仅允许定义一个default_server块,你在domain1、domain2的配置中各声明了一个443端口的default_server,必然触发重复定义错误。
  • 移除default_server后的重定向死循环:这里有两个问题,一是你写的_.domain1.com是无效匹配规则——Nginx的域名通配符仅支持放在域名最前或最后位置,_本身是无意义的占位符而非通配符,放在域名中间完全无法匹配预期的子域名;二是Nginx的server块匹配优先级为「精确server_name匹配 > 前置通配符匹配 > 后置通配符匹配 > 正则匹配 > 对应端口第一个加载的server块」,无效子域名请求匹配不到任何有效规则时,会命中第一个加载的443 server块(也就是裸域跳www的规则),该规则会给当前$host前缀加www后跳转,下一次请求依然匹配不到有效规则,会持续给域名前缀叠加www,最终形成死循环。

另外你贴的原始配置里还有几处语法笔误,包括server_name行末尾缺失分号、[::]443缺失冒号、server_name:多写了冒号,这些也会导致配置加载失败,修复时需要一并修正。

修复步骤

1. 配置全局兜底default_server

删除所有域名独立配置中带default_server标记的catch-all块,在主配置文件(即你原来的default.conf)所有域名配置include语句的最前面,添加全局唯一的80、443端口兜底server块,拦截所有完全不匹配已配置域名的请求:

# 80端口全局兜底
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 404;
}

# 443端口全局兜底
server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name _;
    # 替换为机器上任意一份有效SSL证书路径即可,仅用于完成SSL握手
    ssl_certificate /path/to/any/valid/fullchain.pem;
    ssl_certificate_key /path/to/any/valid/privkey.pem;
    return 404;
}

2. 修正单域名的无效子域名拦截规则

对每个域名的独立配置文件做两处调整:

  • 修正通配符规则:将原来无效的_.domain.com写法替换为正确的前置通配符*.domain.com,通配符块不要加default_server标记
  • 调整块顺序:将子域名拦截的通配符块放在该域名所有443端口server块的最末尾,利用Nginx最长匹配优先级规则,保证只有未单独配置的子域名才会命中该拦截块
    以domain1.conf为例,修正后配置如下:
# HTTP统一跳HTTPS
server {
  listen      80;
  listen      [::]:80;
  server_name domain1.com www.domain1.com;
  return      301 https://$host$request_uri;
}

# 裸域跳www
server {
  listen      443 ssl http2;
  listen      [::]:443 ssl http2;
  server_name domain1.com;
  include     /path/to/ssl_config.conf;
  return      301 https://www.$host$request_uri;
}

# 正常提供服务的www子域名
server {
  listen      443 ssl http2;
  listen      [::]:443 ssl http2;
  server_name www.domain1.com;
  include     /path/to/ssl_config.conf;
  location    / { proxy_pass http://$app; }
}

# 拦截该域名下所有未单独配置的子域名
server {
  listen       443 ssl http2;
  listen       [::]:443 ssl http2;
  server_name  *.domain1.com;
  include      /path/to/ssl_config.conf;
  return       404;
}

domain2.conf按完全相同的逻辑调整,替换对应域名为domain2.com即可。

3. 校验并重载配置

执行配置语法校验:

nginx -t

确认输出syntax is okay、test is successful后,重载Nginx使配置生效:

nginx -s reload
修复逻辑说明
  • 全局仅保留一份default_server配置,从根源解决重复default_server的启动报错,所有指向你服务器IP但未在Nginx中配置的域名请求,都会被全局兜底块直接拦截返回404。
  • 单域名下的*.domain.com通配符块放在同域名所有精确匹配规则之后,优先级低于精确配置的裸域、www子域名规则,只会命中foo.domain1.com这类未单独配置的子域名,不会干扰正常业务的跳转逻辑,彻底解决重定向死循环问题。

内容的提问来源于stack exchange,提问作者lonix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 23:09:18