Подключение по ssh без белого IP и VPN

Материал из Mindsellers
Перейти к: навигация, поиск

Linux

Иногда возникает потребность подключаться к неким машинам по ssh, причем заранее неизвестно, где и как эта самая машина будет работать. Допустим, мы преднастроили кучу линуксовых системников и разослали в филиалы большой организации с крайне разнородными подключениями к интернет - от 3G до xDSL и спутника. Очевидным кажется решение использовать vpn, но это не всегда оправданно и возможно, особенно если мы системники и разослали для того, чтобы они выступали в качестве vpn-гейтов для филиалов, а доступ-то к ним нужен и в случае отвала vpn.

На помощь нам приходит механизм туннелирования, а конкретно проброс удаленного порта на локальный ПК. Достаточно написать небольшой скрипт - и наша задача будет реализована. Для начала необходимо настроить авторизацию по ключам на главном сервере, к которому и будут подключаться все машины. Для этого, если вы еще не меняли /etc/ssh/sshd_config кардинальным образом, достаточно просто создать пользователя для подключения на сервере и в его домашний каталог положить файл .ssh/authorized_keys, куда и нужно будет добавить ключи от всех машин. В принципе, если мы машины клонируем, то и ключ у нас будет одинаковый, что вообще-то полный кошмар в плане информационной безопасности, но удобно и быстро в плане админской лени.

Далее, в файл /etc/ssh/sshd_config нужно добавить строчку

GatewayPorts yes

На этом настройка серверной части завершена. Переходим к скрипту



#!/bin/bash
server="188.188.188.188" # белый адрес сервера
remote="10.10.10.10" # адрес сервера, на который пробрасываем порты. 
# может совпадать или не совпадать с белым адресом
# совпадает только в случае, если сервер имеет единственный интерфейс 
# и подключен напрямую в интернет, без NAT
user="user" # пользователь для удаленного подключения
ssh="10524" # удаленный порт для ssh
rdp="10525" # и для rdp

if /usr/bin/ssh ${user}@${server} nc -z -w 3 $remote $ssh # проверяем доступность нашего порта на удаленном сервере
then
        echo "Port ${ssh} is up" # если доступен, то все в порядке
else
        killall ssh -9  # Иначе убиваем ssh-сессии локально
        killall ssh -9  # если подвисли

/etc/init.d/ssh restart #перезапускаем сервис локально
/usr/bin/ssh -f -N ${user}@${server} -R ${remote}:${ssh}:127.0.0.1:22 -R ${remote}:${rdp}:127.0.0.1:3389 #и подключаемся заново с пробросом портов
fi
exit 0


Остается только добавить исполнение этого скрипта в cron, например, раз в пару минут.

Естественно, для каждого устройства порты ssh и rdp (или любые другие) должны быть уникальными.