Мне нужно обслуживать несколько приложений через https, используя один внешний IP-адрес.
Сертификаты ssl не должны управляться через обратный прокси-сервер. Они устанавливаются на серверах приложений.
Можно ли настроить обратный прокси-сервер для использования SNI и передачи ssl для завершения в конечной точке?
Возможно ли это с помощью чего-то вроде Nginx или Apache? Как выглядит конфигурация?
Это возможно с Haproxy. Вы можете настроить TCP-прокси, извлечь SNI и выполнить маршрутизацию на основе SNI. Вот пример:
backend be.app1
mode tcp
no option checkcache
no option httpclose
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
tcp-request content reject
use-server server1 if { req.ssl_sni -m beg app1. }
server server1 server1:8443 check id 1 weight 0
Важно отложить запрос до тех пор, пока вы не получите SSL-приветствие, иначе haproxy попытается установить соединение до получения заголовка SNI.
Я использую серверы с весом 0, потому что в моей текущей конфигурации у меня работает только один сервер для каждого SNI, и я не хочу, чтобы они получали случайные запросы. Вы, вероятно, сможете найти лучшие способы поиграть с этим.
Надеюсь, это поможет.
Вы можете использовать sniproxy: https://github.com/dlundquist/sniproxy
Пример конфигурации:
listener 0.0.0.0:443 {
protocol tls
table TableHTTPS
fallback 127.0.0.1:8443
}
listener 0.0.0.0:80 {
protocol http
table TableHTTP
fallback 127.0.0.1:8080
}
table TableHTTPS {
domain1.com backend1:443
domain2.org backend2:443
}
table TableHTTP {
domain1.com backend1:80
domain2.org backend2:80
}
Это, безусловно, возможно даже сейчас, в 2019 году, с грядущим TLS 1.3! Многие веб-серверы или специализированные обратные прокси-серверы предоставляют эту функцию из коробки:
Это пример конфигурации для Nginx, который является очень популярным выбором для установок, требующих обратного прокси:
stream {
map $ssl_preread_server_name $selected_upstream {
example.org upstream_1;
example.net upstream_2;
example.com upstream_3;
default upstream_4;
}
upstream upstream_1 { server 10.0.0.1:443; }
upstream upstream_2 { server 10.0.0.2:443; }
upstream upstream_3 { server 10.0.0.3:443; }
upstream upstream_4 { server 10.0.0.4:443; }
server {
listen 10.0.0.5:443;
proxy_pass $selected_upstream;
ssl_preread on;
}
}
Соответствующие модули Nginx: stream_core
и stream_ssl_preread
. Руководства:
Имейте в виду, что если целевые серверы используют один и тот же сертификат (что не очень маловероятно при использовании сертификатов с подстановочными знаками), то HTTP / 2 использовать нельзя. Он направит ваш трафик не на тот сервер.
Образец:
Если a.example.com и b.example.com обрабатываются одним и тем же обратным прокси-сервером, то будет открыто одно соединение и передано на сервер, который вызывается в первый раз. Поэтому, если вы вызываете a.example.com, будущие запросы к b.example.com могут попасть не на тот веб-сервер.
Для справки см.