文案站挂进Nginx集群后502:Host头与WebSocket的排查复盘

发布于 15天前 ❤ 0 👁 17 阅读 💬 1 评论

这篇记录我在一个CMS站点接进别人的Nginx反向代理后,踩到的两个真坑:一个把整站打成502,一个让协同编辑静默失效。全部现象与验证都是本机实测。

背景

我手上有一个基于Node的CMS站点(内容管理用,跑在3000端口,本机lo回环监听)。新需求是接进公司统一入口:由统一网关的Nginx集群按主域名分发,HTTPS由网关侧终止,我这边只需要一个HTTP上游。

按经验,把站点接进别人的Nginx应该是最省事的一步,结果上来就挂了。

第一个坑:网关证是合并SAN证,SNI拿不到匹配证书,握手直接失败

现象:用主域名访问返回502,网关错误日志里全是"no suitable certificate"这类握手报错,后端Node进程却一切正常,直连IP的3000端口200。

我一开始怀疑是Nginx配置写错了upstream,反复核对location和proxy_pass,没问题。后来用openssl s_client连了一下,才看清根因:网关那台机器上证书是「合并SAN」的一张证,同时包含主域名和另外两个子域,但Nginx里这个server块的server_name写的是子域,SNI进来的是主域名,于是证书选择阶段就挑不出一张能匹配的证书,TLS握手失败,浏览器侧表现就是502/连接被重置。

修法两步:一是把这个server块的server_name改成覆盖主域名(或者干脆加default_server兜底),二是用openssl s_client -servername 主域名 -connect 网关:443 复验,确认返回的证书SAN里包含主域名才算完。

这里踩出来的经验是:502不一定是后端挂了。网关到后端这一段如果压根没握手成功,浏览器看到的也是502。排查顺序应该是:先在后端机curl自己的端口(确认后端活)→再curl网关IP并显式带Host头(确认分发正确)→最后openssl s_client看SNI与证书(确认TLS层)。把这三层分开,5分钟能定位,否则就会在upstream配置里瞎改。

第二个坑:协同编辑走WebSocket,Nginx默认不升264级

TLS修好后静态页面正常,但协同编辑功能没反应:打开编辑器,页面不报错,字数栏不动,两个人同时改互相看不到。

查浏览器控制台,WebSocket连接一直pending然后失败。原因是Nginx默认不会把Upgrade请求转发给上游——普通HTTP请求能过,带Upgrade的都死在网关。同时上游侧也得接受外部Host,否则应用侧的跨域判断会拒掉。

最终配置的关键三行:proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade",再加proxy_set_header Host $host。补完之后协同编辑立刻正常。

顺带发现的一处旧代码坑

排查过程中我还顺手翻了自己站点的库访问代码,发现一处双标写法:变量声明时名字写的是一个(DB_PATH),打开时却硬编码了"data/app.db"。当时正好有环境变量兜底,所以线上跑着没出事——但这属于埋雷:哪天换库路径,变量改了而硬编码没改,就会出现「以为连的是新库、实际写的是旧库」,而且因为周围有try/catch兜底,可能连报错都没有,静默写错地方。

我的处理方式是把硬编码全部收敛到一个DB_PATH(环境变量优先,其次默认路径),并且让「库打不开」这种情况直接抛错而不是被catch吞掉。凡是catch里什么都不做的代码,都值得回头看一眼,它吞掉的不只是异常,往往还有需要立刻知道的事实。

可复用的结论

  1. 接别人的Nginx,先确认三件事:SNI证书是否覆盖你的域名、Upgrade头是否透传、Host是否透传。这三条不过,后面所有排查都是浪费。
  2. 502优先怀疑TLS握手,不是后端进程。
  3. 路径类配置不要留硬编码兜底,环境变量改了硬编码没改等于静默写错库。
  4. 空catch是排查事故的隐形人,宁可让它抛出来。

补一句成本口径:这次从502到全部正常,实际动手约40分钟,其中30分钟浪费在没先分层验证、直接在upstream配置里反复试。先分层、再动手,比改配置快得多。

评论 (1)

Meicheng · 站长
Meicheng · 站长 14天前
同踩过 Host 头的坑,补两个容易漏的点:一是 proxy_pass 尾部带不带斜杠会改变路径拼接,排查时先 curl 一下网关看是 404 还是 502,能快速定位到底是哪一层出了问题;二是 WebSocket 是否真升级成功,用浏览器 Network 面板看握手响应是不是 101 Switching Protocols,如果还是 200 但功能时好时坏,十有八九是 Upgrade/Connection 头没透传,Nginx 里给 /ws 单独加 proxy_set_header Upgrade $http_upgrade。复盘很扎实,收藏了。

登录 后参与评论