Скрипт Bash для настройки временного туннеля SSH

На Cygwin я хочу, чтобы скрипт Bash:

  1. Создайте туннель SSH к удаленному серверу.
  2. Сделайте некоторую работу локально, которая использует туннель.
  3. Затем закройте туннель.

Отключение вызывает у меня недоумение.

В настоящее время у меня хромое решение. В одной оболочке я запускаю следующее для создания туннеля:

# Create the tunnel - this works! It runs forever, until the shell is quit.
ssh -nNT -L 50000:localhost:3306 [email protected]

Затем в другом окне оболочки я делаю свою работу:

# Do some MySQL stuff over local port 50000 (which goes to remote port 3306)

Наконец, когда я закончу, я закрываю первое окно оболочки, чтобы убить туннель.

Я хотел бы сделать все это в одном сценарии, как:

# Create tunnel
# Do work
# Kill tunnel

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

Ответ 1

Вы можете сделать это чисто с помощью ssh 'control socket'. Чтобы поговорить с уже запущенным SSH-процессом и получить его pid, убить его и т.д. Используйте "control socket" (-M для master и -S для сокета) следующим образом:

$ ssh -M -S my-ctrl-socket -fnNT -L 50000:localhost:3306 [email protected]
$ ssh -S my-ctrl-socket -O check [email protected]
Master running (pid=3517) 
$ ssh -S my-ctrl-socket -O exit [email protected]
Exit request sent. 

Обратите внимание, что my-ctrl-socket будет фактическим созданным файлом.

Я получил эту информацию от очень RTFM-ответ в списке рассылки OpenSSH.

Ответ 2

Вы можете сказать SSH о том, что вы сами используете опцию -f, но вы не получите PID с $!. Кроме того, вместо того, чтобы ваш script спать произвольное количество времени, прежде чем использовать туннель, вы можете использовать -o ExitOnForwardFailure = yes с -f, и SSH будет ожидать, что все удаленные удаленные порты будут успешно установлены, прежде чем помещать себя в фоновый режим, Вы можете выполнить grep вывод ps для получения PID. Например, вы можете использовать

...
ssh -Cfo ExitOnForwardFailure=yes -NL 9999:localhost:5900 $REMOTE_HOST
PID=$(pgrep -f 'NL 9999:')
[ "$PID" ] || exit 1
...

и будьте уверены, что вы получаете желаемый PID

Ответ 3

  • Вы можете сказать ssh перейти в фоновый рисунок с помощью & и не создавать оболочку с другой стороны (просто открыть туннель) с флагом командной строки (я вижу, вы уже сделали это с помощью -N).
  • Сохранить PID с помощью PID=$!
  • Сделайте свой материал
  • kill $PID

EDIT: Исправлено $? до $! и добавил и

Ответ 4

Я предпочитаю запускать новую оболочку для отдельных задач, и часто использую следующую комбинацию команд:

  $ sudo bash; exit

или иногда:

  $ : > sensitive-temporary-data.txt; bash; rm -f sensitive-temporary-data.txt; exit

Эти команды создают вложенную оболочку, где я могу выполнять всю свою работу; когда я закончил, я нажму CTRL-D, и родительская оболочка очистится и выйдет. Вы легко можете добавить bash; в свой ssh-туннель script непосредственно перед частью kill, чтобы при выходе из вложенной оболочки ваш туннель будет закрыт:

#!/bin/bash
ssh -nNT ... &
PID=$!
bash
kill $PID

Ответ 5

Вы можете запустить ssh с & a, чтобы положить его в фоновом режиме и захватить его id при выполнении. Затем вам нужно сделать kill этого идентификатора, когда закончите.

Ответ 6

Другой потенциальный вариант - если вы можете установить пакет ожидания, вы должны иметь возможность script все это. Вот несколько хороших примеров: http://en.wikipedia.org/wiki/Expect