Nginx配置问题:带TLS透传的WebSocket反向代理实现
解决Nginx TLS透传WebSocket代理的问题
问题拆解
你要做的是TLS透传(SSL Passthrough)——让客户端直接和后端WebSocket服务器完成TLS握手,Nginx只负责转发TCP流量就行。之前的两个配置都踩了坑:
HTTP模块配置错得离谱:
- 你给
listen 443却没配SSL证书,Nginx想和客户端握手但拿不出证书,直接触发SSL版本错误; - HTTP模块是用来解析HTTP请求的,而TLS透传需要原封不动转发TCP流量,根本不该用HTTP模块来搞这个。
- 你给
Stream模块配置的潜在问题:
- 可能是443端口被之前的HTTP模块配置占了;
- 后端AWS WebSocket网关的安全组没开代理服务器静态IP的访问权限;
- 少数情况是Nginx的TCP连接转发没调好(不过默认Stream模块是支持的)。
正确的Stream模块配置
用Stream模块做纯TCP转发才是TLS透传的正确姿势,配置如下:
stream { upstream websocket_backend { server mybackendserver.com:443; # 要是需要故障转移,再加备用后端就行 # server backup-backend:443 backup; } server { listen 443; proxy_pass websocket_backend; # WebSocket是长连接,超时时间设长点 proxy_timeout 1d; proxy_connect_timeout 10s; } } # 记得把HTTP模块里占用443端口的配置删掉或者注释掉! # http { # ... # server { # listen 443; # 这个必须干掉 # ... # } # }
必做检查步骤
确认Nginx支持Stream模块:
跑这个命令看看:nginx -V 2>&1 | grep -- '--with-stream'输出里有
--with-stream就没问题;要是没有,就得装带Stream模块的Nginx包(比如Ubuntu装nginx-full),或者重新编译的时候加上这个参数。检查443端口有没有被占:
用这个命令查:sudo lsof -i :443要是有其他进程占着,要么停掉那个进程,要么换个监听端口。
安全组和防火墙必须配对:
- 代理服务器:开放443端口的TCP入站流量;
- 后端AWS网关:在安全组里加代理服务器的静态IP,允许这个IP访问443端口。
用verbose模式测试排错:
跑这个命令看详细日志:wscat -c wss://myproxy.com --verbose成了的话会显示TLS握手成功,WebSocket连接建立;要是还失败,看日志里的细节就能定位问题(比如DNS解析错了、防火墙拦了、证书不匹配之类的)。
额外说明
因为后端服务器的证书已经包含myproxy.com域名,客户端握手时发的SNI(服务器名称指示)会直接透传给后端,后端返回的证书能被客户端验证通过,所以整个流程能正常走通。
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

