Сервера MTProto → Сайт и MTProto прокси на одном порту 443

Сайт и MTProto прокси на одном порту 443

Порт 443 на сервере часто занят сайтом, а прокси на другом порту живёт хуже. Решение — разделить входящие соединения по SNI: имя из TLS-запроса решает, куда идёт соединение — на веб-сервер или в прокси. У серверов в таблице выше 443 отдан прокси целиком; ниже — как совместить.

Подключить srv1Подключить srv2Подключить srv3Все сервера

Схема не для новичков, но и не магия: один блок конфигурации.

Принцип

TLS ClientHello содержит имя хоста открытым текстом. Мультиплексор на 443 читает его, не расшифровывая: если это ваш сайт — передаёт соединение веб-серверу, если домен-легенда прокси — в MTProto-сервер. Оба слушают локальные порты, снаружи виден один 443.

Инструменты: stream-модуль nginx с ssl_preread, sslh, или сама реализация прокси, если умеет проксировать чужие имена на бэкенд.

Вариант с nginx stream

В блоке stream включается ssl_preread, карта имён на бэкенды: ваш домен → 127.0.0.1:8443 (где http-сервер), домен-легенда → 127.0.0.1:2443 (прокси), всё остальное → сайт по умолчанию. Веб-сервер переезжает с 443 на локальный порт, прокси слушает свой локальный.

Важно: домен-легенда прокси должен совпадать с хвостом секрета, иначе клиенты придут не туда.

Вариант «прокси впереди»

Современные реализации MTProto умеют быть мультиплексором сами: правильная подпись — обслуживают, чужое имя — проксируют на указанный бэкенд. Тогда прокси слушает 443, а сайт живёт на локальном порту. Проще в настройке, но сайт получает соединения через прокси.

Для небольшого сайта это нормально; для нагруженного лучше nginx впереди.

Подводные камни

PROXY protocol: без него бэкенд видит все соединения от 127.0.0.1 — включите, если нужны реальные IP в логах сайта. Сертификат: домен-легенда прокси не должен быть вашим сайтом — легенда должна вести на чужой ресурс. HTTP/3 на UDP 443 разделению не мешает, прокси его не использует.

Проверка: сайт открывается по своему имени, Telegram подключается через прокси, а запрос с именем легенды показывает настоящий чужой сайт.

Минимальный пример

В stream-блоке nginx: map $ssl_preread_server_name $upstream с двумя строками — имя вашего сайта ведёт на локальный порт веб-сервера, домен-легенда прокси ведёт на локальный порт MTProto, default — на сайт; server слушает 443 с ssl_preread on и делает proxy_pass $upstream. Веб-сервер переводится на 127.0.0.1:8443 с включённым proxy_protocol, если нужны реальные адреса в логах.

Прокси запускается на 127.0.0.1:2443 в обычном режиме. После перезагрузки nginx проверьте три вещи: сайт открывается по своему имени, Telegram подключается через прокси, а запрос с именем легенды показывает настоящий чужой сайт. Порядок именно такой — если сломался сайт, вы узнаете об этом первым.

Вопросы и ответы

Можно ли использовать Caddy вместо nginx?

Да, через плагин layer4 с разбором SNI.

Замедлит ли мультиплексор прокси?

Нет, чтение SNI — микросекунды на соединение.

Нужен ли отдельный IP?

Нет, в этом и смысл: один IP, один порт, два сервиса.

Читайте также

← Сервера MTProto