В удаленной лабораторной системе у меня есть сценарий оболочки, который запускает обратный туннель SSH к моей главной перемычке, который запускается с заданием cron каждые 5 минут. Если SSH-туннель работает, ничего не происходит, если он не работает, он инициирует его.

#!/bin/bash
createTunnel() {
/usr/bin/ssh -N -R :2222:localhost:22 username@jumpbox.example.com
if [[ $? -eq 0 ]]; then
 echo Tunnel to jumpbox created successfully
else
 echo An error occurred creating a tunnel to jumpbox. RC was $?
fi
}
/bin/pidof ssh
if [[ $? -ne 0 ]]; then
  echo Creating new tunnel connection
  createTunnel
fi

Это было чрезвычайно надежно, чтобы гарантировать мой доступ к удаленной машине, если она будет перезагружена или когда мой IP-адрес Jumpbox изменится. Однако недавно я добавил второй SSH-туннель к этой системе, и возникла ситуация, когда один из двух туннелей вышел из строя и не был восстановлен. Похоже, что поскольку был один туннель, вывод pidof по-прежнему возвращался с PID, поэтому скрипт никогда не запускал "createTunnel". Поскольку у меня есть два SSH-туннеля, вывод pidof показывает оба PID:

$ /bin/pidof ssh
28281 28247

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

1 ответ1

2

Мои мысли:

  1. Пид файлы. Я думаю, что это общий подход.
  2. XY проблема, используйте autossh .

(Некоторые другие ответы могут развить эти идеи.)

  1. Есть два сценария, верно? (не совсем соответствует DRY). Дайте им разные имена. Ваш скрипт ожидает выхода из ssh . Дополнительный экземпляр, вместо проверки pid (s) ssh , должен проверять pid (s) со своим собственным именем. Точно один pid и два pid означают, что предыдущий скрипт еще не запущен:

    [ $(pidof -x scriptname | wc -w) -eq 2 ] && createTunnel
    

    Почему два? Потому что $() запускает подоболочку, которая тоже считается. Довольно грязно, да ладно.

  2. Думаю, что-то нестандартное. Создайте две символические ссылки с уникальными именами, например:

    ln -s /usr/bin/ssh ssh-foo
    ln -s /usr/bin/ssh ssh-bar
    

    Пусть первый скрипт запускает ssh-foo , а второй запускает ssh-bar . Их вызовы pidof должны быть направлены на ssh-foo или ssh-bar соответственно. Таким образом, они не будут смешиваться. В качестве бонуса, дополнительный ssh (возможно, будет запущен по совершенно другой причине в будущем) не повлияет на них.

И наконец:

  1. Вам не нужно ничего проверять.

    /usr/bin/ssh -o ExitOnForwardFailure=yes -N -R :2222:localhost:22 username@jumpbox.example.com
    

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .