wss连接失败主因是nginx未正确透传websocket升级请求,需确保443 ssl server块中配置proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、map动态设置connection头,并排除waf拦截、路径错位及证书权限问题。

WSS连接失败,表面是“WebSocket connection to 'wss://...' failed”,但真正卡点往往不在证书本身,而在Nginx如何把客户端的升级请求完整、准确地转给后端。只要路径走对、头传全、协议对齐、中间层不拦截,WSS握手就能稳过。
确认SSL证书配置无硬伤
证书无效或链不全,会导致TLS握手阶段就失败,根本到不了WebSocket升级环节。
- 用
openssl s_client -connect yourdomain.com:443 -showcerts检查证书是否有效、是否包含完整中间证书 - 在宝塔等面板中,确认
ssl_certificate和ssl_certificate_key路径真实存在,且Nginx进程(如www用户)有读取权限(chmod 644/600,chown www:www) - 避免混用HTTP和HTTPS的
location块:WSS必须走server { listen 443 ssl; ... }下的配置,不能错配到80端口的HTTP块里
检查Upgrade头是否真正透传到后端
服务端日志若报Handshake failed due to invalid Upgrade header: null,说明Nginx没把Upgrade: websocket和Connection: upgrade这两个关键头送过去。
- 确保
proxy_http_version 1.1已启用——HTTP/1.0不支持Upgrade机制 -
proxy_set_header Upgrade $http_upgrade必须存在,且$http_upgrade是Nginx内置变量,会自动捕获客户端原始Upgrade头 - 不要写死
proxy_set_header Connection "upgrade",应配合map指令动态处理:
map $http_upgrade $connection_upgrade { default upgrade; '' close; }
proxy_set_header Connection $connection_upgrade;
这样既保证WebSocket请求设为upgrade,又避免普通HTTP请求被错误设置而引发问题
排查WAF或防火墙在握手前静默拦截
很多WSS失败没有Nginx错误日志,也没有后端报错,是因为WAF在L7层直接403/444拦截了带Upgrade: websocket的请求。
- 用
hosts文件将域名直解析到源站IP,绕过WAF测试——如果能连通,基本锁定是WAF干扰 - 查WAF访问日志,筛选目标路径(如
/ws)和状态码403或空响应体 - 在WAF控制台添加放行规则:匹配URI含
/ws或/socket,且请求头含Upgrade: websocket,动作设为“放行”并禁用关联防护规则 - 检查云厂商安全组和系统防火墙(
firewalld/ufw),确保WSS所用端口(如443,或自定义端口)已开放TCP入站
验证Nginx location路径与后端实际监听路径一致
前端连wss://example.com/chat,但Nginx转发到了http://127.0.0.1:8080/api/chat,而后端只监听/websocket——这种路径错位会导致404或400,看起来像升级失败。
- 前端WebSocket URL路径(如
/ws)要与Nginxlocation /ws { ... }完全匹配 -
proxy_pass末尾加不加/影响路径重写:proxy_pass http://backend/ws;→ 原路径/ws/chat变成/ws/ws/chat(错误)proxy_pass http://backend/;→/ws/chat变成/chat(推荐,需后端监听根路径) - 用
curl -i -H "Connection: upgrade" -H "Upgrade: websocket" https://yourdomain.com/ws手动模拟握手请求,看返回是否为101 Switching Protocols











