2009/08/21

В помощь администратору: Autossh

Иногда необходимо иметь возможность удалённо управлять какими-то системами, которые находятся за firewall'ами, которые Вы не контролируете. В таких случаях помогают ssh-тунели с использованием перенаправления (forwarding) портов. Например, допустим имеется удалённая машина trick, которая находится за маршрутизатором в удалённой локальной сети, и вторая машина rose имеющая внешний ip-адрес. Для того, чтобы иметь возможность с rose заходить на trick (либо использовать какой-то сервис на trick), необходимо поднять туннель с использованием перенаправления удаленных портов (remote port forwarding):
ssh -f -N username@rose -R 3722:127.0.0.1:22
Получаем такую картину: на rose в списке открытых портов появляется порт 3722, который на самом деле перенаправляет все пакеты на 22-й порт trick-системы. После этого можно логиниться через ssh на trick из rose:
ssh username@127.0.0.0 -p 3722
А что делать, чтобы тунели были постоянно доступны? Ведь ssh-соединения бывают рвуться и тогда опять необходимо с trick-системы инициировать тунель. А если trick находится в 100 км от Вас? А если их таких у Вас 20? :) Вот тут-то и помогает замечательная вещь - autossh, утилитка занимающаяся тем, что поддерживает поднятые ssh-тунели в рабочем состоянии. Перед её запуском необходимо установить переменную AUTOSSH_PORT, указывающую номер порта, который будет использоваться для heartbeat-пакетов на предмет того - жив ли тунель.
Также, если тунели необходимо поднимать во время старта системы, советуют установить переменную AUTOSSH_GATETIME=0. Переменная AUTOSSH_DEBUG позволит получить из логов дополнительную информацию о ходе процесса.
export AUTOSSH_DEBUG=1
export AUTOSSH_GATETIME=0
export AUTOSSH_PORT=20037
autossh -f -N username@rose -R 3722:127.0.0.1:22
Без ключа -f апликация не отправляется в фон, поэтому данный режим полезен, чтобы разбираться с проблемами при установлении тунеля, если они возникают.
В приведенном выше примере кроме портов rose:3722 и trick:22 поднимается ещё 3 дополнительных (так как установлена переменная AUTOSSH_PORT) - trick:20037, rose:20037, trick:20038, связанных между собой в цепочку для прохождения heartbeat-пакета. Таким образом, что отправляя запрос на trick:20037, пакет приходит на rose:20037, который в свою очередь перенаправляет его дальше на trick:20038. Получается своеобразный "бумеранг", позволяющий следить за тунелем.

Links:
  1. Keeping your SSH connections alive with autossh

4 comments:

Angel 2S2 said...

Спасибо, очень пригодилось :)

Rett Pop said...
This comment has been removed by the author.
mitroko said...

А почему не попробовать связку
bash: if ! [ $(connected) ]; then ssh -R ...; fi;
И в крон?
Тот же автоssh только ручками.
Будет проверять, если канала нету - поднять каждую минуту.

Anonymous said...

tun_skonst(){
trap_func(){
service sshd stop
}
trap "trap_func" INT
if [[ $UID != 0 ]] && [[ -x `where\ sudo` ]]; then
SUDO_CMD="$(where sudo)"\
${SUDO_CMD} /etc/rc.d/sshd\ restart
fi

while true; do
ssh -i /home/yaa/.ssh/id_rsa\ anonymus@192.168.168.1-p 234 \ -R:9876:localhost:22 2>/dev/null ||\
{ echo connection seems refused\ && trap_func && exit 1; }
wait $!
done
}