HAProxy 通过同一端口路由 https SNI 和 http

use*_*862 7 haproxy

我有一个 HAProxy 路由 HTTPS,无需使用 SNI 终止。

配置类似于以下内容:

frontend ft_ssl_vip
  bind 0.0.0.0:5000
  mode tcp
  option tcplog

  tcp-request inspect-delay 5s
  tcp-request content accept if { req.ssl_hello_type 1 }

  default_backend bk_ssl_default

# Using SNI to take routing decision
backend bk_ssl_default
  mode tcp

  acl application_1 req.ssl_sni -i foo.example.com
  acl application_2 req.ssl_sni -i bar.example.com

  use-server server1 if application_1
  use-server server2 if application_2
  use-server server3 if !application_1 !application_2

  option ssl-hello-chk
  server server1 127.0.0.1:777
  server server2 127.0.0.1:778
  server server3 127.0.0.1:779
Run Code Online (Sandbox Code Playgroud)

我还需要通过同一端口 (5000) 路由 HTTP 流量。

如何修改我的配置以通过 SNI 适应 HTTP 和 HTTPS,而不会在同一端口上终止?


编辑


我离得更近了。HTTPS 路由似乎正在工作,但由于某种原因,HTTP 后端 acl 与域不匹配。

这是我所在的位置:

frontend app
  bind 0.0.0.0:5000
  mode tcp
  option tcplog

  tcp-request inspect-delay 5s
  tcp-request content accept if HTTP
  tcp-request content accept if { req.ssl_hello_type 1 }


  use_backend testing_http if HTTP

  default_backend testing_https



backend testing_https
  mode tcp

  acl app_2 req.ssl_sni -i foo.bar.com

  use-server server2 if app_2
  use-server default if !app_2

  server server2 127.0.0.1:777
  server default 127.0.0.1:443



backend testing_http
  mode http

  acl app_2 hdr(host) -i foo.bar.com

  use-server server2 if app_2
  use-server default if !app_2

  server server2 127.0.0.1:777
  server default 127.0.0.1:80
Run Code Online (Sandbox Code Playgroud)

use*_*862 10

我发布了我自己问题的答案,因为我已经能够将一些东西拼凑起来,而这个问题似乎没有任何兴趣。如果它出现在谷歌搜索中,这应该对某人有所帮助。

到目前为止,以下内容似乎对我有用:

frontend app
  bind 0.0.0.0:5000
  mode tcp
  option tcplog

  tcp-request inspect-delay 5s
  tcp-request content accept if HTTP
  tcp-request content accept if { req.ssl_hello_type 1 }


  use_backend testing_http if HTTP

  default_backend testing_https



backend testing_https
  mode tcp

  acl app_2 req.ssl_sni -i foo.bar.com

  use-server server2 if app_2
  use-server default if !app_2

  server server2 127.0.0.1:777
  server default serverfault.com:443



backend testing_http
  mode http

  acl app_2 hdr_dom(host) -i foo.bar.com

  use-server server2 if app_2
  use-server default if !app_2

  server server2 127.0.0.1:777
  server default www.example.com:80
Run Code Online (Sandbox Code Playgroud)

需要理解的重要部分——前端检查请求是否为 HTTP。如果不是,则检查它是否是 SNI 请求。否则,它不接受。

另一部分让我失望的是 http 后端的主机匹配。使用 hdr_dom 而不是 hdr 的域匹配很重要,这样字符串中手动指定的端口就不会破坏 acl。

最难的部分是前端的tcp模式对http有无用的日志记录。并且由于 http 后端无法登录,因此您不会获得任何 http 信息。