Автоматическое восстановление ssh туннеля
Описание задачи:
Автоматически восстанавливать ssh соединение при разрыве
Решение:
Для работы скриптов проверки и автоматического восстановления работоспособности туннеля необходимо добиться работоспособности ssh-сессии по ключам. Это необходимо чтобы не хранить пароли в скриптах, из соображений безопасности.
Вся работа проводится из под пользователя, под которым будет устанавливаться сессия SSH для проброса портов.
- Убедиться что необходимые для обмена ключи есть (файлики id_rsa.pub и/или id_dsa.pub), выполнив команду
ls –al ~/.ssh/
-
Вывод команды:
-rw------- 1 user132 users 672 2008-12-13 01:13 id_dsa -rw-r--r-- 1 user132 users 604 2008-12-13 01:13 id_dsa.pub -rw------- 1 user132 users 1675 2008-12-12 20:55 id_rsa -rw-r--r-- 1 user132 users 396 2008-12-12 20:55 id_rsa.pub -rw-r--r-- 1 user132 users 13564 2008-12-10 18:59 known_hosts
Если их нет – то выполнить последовательно 2 команды, нажимаю просто Enter погда происходит запрос на пароль для ssh-ключей
ssh-keygen -t rsa
Вывод:
Generating public/private rsa key pair. Enter file in which to save the key (/home/user132/.ssh/id_rsa): Created directory '/home/user132/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user132/.ssh/id_rsa. Your public key has been saved in /home/user132/.ssh/id_rsa.pub. The key fingerprint is: fc:d7:c5:17:8a:0c:c7:63:72:61:7c:18:79:d0:86:73
ssh-keygen -t dsa
Вывод:
Generating public/private dsa key pair. Enter file in which to save the key (/home/user132/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user132/.ssh/id_dsa Your public key has been saved in /home/user132/.ssh/id_dsa.pub. The key fingerprint is: 32:97:fd:fb:30:0a:f2:87:76:a5:45:e5:d2:62:35:d6
-
Далее небходимо экспортировать публичные ключи на удаленную машину:
МЕТОД 1 (простой): На клиентской машине (с которой инициируется ssh-сессия) под пользователем из под которого предполагается выполнять проброс портов выполнить команду:
ssh-copy-id -i ~/.ssh/id_rsa.pub -l <remote_login> <remote_host>
где:
<remote_login> – имя удаленного пользователя, под которым выполняется проброс портов
<remote_host> – удаленный хост (c mysql)и ввести пароль
Если по какой-либо причине в системе не найдена команда ssh-copy-id придется выполнить операцию вручную (МЕТОД 2)МЕТОД 2 (сложный): залогиниться по ssh на удаленный сервер выполнив команду:
ssh -l <remote_login> <remote_host>
и введя пароль, скопировать содержимое файла
~/.ssh/id_rsa.pub
с клиента на сервер дописав его в конец файла ~/.ssh/authorized_keys .
Если файла authorized_keys нет, его необходимо создать с правами 600 в каталоге ~/.ssh и владельцем <remote_login>.
команды:cd ~/.ssh touch authorized_keys chmod 600 authorized_keys
вот примерное содержание файла ~/.ssh/authorized_keys :
ssh-rsa AAAA7Hz<одна_длинная_строка>ZGHhTQn72Jk0XslFLkTzYvwQ== user132@some_host
Далее закрыть текущую сессию ssh на <remote_host> и попробовать залогиниться без пароля просто набрав в командной сроке:
ssh -l <remote_host> <remote_host>
Если все прошло удачно приступим к правке скрипта по проверке статуса туннеля необходимо поправить слежующий скрипт:
#!/bin/sh
#-*-Perl-*-
exec perl -w -x $0 "$@"
#!perl
use IO::Socket;
my $sock = new IO::Socket::INET (
PeerAddr => 'localhost',
PeerPort => 'some_port1',
Proto => 'tcp',
);
my @children;
unless ($sock) {
print "No socket avialble!\nTrying to reopen socket...\n";
my $child = fork;
exec("ssh -t -t -t -l <remote_user> <remote_host> -L <some_port1>:server2:<some_port2>")
if $child == 0;
}
print "OK!\n";
close($sock);
exit 0;
где:
<remote_login>
– имя удаленного пользователя, под которым выполняется проброс портов
<remote_host>
– удаленный хост (c mysql)
<some_port1>,<some_port2>
- порт, пробрасываемый и локальный
далее добавить запись в crontab:
crontab -e */3 * * * * /путь/до/скрипта/check_ssh.pl
Раз в 3 минуты будет происходить проверка , и если нет проброса, то будет запускаться новый ssh
Все готово.
