Маршрутизация трафика SSH на основе домена с HAProxy

В настоящее время я строю свой собственный небольшой кластер дома и пытаюсь заставить SSH-маршрутизацию (балансировку нагрузки) работать с HAProxy. Я понял, как маршрутизировать HTTP-трафик, но я борюсь с SSH. Я не знаю достаточно о протоколе TCP, чтобы сразу узнать, что мне нужно искать, чтобы я мог определить, как запрашивать соединения для чего-то вроде хоста (не уверен, что это вообще где-то в соединении) или просто что-то, что идентифицирует какой сервер я хочу в SSH.

В документации снова и снова упоминается трафик SSH, поэтому я мог что-то пропустить. Я не хочу использовать разные порты и маршрутизировать туда и обратно, используя разные порты, потому что они могут быть нестандартными, поэтому заблокированы в общедоступных сетях или других вещах, которые ограничивают меня.

Моя текущая настройка выглядит так:

Запрос на мои домены (или IP) -> Маршрутизатор -> Переадресация NAT в зависимости от порта -> HAProxy, прослушивающий этот порт -> теперь должен идентифицировать трафик, выделенный для определенного сервера, и трафик прокси к нему.

Редактировать: Поскольку Cha0s прояснилось, это просто невозможно с SSH (или так).

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

3 ответа

Решение

Я считаю, что вы смешиваете условия.

Балансировка нагрузки обычно означает, что вы подключаетесь к одному хосту (example.com) и позволить распределителю нагрузки распределить все подключения к одному или нескольким хостам бэкэнда, обычно без контроля пользователя, к какому фактическому хосту вы подключаетесь. Это легко сделать для SSH различными способами.

Некоторые протоколы, такие как HTTP с Host заголовок, может дать балансировщику нагрузки больше информации, чтобы решить, на какие внутренние серверы должно быть направлено соединение (например, example.com направляется в a а также b, в то время как example.org направляется в c а также d).

У SSH нет такого поля, и, следовательно, это невозможно сделать с помощью балансировщика нагрузки и только одного IP-адреса. Это делает LB непригодным для этой задачи.

Как правило, это решается путем использования хоста в качестве хоста прокси / шлюза / перехода SSH и инструктирует ваших клиентов SSH использовать его как таковой. Если вы используете OpenSSH, поместите следующее в ваших клиентов ~/.ssh/config

Host  *.internal.lan
   ProxyCommand ssh -q -A  -x proxy.example.com -W %h:%p

Теперь, если вы подключитесь к именам, перечисленным в Host линия, ваш клиент SSH сначала подключится к proxy.example.com (который должен указывать на ваш общедоступный IP-адрес) и использовать его в качестве шлюза для пересылки на фактическую машину (используйте переадресацию порта NAT на порт 22 фактической прокси-машины, если это применимо). Обратите внимание, что proxy.example.com должен быть в состоянии решить *.internal.lan, Либо настройте DNS-сервер, либо используйте внутренний, предлагаемый вашим маршрутизатором, для достижения этой цели.

После этого из внешней сети вы подключаетесь к nas.internal.lan чтобы добраться до вашего NAS (или raspi.internal.lan и т. д.), а внутри вашей локальной сети вы просто используете nas или же raspi (поэтому соединение прямое, а не через шлюз).

Другой способ, учитывая тот факт, что вы используете NAT:

Создайте переадресацию портов в вашем маршрутизаторе NAT, например, как

Port 2210 -> internal host1, port 22
Port 2211 -> internal host2, port 22

и затем поместите следующее в ваших клиентов ~/.ssh/config:

Host host1.example.com  
   Port 2210

Host host2.example.com 
   Port 2211

и убедитесь, host1/2.example.com оба указывают на ваш внешний IP-адрес.

Тогда вы можете просто подключиться через SSH к host1.example.com и OpenSSH подключится к порту 2210, который пересылается на ваш внутренний хост1 шлюзом NAT.

Оба метода работают в вашем сценарии.

Так что, вообще говоря, да, только HTTP может определять имя хоста назначения в HAProxy... Однако, если TCP-клиент, подключающийся к HAProxy, отправляет адрес назначения (IP или FQDN), можно удалить эту информацию и использовать ее для целей маршрутизации.,

Я представляю своего дилера по покеру в Minecraft:

#starting from top of file, for completeness.
    global
       user haproxy
       group haproxy
#setting tcp mode here is required, won't work if in frontend area!
    defaults
       mode tcp
#setting up the HAProxy listener:
    frontend frontend-name
       bind :25565
       tcp-request inspect-delay 3s
#ACLs for 1.9 and newer clients:
        acl mojang req.payload(5,16) -m sub sub1.domain.tld1
        acl bungee req.payload(5,16) -m sub sub2.domain.tld1
        acl bungee req.payload(5,16) -m sub sub1.domain.tld2
        acl nukkit req.payload(5,16) -m sub sub3.domain.tld1
#ACLs for 1.8 and older clients, keeping pinger working:
        acl mojang req.payload(4,16) -m sub sub1.domain.tld1
        acl bungee req.payload(4,16) -m sub sub2.domain.tld1
        acl bungee req.payload(4,16) -m sub sub1.domain.tld2
        acl nukkit req.payload(4,16) -m sub sub3.domain.tld1
#Accept connections if matching an ACL above:
        tcp-request content accept if bungee
        tcp-request content accept if mojang
        tcp-request content accept if nukkit
#Route connection to appropriate backend server:
        use_backend minecraft.bungee if bungee
        use_backend minecraft.mojang if mojang
        use_backend minecraft.nukkit if nukkit
#backend servers - one bungee network, one notchian server, one nukkit server:
    backend minecraft.bungee
    #here we're directing the connection to bungee on 127.0.0.1:25566
    #We're also sending the proxy-protocol(v2) to bungee (check conf!)
       server bungee-server 127.0.0.1:25566 send-proxy-v2
    backend minecraft.mojang
    #Mojang servers can't use the proxy-procotol, so not sending it
       server mojang-server 127.0.0.2:25567
    backend mincraft.nukkit
    #nukkit will never work here, as Bedrock is based on UDP, not TCP!
       server sponge-server 127.0.0.3:25568
#EoF

Это базовая настройка и работает. Моя производственная установка значительно отличается, используя параметры, которые требует моя установка.

Теперь все сводится к - вы можете найти хост назначения в пакете, чтобы вы могли искать его с полезной нагрузкой HAProxy?

AFAIK, вы не можете сделать это на основе домена. HTTP может работать так, потому что он имеет специальный Host заголовок, который браузеры (в данном случае обратные прокси) могут понять и принимать решения на его основе.

На других протоколах TCP я не знаю ничего подобного. Определенно не по SSH.

Другие вопросы по тегам