Скрипт Bash для настройки временного туннеля SSH - PullRequest
120 голосов
/ 11 февраля 2010

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

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

«Отключение» меня озадачило.

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

# Create the tunnel - this works! It runs forever, until shell is quit.
ssh -nNT -L 50000:localhost:3306 jm@sampledomain.com

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

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

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

Я бы хотел сделать все это одним скриптом, например: # Создать туннель # Работай # Убить туннель

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

Ответы [ 6 ]

294 голосов
/ 04 марта 2013

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

$ ssh -M -S my-ctrl-socket -fnNT -L 50000:localhost:3306 jm@sampledomain.com
$ ssh -S my-ctrl-socket -O check jm@sampledomain.com
Master running (pid=3517) 
$ ssh -S my-ctrl-socket -O exit jm@sampledomain.com
Exit request sent. 

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

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

19 голосов
/ 13 октября 2012

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

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

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

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

РЕДАКТИРОВАТЬ: Fixed $? в $! и добавил &

4 голосов
/ 11 февраля 2010

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

  $ sudo bash; exit

или иногда:

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

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

#!/bin/bash
ssh -nNT ... &
PID=$!
bash
kill $PID
2 голосов
/ 11 февраля 2010

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

2 голосов
/ 11 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...