2009-09-08 13:04:22 +0000 2009-09-08 13:04:22 +0000
244
244

Как надежно держать туннель SSH открытым?

Я использую туннель SSH с работы, чтобы обойти различные идиотские брандмауэры (с моим боссом все в порядке :)). Проблема в том, что через некоторое время соединение по ssh обычно зависает, и туннель разрывается.

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

Бонусные баллы для того, кто может подсказать мне, как предотвратить зависание моего ssh-соединения, конечно!

Ответы (16)

296
296
296
2009-09-08 13:43:51 +0000

Похоже, тебе нужна автошш . Это отследит туннель ssh и перезапустит его по мере необходимости. Мы использовали его пару лет и, похоже, он хорошо работает.

autossh -M 20000 -f -N your_public_server -R 1234:localhost:22 -C

Более подробная информация о параметре -M здесь

40
40
40
2009-09-28 13:47:26 +0000

Все брандмауэры с контролем состояния забывают о соединении после того, как некоторое время не видели пакет для этого соединения (чтобы предотвратить переполнение таблиц состояния соединениями, где оба конца умерли, не закрыв соединение). Большинство реализаций TCP будут посылать пакеты keepalive после долгого времени, не видя их с другой стороны (2 часа - это обычное значение). Однако, если есть брандмауэр с контролем состояния, который забывает о соединении до того, как могут быть отправлены keepalive пакеты, то долгоживущее, но простаивающее соединение прервётся.

Если это так, то решение заключается в том, чтобы не допустить простое соединение. В OpenSSH есть опция под названием ServerAliveInterval , которая может быть использована для предотвращения того, чтобы соединение не простаивало слишком долго (в качестве бонуса, она будет определять, когда коллега умер раньше, даже если соединение простаивает).

24
24
24
2010-05-29 13:45:08 +0000

На Вашей собственной машине Mac или linux настройте, чтобы Ваш ssh сохранял работоспособность сервера каждые 3 минуты. Откройте терминал и используйте свой невидимый .ssh у себя дома:

cd ~/.ssh/

затем создайте 1 строчный конфигурационный файл:

echo "ServerAliveInterval 180" >> config

вы также должны добавить:

ServerAliveCountMax xxxx (high number)

по умолчанию 3, поэтому ServerAliveInterval 180 перестанет посылать через 9 минут (3 из 3-х минутного интервала, указанного ServerAliveInterval).

23
23
23
2009-09-22 14:58:15 +0000

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

while true
do
  ssh <ssh_options> [user@]hostname
  sleep 15
done

Обратите внимание, что для этого требуется ключевой файл, чтобы установить соединение автоматически, но так же обстоит дело и с autossh.

21
21
21
2016-07-28 06:10:14 +0000

Systemd идеально подходит для этого.

Создайте служебный файл /etc/systemd/system/sshtunnel.service, содержащий:

[Unit]
Description=SSH Tunnel
After=network.target

[Service]
Restart=always
RestartSec=20
User=sshtunnel
ExecStart=/bin/ssh -NT -o ServerAliveInterval=60 -L 5900:localhost:5900 user@otherserver

[Install]
WantedBy=multi-user.target

(Изменить команду ssh в соответствии с этим)

  • это будет работать как пользователь sshtunnel, поэтому убедитесь, что пользователь существует первым
  • выпустите systemctl enable sshtunnel, чтобы установить его на запуск во время загрузки
  • выпустите systemctl start sshtunnel, чтобы начать немедленно

Update Jan 2018 : некоторые дистрибутивы (e. g. Fedora 27) могут использовать политику SELinux для предотвращения использования SSH из systemd init, в этом случае нужно будет создать пользовательскую политику для предоставления необходимых исключений.

11
11
11
2013-11-28 01:04:34 +0000

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

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

То, что вы хотите, 1) чтобы соединение оставалось постоянно открытым при нормальных обстоятельствах, 2) чтобы сторона-источник обнаруживала сбой соединения и выходила при сбое, и 3) чтобы команда ssh переиздавалась каждый раз, когда она выходит (как вы это делаете, зависит от платформы, сценарий “в то время как верно”, предложенный Jawa, является одним из способов, в OS X я на самом деле установил элемент запуска).

9
9
9
2014-03-08 21:30:40 +0000

Всегда используйте опцию ServerAliveInterval SSH в случае, если проблемы туннеля генерируются просроченными сеансами NAT.

Всегда используйте метод переадресации в случае, если соединение полностью выйдет из строя, у вас есть, по крайней мере, три опции здесь:

  • программа autossh
  • bash скрипт (while true do ssh ...; sleep 5; done) не удаляет команду sleep, ssh может быстро выйти из строя, и вы перезапустите слишком много процессов
  • /etc/inittab, чтобы иметь доступ к ящику, отправленному и установленному в другой стране, за NAT, без переадресации порта на ящик, вы можете настроить его на создание туннеля ssh обратно к вам:

  • скрипт upstart на Ubuntu, где /etc/inittab недоступен:

