Постоянное фоновое соединение ssh для создания обратного туннеля: как правильно?

41

Смежный вопрос: инициировать ssh-соединение с сервера на клиент

Ответ оттуда мне очень помог, эта команда делает то, что мне нужно:

ssh -R 2225:localhost:22 loginOfServerWithPublicIP@publicIP

Поэтому я написал сценарий для повторного подключения:

 #!/bin/bash

 while true; do
    echo "try to connect..."
    ssh -o ServerAliveInterval=240 -R 2225:localhost:22 user@host
    echo "restarting in 5 seconds.."
    sleep 5
 done

И добавил это в /etc/crontab. Но я обнаружил, что это работает, только если я выполняю его «вручную» из оболочки, но если он вызывается cron, ssh подключается и сразу же завершает работу. (так, скрипт выше соединяется все время)

От man ssh, я обнаружил, что для фоновых соединений я должен назвать его с -nключом, но это не помогло. Затем я просто искал похожие сценарии и обнаружил, что он работает, если я вызываю tail -f something, то есть какую-то «бесконечную» команду, поэтому я просто создал пустой файл, /tmp/dummy_fileи теперь моя команда ssh выглядит так:

ssh -o ServerAliveInterval=240 -R 2225:localhost:22 -n user@host tail -f /tmp/dummy_file

Это работает сейчас! Но это решение кажется немного уродливым, плюс я не очень понимаю реальные причины такого поведения. Случайно я попытался позвонить bashвместо tail -f( bashкажется, мне тоже «бесконечной» командой), но это не сработало.

Итак, может кто-нибудь объяснить, пожалуйста, это поведение, и как правильно создать фоновое соединение SSH для поддержания обратного туннеля SSH?

Дмитрий Франк
источник
как насчет использования &в конце вашей команды SSH:ssh -o ServerAliveInterval=240 -R 2225:localhost:22 user@host &
Networker
Но тогда мой whileцикл будет запускаться снова и снова, начиная новое фоновое sshсоединение каждые 5 секунд, верно? Это не то, что мне нужно.
Дмитрий Франк

Ответы:

37

Похоже, вы хотите -Nопцию ssh.

 -N      Do not execute a remote command.  This is useful for just forwarding ports
         (protocol version 2 only).
Патрик
источник
16

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

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

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

0xC0000022L
источник
Я на самом деле пытался autossh, я прочитал эту статью: goo.gl/jVuuSR , но он работал только для меня, если у меня есть подключение к Интернету сразу при загрузке системы; но если соединение установлено позже, оно не работает. Не уверен, может быть, я сделал что-то не так, но даже в этой статье автор имеет sleep 10в своем /etc/rc.local, чтобы быть уверенным, что интернет-соединение уже готово, когда вызывается autossh.
Дмитрий Франк
2
@DmitryFrank: немного несправедливо не упоминать об этом в своем вопросе, если вы пытались. Я все еще рекомендую это. С помощью upstartдругих замен init вы можете связать запуск туннеля с одним или несколькими подключенными сетевыми устройствами. Лучшее из решений (IMO) в Интернете - вот это: erik.torgesta.com/tag/ssh-upstart ... и нет sleep 10, в любом случае это не поможет.
0xC0000022L
Извините, что не упомянул, что, если честно, когда это не сработало для меня, я решил сделать это просто «вручную» и совершенно забыл об autossh. Спасибо ssh-upstart, я посмотрю на это!
Дмитрий Франк
опоздал на вечеринку, но я хотел добавить, что я не мог надежно получить autossh для поддержки обратного туннеля. если по какой-то причине обратный туннель не удался, autossh не заметит и не восстановит соединение. Мне нужно несколько туннелей от нескольких серверов, и это усложняет ситуацию
DeveloperChris
@DeveloperChris: Ну, я запускаю именно этот сценарий - и надежно. Если удаленный сервер буквально не выйдет из строя и вам не потребуется его снова включить, туннель всегда восстанавливается. Возможно, вам следует написать свой вопрос и сообщить подробности. Конечно, это можно сделать. Я использовал это, чтобы обойти проблемы VPN в течение нескольких месяцев.
0xC0000022L
9

Я поддержу предложение @ 0xC0000022L и буду его использовать autossh. Я использую его для поддержания SSH-соединения с моего ноутбука, так как я беру его с места на место, и он просто работает. Я использую это соединение для туннелирования задних портов 25 и 2143 для доступа к моим личным серверам SMTP и IMAP.

Вот скрипт, который я использую:

$ more /home/saml/bin/autossh_mail.sh
#!/bin/bash

autossh -M 0 -f -N -L 2025:localhost:25 -L 2143:localhost:143 sam@imap-o

Затем я сохраняю Hostзапись в моем $HOME/.ssh/configфайле для хоста imap-o.

$ more $HOME/.ssh/config
ServerAliveInterval 15
ForwardX11 yes
ForwardAgent yes
ForwardX11Trusted yes

GatewayPorts yes

Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
IdentityFile ~/.ssh/id_dsa

Host imap-o
    User sam
    ProxyCommand ssh sam@mygw.mydom.com nc `echo %h|sed 's/-o//'` %p

autossh_mail.shСкрипт запускается как часть моего рабочего стола , когда я войти в систему . Вы можете получить доступ к нему через gnome-session-properties.

       сс # 1

                                          сс # 2

SLM
источник