You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Varnish 6.0 LTS远程代理无法处理WebSocket问题求助

问题:Varnish代理WebSocket连接失败排查

环境背景

后端Node.js服务器分端口提供服务:

  • 3000端口:HTTP服务
  • 3001端口:WebSocket服务
  • 3002端口:安全WebSocket服务

前端部署独立的Hitch/Varnish缓存代理,监听80/443端口,默认将流量转发至后端3000端口的HTTP服务。目前用户访问https://foo.tld可正常通过Varnish获取内容,但页面JS发起的wss://foo.tld:3002安全WebSocket连接无法正常工作。

已配置的WebSocket透传规则

已在VCL中添加标准WebSocket透传配置:

if (req.http.upgrade ~ "(?i)websocket") {
    return (pipe);
}

以及:

sub vcl_pipe {
    #Declare pipe handler for websockets
    if (req.http.upgrade) {
        set bereq.http.upgrade = req.http.upgrade;
        set bereq.http.connection = req.http.connection;
    }
}

已尝试的无效方案

  • 在VCL中新增指向后端3001/3002端口的websockets后端,在pipe前设置set req.backend_hint = websockets;
  • 关闭HTTPS,尝试纯HTTP环境下的WebSocket连接
  • 修改varnish.service配置让Varnish监听其他端口,但Varnish无法启动
  • 在VCL中通过std.port(server.ip) == 3001判断端口并切换后端

目标是让Varnish通过Hitch在443端口接收wss://流量(或直接监听3002端口),透传至后端WebSocket服务器,无论两端连接是否加密。此前同机部署或Cloudflare CDN下的配置均可正常工作,但远程代理场景下始终无法解决。

环境简化后的问题(更新)

已简化测试环境:

  • 后端8080端口提供纯HTTP服务
  • 后端6081端口提供WS服务
  • 移除Hitch和TLS组件

直接访问后端IP时WebSocket可正常工作,但通过Varnish代理仍无法连接,问题明确出在Varnish配置上。

当前相关配置

hitch.conf(当前测试未使用)

frontend = "[*]:443"
frontend = "[*]:3001"

backend = "[127.0.0.1]:8443"    # 6086 is the default Varnish PROXY port.
workers = 4                     # number of CPU cores

daemon = on

# We strongly recommend you create a separate non-privileged hitch
# user and group
user = "redacted"
group = "redacted"

# Enable to let clients negotiate HTTP/2 with ALPN. (default off)
# alpn-protos = "h2, http/1.1"

# run Varnish as backend over PROXY; varnishd -a :80 -a localhost:6086,PROXY ..
write-proxy-v2 = on             # Write PROXY header

syslog = on
log-level = 1
# Add pem files to this directory
# pem-dir = "/etc/pki/tls/private"
pem-file = "/redacted/hitch-bundle.pem"

default.vcl(简化后用于测试,后端为远程服务器)

# Marker to tell the VCL compiler that this VCL has been adapted to the
# new 4.0 format.
vcl 4.0;

# Default backend definition. Set this to point to your content server.

backend default {
    .host = "remote.server.ip";
    .port = "8080";
}

backend websockets {
        .host = "remote.server.ip";
        .port = "6081";
}

sub vcl_recv {
    # Happens before we check if we have this in cache already.
    #
    # Typically you clean up the request here, removing cookies you don't need,
    # rewriting the request, etc.

    #Allow websockets to pass through the cache (summons pipe handler below)

    if (req.http.Upgrade ~ "(?i)websocket") {
        set req.backend_hint = websockets;
        return (pipe);
    } else {
        set req.backend_hint = default;
    }
}

sub vcl_pipe {
    if (req.http.upgrade) {
        set bereq.http.upgrade = req.http.upgrade;
        set bereq.http.connection = req.http.connection;
    }
    return (pipe);
}

Varnish的systemd执行参数

ExecStart=/usr/sbin/varnishd \
          -a http=:80 \
          -a proxy=localhost:8443,PROXY \
          -a ws=:6081 \
          -p feature=+http2 \
          -f /etc/varnish/default.vcl \
          -s malloc,256m \
          -p pipe_timeout=1800

在纯HTTP和非安全WebSocket的简化环境下,问题仍未解决,恳请协助排查。

内容的提问来源于stack exchange,提问作者8protons

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:20:42