§ Подключение к SSH за маршрутизатором с UPnP

Так получается что у моих родителей на домашних ноутбуках установлен и настроен Linux. Поэтому для того что бы что нибудь поправить мне не приходится подключать VNC и прочую ерунду, мне нужен только SSH порт и все. Но так как все они сидят за маршрутизатором (D-Link DIR300) то каждый раз выяснять какой у них внутри IP и пробрасывать порт вручную как то муторно и в целом не хочется. Поэтому я решил воспользоваться небольшой военной хитростью под названием UPnP

Дело в том, что протокол UPnP имеет такое расширение как IGD, позволяющее динамически настраивать маршрутизатор в рамках проброса портов. Это вполне подходит для проброса порта SSH на маршрутизаторе. Утилита которая позволяет открывать и закрывать порты называется upnpc, и идет вместе с пакетом miniupnpc. Поэтому что бы много не заморачиваться, я написал следующий скрипт на bash + upnpc + zenity. 

Сперва нам необходимо поставить недостающие пакеты

sudo aptitude install -y zenity miniupnpc

Ну а теперь можно писать следующий скрипт.

#!/bin/bash

# Start port 22222
PORT=22222

# Test for router
upnpc -l > /dev/null
if [[ $? -ne 0 ]]
then
  zenity --warning --title="Ошибка UPnP" --text="Маршрутизатор с поддержкой UPnP не найден."
  exit 2
fi

USER=`whoami`
EXT_IP=`upnpc -l | awk '/ExternalIPAddress/ {print $3}'`
INT_IP=`hostname -I`
PORTS=`upnpc -l | awk '/^\ [0-9]\ TCP/ {print $3}' | sed 's/->.*//g' | tr '\n' ' '`

# Find first free port
while [[ "$PORTS" =~ .*$PORT\ .* ]]
do
  PORT=$(( $PORT + 1 ))
done

# Opening port
upnpc -a $INT_IP 22 $PORT TCP

if [[ $? -ne 0 ]]
then
	zenity --warning --title="Ошибка UPnP" --text="Не удалось открыть порт"
	exit 3
fi

# Informing
zenity --info --title="Проброс SSH" --text="Адресс для подключения:\n ssh $USER@$EXT_IP -p $PORT\n Не закрывайте это окно до завершения сеанса."

# Closing port
upnpc -d $PORT TCP
if [[ $? -ne 0 ]]
then
  exit 4
fi

Данный скрипт автоматически считывает имя пользователя, внешний и внутренний IP адресс, и пытается самостоятельно найти первый свободный TCP порт доступный на роутере для маппинга (по умолчанию 22222 если нет - то проверяет следующий), как только порт найден, скрипт сообщает роутеру что необходимо совершить проброс со свободного порта на себя на порт 22 (SSH), и выдает пользователю сообщение, в котором указывает что нужно набрать удаленной стороне (логин, внешний IP, порт). После нажатия "OK" в информационном окошке скрипт автоматически закрывает проброс порта.

Достаточно быстро и легко. Теперь когда мне нужно помочь родителям, я просто прошу скинуть мне строчку которую выдает им скрипт. И никакого геммороя с удаленным изменением конфигурации маршрутизатора.


comments powered by Disqus