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

Проксирование TCP по имени хоста

У меня есть несколько TCP-портов игровых серверов на моем единственном хосте. Цель состоит в том, чтобы пользователи могли подключаться к server1.domain.net и направлять их на основе этого поддомена. Мой первый инстинкт написал следующее, но затем я понял, что трафик TCP не будет иметь заголовок для чтения. Использование HAProxy 1.5.8. Я пробовал сделать то же самое, используя несколько бэкэндов, use_backend и полные строки ACL, но получил тот же результат (по понятным причинам).

listen game-listener
  bind x.x.x.x:22222
  mode  tcp
  use-server  server1 if { hdr(host) -i server1.domain.net }
  use-server  server2 if { hdr(host) -i server2.domain.net }
  server server1 localhost:22201 check
  server server2 localhost:22202 check

Есть ли такая проверка, как hdr (host), которую я могу использовать для TCP-соединений? Или я все делаю правильно, и игра просто не идет хорошо?

Спасибо!

В качестве альтернативы проксированию (где это зависит от протокола приложения, если это возможно на основе имен хостов) вы можете проверить, работает ли клиентское программное обеспечение SRV знайте, и в этом случае вы сможете настроить это только в DNS.

An SRV запись имеет следующий формат:

_Service._Proto.Name TTL Class SRV Priority Weight Port Target


В вашем конкретном примере, где вы упомянули несколько экземпляров Minecraft, это должно быть возможно сделать на основе SRV записи и записи могут выглядеть примерно так:

_minecraft._tcp.foo.example.com. 86400 IN SRV 0 5 25565 server1.example.com.
_minecraft._tcp.bar.example.com. 86400 IN SRV 0 5 25566 server1.example.com.

Диспетчеризация подключений к различным бэкэндам в зависимости от имени хоста, к которому подключился клиент, невозможно на уровне TCP.

Вам нужно будет либо использовать отдельные IP-адреса для каждого имени хоста, либо реализовать проксирование на прикладном уровне с помощью кода конкретного протокола для определения имени хоста.

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

  • HTTP легко поддерживать. Все клиенты HTTP / 1.1 и большинство клиентов HTTP / 1.0 отправят заголовок хоста перед тем, как ожидать ответа от сервера. Клиенты без заголовка хоста, скорее всего, давно исчезли, так как в наши дни многие сайты без него не работают.
  • HTTPS может поддерживаться для всех клиентов с поддержкой SNI. SNI был стандартизирован гораздо позже, чем HTTP / 1.1, но все еще есть несколько клиентов без поддержки SNI.
  • DNS можно поддерживать, но это немного сложно. В большинстве случаев вы просто управляете своим авторитетным DNS-сервером непосредственно на общедоступном IP-адресе вместо проксирования.
  • SMTP можно поддерживать, но это тоже сложно. Прокси-сервер для SMTP, скорее всего, будет больше похож на ретранслятор SMTP, чем на прокси.
  • SSH невозможно поддерживать. В протоколе просто не существует концепции имен хостов. Клиент может использовать DNS для разрешения IP-адреса сервера и может связывать сохраненные ключи хоста с их именами хостов, но это полностью детали реализации на стороне клиента. Это не будет видно прокси-серверу, поэтому его нельзя использовать для отправки соединений. Более того, никакая полезная информация не отправляется в открытом виде, и даже те немногие фрагменты информации, которые отправляются в виде открытого текста в начале протокола SSH, аутентифицируются позже в протоколе, поэтому, если вы ошиблись в какой-либо части этого сообщения, связь прервется. Что делает это еще более невозможным для обработки, так это тот факт, что клиент не отправляет ни одного байта полезной нагрузки, пока сервер не отправит баннер обратно клиенту. Таким образом, у прокси не будет буквально никакой информации для работы.

Мне неизвестен какой-либо другой протокол с именем хоста, который можно было бы использовать для таких целей. Поэтому я предполагаю, что большинство протоколов, не указанных в приведенном выше списке, невозможно проксировать по имени хоста.