Я нахожусь в ситуации, когда мне нужно предоставить прозрачный обратный прокси-сервер перед набором тысяч внутренних веб-серверов https, при этом список меняется (относительно) часто.
Я знаю, что могу сказать haproxy
чтобы выбрать серверную часть для подключения на основе строки SNI, которую клиент отправляет вместе с Client Hello (см., например, Может ли обратный прокси-сервер использовать SNI с проходом SSL?), но, похоже, мне нужно было бы перечислить все бэкенды и ссылаться на них индивидуально в конфигурации; то есть «если SNI такой-то, поговорите с бэкендом то-то и то-то».
Вместо этого я хотел бы просто взять строку SNI из Client Hello, найти ее в DNS, подключиться к IP, предоставляемому DNS (на TCP-порту 443), передать приветствие клиента на сервер, а затем продолжить ретрансляцию между клиентом и сервер.
Я не хочу проверять трафик и не хочу устанавливать новый сертификат на клиентах.
Может ли haproxy это сделать? Если нет, то какая еще программа может?
В итоге я использовал nginx
с модуль предварительного чтения потокового SSL.
Конфигурация предельно проста:
stream {
server {
resolver 127.0.0.1;
listen 443;
ssl_preread on;
proxy_pass $ssl_preread_server_name:443;
}
}
Нет http { }
блок даже понадобится, но nginx
segfault для меня, если я его пропустил, поэтому у меня пустой http { }
блок в конфиге. Загружается только модуль потока. В resolver
необходим для того, чтобы nginx мог искать имена бэкэндов в DNS; У меня есть кеширующий рекурсивный преобразователь на 127.0.0.1.
Я делаю так, чтобы все клиенты, которым необходимо подключиться к любому из бэкэндов, вместо этого подключались к моему nginx (используя комбинацию DNS с разделением горизонта и DNAT), а nginx подключался к фактическим бэкэндам от их имени. Это полностью прозрачно для клиентов.
Вы можете установить переменные в HAProxy с помощью http-request set-var на значение SNI и ссылаться на него с помощью var.
https://www.haproxy.com/documentation/hapee/1-9r1/onepage/#7.3.2-var