или всегда используйте оба метода.

6
6
6
2013-05-30 13:32:05 +0000

Я решил эту проблему с помощью этого:

Редактируйте

~/.ssh/config

И добавьте

ServerAliveInterval 15
ServerAliveCountMax 4

Согласно man page для ssh_config:

ServerAliveCountMax
         Sets the number of server alive messages (see below) which may be
         sent without ssh(1) receiving any messages back from the server.
         If this threshold is reached while server alive messages are
         being sent, ssh will disconnect from the server, terminating the
         session. It is important to note that the use of server alive
         messages is very different from TCPKeepAlive (below). The server
         alive messages are sent through the encrypted channel and there‐
         fore will not be spoofable. The TCP keepalive option enabled by
         TCPKeepAlive is spoofable. The server alive mechanism is valu‐
         able when the client or server depend on knowing when a connec‐
         tion has become inactive.

         The default value is 3. If, for example, ServerAliveInterval
         (see below) is set to 15 and ServerAliveCountMax is left at the
         default, if the server becomes unresponsive, ssh will disconnect
         after approximately 45 seconds. This option applies to protocol
         version 2 only.

 ServerAliveInterval
         Sets a timeout interval in seconds after which if no data has
         been received from the server, ssh(1) will send a message through
         the encrypted channel to request a response from the server. The
         default is 0, indicating that these messages will not be sent to
         the server. This option applies to protocol version 2 only.
4
4
4
2015-06-06 23:41:10 +0000

ExitOnForwardFailure yes является хорошим дополнением к другим предложениям. Если он подключается, но не может установить переадресацию портов, то для вас это так же бесполезно, как если бы он вообще не подключался.

1
1
1
2012-03-13 12:11:18 +0000

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

Пример, начинается локально:

screen
ssh -R ......

Когда применяется удаленная переадресация, у вас есть оболочка на удаленном компьютере:

screen
Ctrl + a + d

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

1
1
1
2015-07-30 14:02:55 +0000

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

Подумал, что поделюсь своим решением на случай, если у кого-то еще возникнет такая же проблема:

#!/bin/bash
read -s -p "Password: " pass
while true
do
    sshpass -p "$pass" ssh user@address -p port
    sleep 1
done
1
1
1
2009-09-08 14:09:33 +0000

В то время как есть такие инструменты, как autossh, которые помогают перезапустить сеанс ssh… что я нахожу действительно полезным, так это запуск команды ‘screen’. Она позволяет вам восстановить сеансы ssh даже после того, как вы отключились. Особенно полезно, если ваше соединение не настолько надежно, как должно быть.

…не забудьте отметить, что это “правильный” ответ, если он поможет вам k! ;-).

1
1
1
2009-09-08 13:17:28 +0000

У меня была необходимость поддерживать туннель SSH на длительный срок. Мое решение было запущено с сервера Linux, и это всего лишь небольшая программа на C, которая перезапускает ssh, используя аутентификацию на основе ключей. 0x2 и 0x2 и я не уверен насчет зависания, но у меня туннели погибли из-за таймаутов.

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

0
0
0
2017-07-15 00:04:11 +0000

Так как autossh не удовлетворяет нашим потребностям (он существует с ошибкой, если не может подключиться к серверу с первой же попытки), мы написали чистое бэш-приложение: https://github.com/aktos-io/link-with-server

По умолчанию оно создает обратный туннель для sshd-порта NODE (22) на сервере. Если вам нужно выполнить какие-либо другие действия (например, переадресацию дополнительных портов, отправку почты при подключении и т.д…), вы можете разместить ваши скрипты on-connect и on-disconnect папки.

0
0
0
2009-09-28 10:27:21 +0000

У меня были похожие проблемы с моим предыдущим провайдером. Для меня это было то же самое с любым tcp-соединением, посещением сайтов или отправкой почты.

Решением было настроить VPN-соединение через UDP (я использовал OpenVPN). Это соединение было более терпимым к тому, что вызывало отключения. Тогда вы можете запустить любой сервис через это соединение.

С соединением все еще могут быть проблемы, но так как туннель будет более толерантным, любая сессия ssh будет ощущаться коротким удержанием, а не отключением.

Для этого вам понадобится VPN служба онлайн, которую вы можете установить на вашем собственном сервере.

0
0
0
2020-02-20 15:09:46 +0000

Вы можете очень просто использовать команду tmux на вашем удаленном сервере. Она позволяет вам открыть “сессию” на удаленной машине, где ваш удаленный код будет запущен.

Тогда вы можете выйти (или потерять соединение в вашем случае) на удаленной машине, не беспокоясь, учитывая, что ваш код безопасно запущен в вашей сессии tmux.

Наконец, когда вы переподключаетесь на удаленном сервере, вам нужно всего лишь tmux attach, чтобы вернуться к сеансу, который вы ранее открыли, и все.

Похожие вопросы

6
10
3
19
10