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_sni
而hdr(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。通过使用预定义HTTP
ACL,配置现在如下所示:
frontend www_http
mode tcp
bind *:80
use_backend nginx_pool_http if HTTP
use_backend vpn_backend if !HTTP