Назад | Перейти на главную страницу

HAProxy маршрут https SNI и http через один и тот же порт

У меня есть HTTPS-маршрутизация HAProxy без прерывания с использованием 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

Мне также нужно направить HTTP-трафик через тот же порт (5000).

Как я могу изменить свою конфигурацию, чтобы использовать как HTTP, так и HTTPS через SNI без прерывания через один и тот же порт?


редактировать


Я стал намного ближе. Маршрутизация HTTPS работает, но серверный acl HTTP по какой-то причине не соответствует домену.

Вот где я нахожусь:

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

Я отправляю ответ на свой вопрос, потому что мне удалось кое-что собрать воедино, и этот вопрос, похоже, не представляет интереса. Если он появляется в поиске Google, это должно кому-то помочь.

До сих пор мне кажется, что это работает:

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

Важные части для понимания - интерфейс проверяет, является ли запрос HTTP. Если это не так, он проверяет, является ли это запросом SNI. В противном случае он не принимает.

Другая часть, которая меня сбила с толку, - это сопоставление хоста на сервере http. Было важно использовать сопоставление домена с hdr_dom вместо hdr, чтобы порт, указанный вручную в строке, не нарушал acl.

Самая сложная часть заключается в том, что в режиме tcp во внешнем интерфейсе ведется бесполезный журнал для http. А поскольку серверная часть http не может регистрироваться, вы не получаете никакой информации о http.