如何在 Nginx 中配置 WebSocket 反向代理支持 wss 协议升级

文章导读
在 Nginx 中配置 WebSocket 支持 wss 协议,核心是正确转发 Upgrade 和 Connection header,并将 HTTP 协议版本设为 1.1,同时需在 Nginx 侧终止 SSL 连接。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

在 Nginx 中配置 WebSocket 支持 wss 协议,核心是正确转发 Upgrade 和 Connection header,并将 HTTP 协议版本设为 1.1,同时需在 Nginx 侧终止 SSL 连接。

该方案适用于需要加密传输的实时通信场景,配置错误会导致握手失败返回 400 或 502 状态码。

先说结论:Nginx 原生支持 WebSocket 反向代理,但必须显式设置协议升级头并启用 HTTP 1.1 才能维持长连接。

  • 适合:需要透过 Nginx 转发 ws 或 wss 流量的反向代理场景
  • 先准备:确保证书有效且后端服务支持 WebSocket 握手
  • 验收:通过浏览器控制台或 curl 命令确认握手状态码为 101

命令速用版

以下是 Nginx configuration 中 location 块的核心配置片段,直接替换原有 proxy 设置:

location /ws/ {
    proxy_pass http://backend_server;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 86400s;
}

若需支持 wss,需在 server 块中配置 ssl_certificate 和 ssl_certificate_key,并监听 443 端口。

为什么会这样

WebSocket 握手基于 HTTP 协议升级机制,默认 HTTP 1.0 不支持长连接升级。

Nginx 默认 proxy_http_version 为 1.0,会关闭 Connection 头,导致握手中断。WSS 本质是 WebSocket over TLS,通常由 Nginx 处理 SSL 解密后以 ws 协议转发给后端,因此必须配置 SSL 证书。

如何在 Nginx 中配置 WebSocket 反向代理支持 wss 协议升级

分步处理

第一步:配置 SSL 证书(仅 wss 需要)。

在 server 块中监听 443 ssl,指定证书路径,确保 openssl 生成的证书有效。

第二步:编写 location 反向代理规则。

添加 proxy_set_header Upgrade 和 Connection 字段,强制 proxy_http_version 为 1.1。

第三步:调整超时时间。

WebSocket 是长连接,需增大 proxy_read_timeout 和 proxy_send_timeout,避免连接被主动切断。

如何在 Nginx 中配置 WebSocket 反向代理支持 wss 协议升级

第四步:重载配置。

执行 nginx -t 检查语法,执行 nginx -s reload 应用配置。

怎么验证是否生效

使用 curl 命令模拟握手请求,检查返回状态码是否为 101 Switching Protocols。

命令示例:curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: your_domain" https://your_domain/ws/。

或在浏览器开发者工具 Network 面板查看 WebSocket 请求状态,确认 Status 为 101 且数据能正常收发。

如何在 Nginx 中配置 WebSocket 反向代理支持 wss 协议升级

常见坑

坑一:忘记设置 proxy_http_version 1.1,导致后端收不到 Upgrade 头。

坑二:SSL 证书配置错误,导致 wss 握手在 TLS 阶段失败,浏览器报 ERR_SSL_VERSION_OR_CIPHER_MISMATCH。

坑三:超时时间过短,长连接空闲时被 Nginx 主动断开,表现为连接意外丢失。

常见问题

ws 和 wss 配置有什么区别?

wss 需要在 Nginx 侧配置 SSL 证书并监听 443 端口,ws 仅需监听 80 端口。

为什么握手返回 400 Bad Request?

通常是 Upgrade 或 Connection 头未正确转发,或者 Host 头不匹配后端预期。

后端服务需要配置 SSL 吗?

不需要,Nginx 终止 SSL 后通常以明文 ws 协议向内网后端转发,除非要求全链路加密。

参考来源

  • Nginx Official Documentation, "Nginx WebSocket Proxying", https://nginx.org/en/docs/http/websocket.html
  • Nginx Official Documentation, "HTTP ngx_http_proxy_module", https://nginx.org/en/docs/http/ngx_http_proxy_module.html