У меня есть 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.