如何根据域名将流量重新路由到不同的服务器?

如何根据域名将流量重新路由到不同的服务器?

example.com我正在尝试配置 HAProxy 以用于通过端口 443 的 HTTPS 流量和 OpenVPN 连接。配置很简单(为了匿名,一级域名被替换为):

frontend www_ssl
    mode tcp
    bind *:443

    acl host_vpn hdr(host) -i vpn.example.com

    use_backend vpn_backend if host_vpn
    default_backend nginx_pool_ssl

backend nginx_pool_ssl
    balance first
    mode tcp
    server web1 192.168.1.2:443 send-proxy check
    server web2 192.168.1.3:443 send-proxy check

backend vpn_backend
    mode tcp
    server vpn1 192.168.1.4:443

建立 OpenVPN 连接时失败并显示以下消息:

警告:来自对等方的封装数据包长度错误(18516),该长度必须大于 0 且小于等于 1547 - 请确保两个对等方上的 --tun-mtu 或 --link-mtu 相等 - 此情况也可能表示对 TCP 链路存在主动攻击 - [正在尝试重新启动...]

实际情况是,HAProxy 不会将流量重定向到 192.168.1.4,而是转到 192.168.1.2,并尝试将其视为 HTTPS 请求。当我vpn.example.com在浏览器中打开时,情况也是如此:我只会看到 192.168.1.2 提供的网站。

如果我用以下配置替换上面的配置:

frontend www_ssl
    mode tcp
    bind *:443
    default_backend host_vpn

backend vpn_backend
    mode tcp
    server vpn1 192.168.1.4:443

然后 OpenVPN 连接正确建立,但浏览器无法显示任何内容,这意味着问题来自 HAProxy 配置。

这是怎么回事?原始配置有错误吗?

答案1

找到了。

明显的问题是 ACL 指令依赖于 HTTP 标头:鉴于 HAProxy 无法从 HTTPS 流量中提取标头并且 OpenVPN 没有这些标头,因此 ACL 不起作用,并且default_backend这里预计会使用。

我的第一个想法是使用req.ssl_snihdr(host)不是 。我认为这可以检测它是否是 HTTPS 流量:

acl host_non_vpn req.ssl_sni -m sub -i example.com

use_backend vpn_backend if !host_non_vpn
use_backend nginx_pool_ssl if host_non_vpn

虽然它可以很好地处理浏览器请求,但我遇到了一个问题,即通过 HTTPS 从 WebDAV 到 OpenVPN 服务器的部分流量svn被重定向到 OpenVPN 服务器。我不确定这里发生了什么,如果不跟踪网络流量,就很难找到问题所在,也不知道到底哪些请求失败了以及失败的原因。

我最终将 OpenVPN 移至端口 80。通过使用预定义HTTPACL,配置现在如下所示:

frontend www_http
    mode tcp
    bind *:80
    use_backend nginx_pool_http if HTTP
    use_backend vpn_backend if !HTTP

相关内容