Ограничения мультиплексирования SSH

Вопрос или проблема

У меня есть следующая запись в файле .ssh/config

Host AAA
    User BBB
    HostName CCC
    ControlMaster auto
    ControlPath ~/.ssh/%r@%h:%p

Это позволяет мне мультиплексировать несколько ssh-сеансов через одно соединение без необходимости вводить пароль каждый раз, когда мне нужен новый сеанс (пока главное соединение остается открытым).

Однако я заметил, что, когда у меня относительно большое количество мультиплексированных соединений (~7), я не могу добавить больше сеансов к тому же мультиплексированному соединению и получаю следующую ошибку:

> ssh -X AAA

mux_client_request_session: session request failed: Session open refused by peer
Password: 

Мои вопросы:

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

Демон sshd на сервере ограничивает количество сеансов на одно сетевое соединение. Это контролируется опцией MaxSessions в /etc/ssh/sshd_config. Также опция MaxStartups может нуждаться в увеличении, если вы используете большое количество сеансов. (Смотрите man sshd_config для получения дополнительных деталей.) Возможность изменения лимита MaxSessions была введена в OpenSSH 5.1 и, похоже, ранее количество было жестко фиксировано на уровне 10. Если вы превышаете MaxSessions на сервере, вы увидите sshd[####]: error: no more sessions в логе сервера.

Я столкнулся с этой проблемой на сервере с более ранней версией OpenSSH. Я контролирую сервер и решил проблему, создав два CNAME в моей конфигурации named:

realhost.myexample.com.      IN  A       XXX.XXX.XXX.XXX
realhost2.myexample.com.     IN  CNAME   realhost.myexample.com.
realhost3.myexample.com.     IN  CNAME   realhost.myexample.com.

Затем, в моей локальной конфигурации ssh клиента:

ControlMaster auto
ControlPath ~/.ssh/%r_%p_%h

host realhost
hostname realhost.myexample.com

host realhost2
hostname realhost2.myexample.com

host realhost3
hostname realhost3.myexample.com

Оператор ControlPath нужен для того, чтобы названия сокетов управления не пересекались друг с другом.

Вот и все. Однако, чтобы упростить управление, я написал оболочку для ‘ssh’ на стороне клиента. Она понимает, что существуют ‘группы’ хостов (в данном случае realhost, realhost1, realhost2 составляют одну группу). Когда выполняется ‘sshwrapper realhost’, если нет открытых каналов, все три открываются, и сеанс начинается. В следующий раз при выполнении она подсчитывает открытые соединения на канал и открывает новый сеанс в канале с наименьшим числом соединений.

Используя один настоящий и два ‘фейковых’ хоста, я могу подключаться 30 раз перед получением ошибки. Вход в систему чрезвычайно быстро, за исключением того, что первый раз занимает секунду или две, так как все три контрольных канала открываются в это время.

Вам не нужно предварительно настраивать CNAME или все необходимые псевдонимы в .ssh/config.

  • Вы можете отредактировать ваш .ssh/config так, чтобы использовать другой управляющий сокет для каждого псевдонима командной строки, в то время как псевдонимы могут выбираться случайным образом во время выполнения в вашем скрипте, используя эту конфигурацию SSH:

    Host *
    ControlMaster auto
    ControlPath /path/to/sockets/%r@%h-%p.%n
    
    

    Здесь %n заменяется указанным именем хоста на командной строке во время выполнения, что позволяет использовать любые суффиксы имен хостов с настройкой Host, используя шаблон для их совпадения:

    Host foo-*
    HostName fooserver
    User foo
    
  • Затем вы можете вызвать ssh следующим образом:

    ssh foo-bob sleep 90 &
    ssh foo-bob sleep 90 &
    ssh foo-alice sleep 90 &
    ssh foo-alice sleep 90 &
    

    чтобы использовать ровно два управляющих сокета для этих 4 вызовов.

  • Или, когда вы используете что-то вроде этого в скрипте:

    do_ssh(){
      tnr=$(( $tnr + 1 ))
      ssh "foo-$scriptname-$(( $tnr / 5 ))" $@
    }
    tnr=0
    scriptname=backup1
    do_ssh sleep 1 &
    do_ssh sleep 2 &
    ...
    do_ssh sleep 5 &
    

    вы получаете новый сокет для каждого 5-го вызова, а следующие 4 повторно используют тот же ControlPath, так как номер увеличивается, но сокет использует только $tnr/5, что bash округляет до целых чисел, таким образом, вы никогда не используете его 6 раз, эффективно предотвращая 7-е повторное использование, из-за которого возникли проблемы.

Вам просто нужно убедиться, что вы не используете один и тот же псевдоним чаще (чем максимально допустимое количество сессий на управляющий сокет) в вашей программе. Как именно это делать, зависит от вас, и конфигурация SSH может быть статической, используя шаблоны и %n. В примерах функция do_ssh просто следит за тем, чтобы новый сокет использовался каждое 5-е выполнение, в то время как в других скриптах можно использовать другие значения scriptname, чтобы не столкнуться с той же проблемой при одновременном выполнении нескольких скриптов, но другие решения могут быть более эффективными.

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

.

Ответ или решение

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

Теория

SSH-мультиплексирование основывается на концепции контроля соединений, где первое подключение выступает в роли "мастера", а последующие сессии становятся "клиентами", подключенными через этот мастер. Это позволяет избежать повторной аутентификации и снизить задержки при установлении новых соединений. Управление такими сессиями происходит через параметры ControlMaster, ControlPath и ControlPersist.

Однако, мультиплексирование может столкнуться с ограничениями, являющимися результатом настроек серверной стороны, именно конфигурации SSH-демона (sshd). Важными настройками являются MaxSessions, который определяет максимальное количество одновременных сессий, разрешенных на одном соединении, и MaxStartups, который управляет количеством одновременных неаутентифицированных подключений.

Пример

В примере из исходного вопроса, пользователь столкнулся с ошибкой "Session open refused by peer" после достижения примерно семи мультиплексированных сессий. Это говорит о том, что было достигнуто максимальное количество разрешенных сессий на одно соединение. Причиной этого ограничения является настройка MaxSessions на сервере. Значение по умолчанию в OpenSSH – 10 сессий, однако в некоторых установках это значение могло быть изменено в меньшую сторону.

Для наглядности, предположим, что файл конфигурации sshd на сервере имеет следующую запись:

MaxSessions 10

Это ограничивает количество одновременно открытых сессий до 10, что объясняет возникновение ошибки при попытке установить еще одну сессию сверх этого ограничения.

Применение

Для решения этого вопроса возможны следующие подходы:

  1. Настройка сервера: Измените параметр MaxSessions в файле /etc/ssh/sshd_config на более высокое значение и перезапустите sshd. Это увеличит количество сессий, доступных для одного соединения. Тем не менее, необходимо учитывать возможные риски, связанные с увеличением нагрузки на сервер.

  2. Использование разных имен узлов (CNAME): Еще один подход – создание дополнительных записей CNAME в DNS, что позволяет имитировать дополнительные хосты. Это может быть полезно как временное решение, чтобы обойти лимиты сессий.

  3. Изменение конфигурации клиента: В клиентской части можно создать конфигурацию, которая использует различные ControlPath для разных подключений к тому же серверу, как предложено в примере с использованием %n в конфигурации SSH клиента. Это позволяет распределять сессии между несколькими соединениями.

Пример конфигурации клиента:

Host *
    ControlMaster auto
    ControlPath /path/to/sockets/%r@%h-%p.%n

Host AAA
    User BBB
    HostName CCC

Это позволяет управлять количеством коннектов более динамично, распределяя нагрузку. Также можно использовать скрипты-оболочки, чтобы систематизировать и автоматизировать этот процесс.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...