如何配置Listener/Sender Client通过NGINX反向代理连接Azure Relay混合连接?
Azure Hybrid Connection Relay 配置NGINX反向代理的问题
我需要在Azure Hybrid Connection Relay Service与Listener Client之间配置NGINX反向代理。Listener通过初始WebSocket控制通道连接服务后,会通过该通道获取动态的accept WebSocket地址,用于和Sender Client通信。尝试让Sender Client的消息通过反向代理发送至Azure Relay Service时,Azure服务会在反向代理发送应用数据后立即发送TCP RST包。
提供的代码与配置
Sender Client 代码
require("dotenv").config(); process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; // 禁用证书验证 const WebSocket = require("hyco-ws"); const readline = require("readline").createInterface({ input: process.stdin, output: process.stdout, }); const ns = process.env.RelayNamespace; const path = process.env.HybridConnectionName; const keyrule = process.env.SASKeyName; const key = process.env.SASKeyValue; const proxiedAddress = WebSocket.createRelaySendUri("localhost", path); console.log("Proxied URL: "); console.log(proxiedAddress); const uri = WebSocket.createRelaySendUri(ns, path); const token = WebSocket.createRelayToken(uri, keyrule, key); console.log("Actual URL: "); console.log(uri); console.log("Token: "); console.log(token); WebSocket.relayedConnect(proxiedAddress, token, function (wss) { readline.on("line", (input) => { wss.send(input, null); }); console.log("Started client interval."); wss.on("close", function () { console.log("stopping client interval"); process.exit(); }); });
NGINX 配置(原始)
http { upstream relayservice { server revproxy.servicebus.windows.net:443; } server { listen 443 ssl; server_name localhost; ssl_certificate cert/localhost.crt; ssl_certificate_key cert/localhost.key; location ~ ^/(\$hc.*)$ { proxy_read_timeout 300s; proxy_connect_timeout 75s; proxy_pass https://relayservice/$1$is_args$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_pass_request_headers on; } } } events {}
问题分析与修正方案
核心问题点
- Host头验证失败:Azure Relay要求请求的
Host头必须匹配Relay命名空间域名(revproxy.servicebus.windows.net),原始配置中proxy_set_header Host $host传递的是localhost,导致服务拒绝连接并返回RST包。 - 正则表达式匹配错误:
location ~ ^/(\$hc.*)$中的$是正则结束符,未正确转义会导致无法匹配路径中的$hc前缀。 - 超时设置不足:WebSocket是长连接,较短的
proxy_read_timeout会导致连接被提前断开。
修正后的NGINX配置
http { upstream relayservice { server revproxy.servicebus.windows.net:443; keepalive 32; # 启用长连接池,适配WebSocket特性 } server { listen 443 ssl; server_name localhost; ssl_certificate cert/localhost.crt; ssl_certificate_key cert/localhost.key; # 正确匹配$hc开头的路径,转义$符号 location ~ ^/(\$hc.*)$ { proxy_read_timeout 86400s; # 延长超时至1天,适配长连接 proxy_connect_timeout 75s; proxy_pass https://relayservice/$1$is_args$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 传递Azure Relay要求的正确Host头 proxy_set_header Host revproxy.servicebus.windows.net; proxy_pass_request_headers on; # 可选:传递源地址信息 proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } } } events {}
Sender Client代码优化
- 移除
NODE_TLS_REJECT_UNAUTHORIZED = "0",将自签名证书导入系统信任链,避免安全风险。 - 若NGINX使用非
localhost域名,需同步修改WebSocket.createRelaySendUri的第一个参数为代理域名。
Listener端代理配置建议
若要为Listener配置代理,需确保控制通道和动态accept连接都通过NGINX转发:
- 为Listener的控制连接配置相同的NGINX路径规则。
- 通过代码拦截Listener从Azure获取的
accept地址,将域名替换为代理地址;或使用NGINX的sub_filter模块修改WebSocket响应中的地址内容。
内容的提问来源于stack exchange,提问作者Anik Ghosh
相关产品推荐
相关产品推荐

