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

带SNI和子域名的Nginx反向代理重定向配置异常排查

解决Nginx Stream ssl_preread通配符子域名路由失效问题

你碰到的no host in upstream ""错误,核心是当请求匹配通配符子域名时,$name变量没被正确赋值,导致proxy_pass找不到对应的上游服务。我来帮你梳理下问题和解决方案:

问题根源

你的map配置里用了*.my.domain.com这种通配符写法,但在Nginx Stream模块的map指令中,通配符匹配有时候会因为规则优先级或解析逻辑的问题,无法正确匹配到子域名请求,最终导致$name为空,触发上游找不到的错误。

解决方案:改用正则表达式匹配子域名

把通配符替换成正则表达式,能更可靠地匹配所有my.domain.com的子域名,确保$name被正确赋值。修改后的map配置如下:

map $ssl_preread_server_name $name {
    ~^.+\.my\.domain\.com$ c;  # 匹配所有以.my.domain.com结尾的子域名
    a.another.domain.com a;
    b.another.domain.com b;
}

这个正则~^.+\.my\.domain\.com$会精准匹配任何形如xxx.my.domain.com的子域名(比如test.my.domain.com、dev.my.domain.com),完全覆盖你需要的通配符场景。

额外排查步骤

  1. 确认SNI是否正确获取:查看你的stream_443.log日志,执行tail -f /var/log/nginx/stream_443.log后发起请求,检查with SNI name字段是否显示了正确的子域名。如果SNI为空,说明ssl_preread没有正常工作,需要确认Nginx编译时包含了--with-stream_ssl_preread_module模块。
  2. 测试时指定SNI:用curl测试时,要确保请求携带正确的SNI,比如:
    curl -v --resolve test.my.domain.com:443:你的Nginx机器IP https://test.my.domain.com
    
    有些环境下curl不会自动发送SNI,用--resolve可以强制指定域名对应的IP,确保SNI被正确传递。
  3. 添加默认规则(可选):为了避免未匹配到的请求报错,可以在map末尾加一个默认值,比如:
    map $ssl_preread_server_name $name {
        ~^.+\.my\.domain\.com$ c;
        a.another.domain.com a;
        b.another.domain.com b;
        default c;  # 所有未匹配的请求都走upstream c,或者根据需求调整
    }
    

验证配置

修改完配置后,执行nginx -t检查语法是否正确,然后nginx -s reload重启Nginx,再测试子域名请求,应该就能正常路由到upstream c了。

内容的提问来源于stack exchange,提问作者Zaída De Isidro Navarro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:59:37