Pull to refresh

Еще раз о пробросе портов из-за firewall-a

Reading time2 min
Views8.2K
Добрый день.
Я решил написать этот пост по нескольким причинам:
1) Иногда легче дать ссылку на статью, чем в сто первый раз рассказывать человеку, что ему необходимо сделать, и где про все это можно почитать.
2) Появилась необходимость привести знания в систему. А лучше всего это делать, если рассказываешь это другому человеку.
3) Чисто корыстный интерес — хочу инвайт.

Итак. Постановка задачи.
Есть рабочее место (W), закрытое роутером. Есть домашний компьютер (H), с которого периодически необходимо получать доступ к рабочему столу W, и который не имеет «белого» IP.
Schema-1
Менять что-то в настройках роутера — нельзя. Использовать TeamViewer & Co. — не наш путь.


Варианты решения.
Если отбросить сторонние программы, то вариантов решения остается только 2:
  • «протянуть» порт 5900 до белого IP с любой стороны (W или H). Потом просто коннектиться VNC клиентом на этот адрес.
  • Использовать промежуточный сервер для организации соединения. Плюсы этого варианта в том, что нет необходимости что-то менять в системе безопасности рабочего и домашнего серверов.


Я покажу реализацию второго варианта.
Schema-2
Итак, договоримся, что для простоты все машины работают под Linux. Проброс портов будет осуществляться через SSH соединение. Поэтому в качестве промежуточного сервера подойдет даже простенький VDS.

И еще одно замечание — SSHd на VDS-е должен разрешать подключение к проброшенному порту с другого адреса. Это важно! Разрешить это можно, прописав GatewayPorts yes в sshd_config. Не забудьте после этого перегрузить сервис $ sudo /etc/init.d/ssh restart

Схема работы выглядит следующим образом:
1) Машина W проверяет, хочет ли кто-нибудь ко мне подконнектится? (Подробности — ниже)
2) Если нет, то не делаем ничего. Если да, то устанавливаем SSH соединение с VDS сервером.
3) Машина H подключается VNC клиентом к VDS:5900 — и получает доступ к рабочему столу W.
4) Профит!

Отдельный вопрос — что может служить флагом о необходимости соединения?? Я решил этот вопрос просто. О необходимости соединения говорит наличие открытого порта (ну, например, 5995) на VDS. Если порт открыт — значит устанавливаем SSH соединение и пробрасываем порты, если закрыт — значит закрываем ненужный SSH канал до следующего сеанса.

Теперь немного скриптов:
Проверяем хочет ли кто-то доступ к столу?
$ crontab -u root -e
*/15 * * * * /usr/bin/connect_flag.sh

проверка каждые 15 минут.

Скрипт для проверки открытого порта на python-e
import socket
import subprocess

def scan(host, port):
   while 1:
      sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      try:
         sd.connect((host, port))
      except: return 0
      else:
         sd.close()
         return 1

if __name__ == '__main__':
   if scan('yourServer', 5995): print 'start'
   else: print 'stop'


Собственно bash скрипт connect_flag.sh, в котором реализована логика работы
#!/bin/bash
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin

PID=`/bin/ps ux | awk '/ssh -N username/ && !/awk/ {print $2}'`
FLAG=`/usr/bin/python /var/Script/portscan.py`
PARAM="-N username@yourVDS -R 5900:127.0.0.1:5900"

if [ $PID ];
then 
  if [ $FLAG == 'stop' ]; then `kill $PID`; fi
else 
  if [ $FLAG == 'start' ]; then 
    /usr/bin/ssh $PARAM & 
  fi
fi


Вот и все. На что хотелось бы обратить внимание:
  • на VDS сервере — разрешаем подключение к проброшенному порту с внешнего адреса.
  • на H машине — необходим только VNC клиент. И все.
  • на W машине — отрабатываются все скрипты. И их отладка самая трудная часть.
  • Открыть порт-флаг можно банальным nc -vv -l 5995 на VDS сервере.


Спасибо всем, кто дочитал этот пост до конца.
Tags:
Hubs:
Total votes 90: ↑78 and ↓12+66
Comments39

Articles