如何使用 haproxy 在同一端口上分离 vpn 流量和 https 流量?

如何使用 haproxy 在同一端口上分离 vpn 流量和 https 流量?

我有一个目标:在端口 443 上运行 softhether vpn 和 web 应用程序。我希望所有流量都到达 haproxy,它将 vpn 发送到一个容器,其余的发送到另一个容器 (traefik),最后根据 webapp 重新分配到相应的容器。显然这是可能的,但我无法让它工作。

设置:XenServer 中的 2 台虚拟机(基于 Debian 并运行 docker)

VM1 地址 10.0.0.244

VM2 地址 10.0.0.245

VM1:

  • 运行 haproxy 容器,使用网络模式“host”监听 443 端口(即 10.0.0.245:443)

  • 运行 softhether vpn 服务器容器,使用网络模式“主机”监听端口 992(即 10.0.0.245:992)

VM2:

  • 运行 traefik 反向代理容器,docker 内部网络,将主机的 443 映射到本地 443
  • 运行多个 Web 应用程序/容器,同样在 docker 内部网络上,没有主机映射端口,仅暴露给内部 docker 网络。Web 应用程序可通过 traefik 反向代理通过 webappX.domain.com 等名称访问。

值得一提的是,如果 DNS 将 webappX.domain.com 指向 10.0.0.245,那么 traefic 就会正常工作,并且所有 webapp 都可以通过浏览器访问。此外,当我尝试从我的 mac 连接到 softhether vpn 到端口 992 时,连接已建立(当我尝试使用 softether 监听端口 443 并关闭 haproxy 时,它也能正常工作)。vpn.domain.com 的 DNS 记录指向 10.0.0.244。

添加 haproxy 后,我将 webappX.domain.com 的 DNS 记录重新映射到 10.0.0.244。

这是我的 haproxy 配置(我怀疑问题出在这里):

defaults
  timeout client 30s
  timeout server 30s
  timeout connect 5s

frontend ft_https
  bind :443
  mode tcp
  tcp-request inspect-delay 5s
  tcp-request content accept if { req.ssl_hello_type 1 }
  default_backend bk_https

backend bk_https
  mode tcp
  acl vpn_app req_ssl_sni -i vpn.domain.com

  use-server server-se if vpn_app
  use-server server-traefik if !vpn_app

  option ssl-hello-chk
  server server-se localhost:992 check
  server server-traefik 10.0.0.245:443 check

一个关键要求是 traefik 必须接收完整的 URL(例如https://webappX.domain.com) 以便它能够正确地进行反向代理。此外,SSL 终止不应该发生在 haproxy 上。

为了实现这个功能,您是否有什么建议/建议需要改变或尝试?

谢谢你,布兰登。

答案1

好吧,我取得了部分成功,因为它开始适用于 webapps,但 vpn 却不行。经过反复试验和大量谷歌搜索后,我找到了这篇文章: https://discourse.haproxy.org/t/haproxy-not-switching-between-backends/1903/8

这表明,如果我使用通配符证书(我确实这样做了),那么 SNI 将无法按预期工作。这就是为什么 webapps 可以工作(因为每个请求实际上都会转到 1 个服务器地址,即 traefik,它会进一步分割流量),但我永远无法访问 vpn 服务器。

因此,解决方案是使用每个主机的自定义证书(我不想这样做)或不进行这样的设置。除非有其他方法,例如 ha-proxy 替代方案...有什么建议吗?

干杯,布兰登。

相关内容