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

Добрый день.
Я решил написать этот пост по нескольким причинам:
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 сервере.


Спасибо всем, кто дочитал этот пост до конца.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 39

    +9
    Открытый порт можно было проверять netcat'ом ('nc -z'), тогда бы всё уместилось в один скрипт.
      +4
      Согласен. Наверное, так было бы лучше. Просто в свое время меня google «вынес» на такое решение.
      +1
      Чем принципиально отличается коннект VNC от коннекта TeamViewer/Radmin/NX/RDP?
        +1
        Принципиально — ничем.
        Это один из протоколов доступа к рабочему столу. Выбирайте любой. VNC в статье взят для примера.
          0
          А при коннекте, используя RDC. как задать отличный от TCP 3389 порт на который надо коннектиться?
            0
            Написать в поле адреса [адрес]:[порт], например, 127.0.0.1:6689.
              0
              А как сделать чтобы серверная часть слушала на отличном от 3389 порту?
                0
                Если применительно к статье, то просто указать порт при вызове SSH:
                ssh -R 2002:127.0.0.1:3389
                и коннектся на порт 2002.

                Если вообще — то 3389 — порт прописанный в стандарте. Нужно копать в сторону port redirect.
                  0
                  Это к виндовым спецам, я не знаю.
                  С другой стороны, зачем? Ведь совсем не обязательно, чтобы оба конца тунеля были на одинаковых портах.
            0
            разные методы шифрования при почти одинаковом функционале
              0
              Ещё раз. Чем принципиально отличается коннект VNC от коннекта TeamViewer/Radmin/NX/RDP?

              P.S. Я повыделял малость, надеюсь парсер не сожрёт.
            +3
            > Использовать TeamViewer & Co. — не наш путь.
            Однако…
            > Использовать промежуточный сервер для организации соединения.

            Это какое-то деление на ноль. Откройте для себя logmein.com, хотя бы.
              0
              Не согласен.
              1) Я не хочу, чтобы в организации канала принимали участие сервера третьих фирм.
              2) Фишка статьи в организации callback вызова штатными средствами. Logmein хорош, но я не стал бы ставить его на рабочие машины.
              • НЛО прилетело и опубликовало эту надпись здесь
                  +3
                  Нет, он находится под моим контролем. Я могу установить ПО, я могу управлять логами. Я могу, например, организовать RAM диск, и вообще хранить все в оперативке…
                  А куда ляжет информация о вашем трафике на серверах logmein (logmein — только для примера)?
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • НЛО прилетело и опубликовало эту надпись здесь
              +2
              Ну это как-то не секьюрно. Поднимите ВПН хотя бы.
                0
                Между W и VDS — зачем? Там SSH. Между VDS и H — да, можно, но тема статьи проброс портов.
                Я еще пропустил момент идентификации по ключам, но это только «утяжелило» бы статью.
                  0
                  Статья неплохая. И хорошо, что вы понимаете. Но проблема в том, что кто-то прочитает, и сразу решит сделать точь в точь. А в результате будет пользоваться таким не очень безопасным решением. Я считаю, что стоит немножко думать и за читателя, предостерегать как-то. Но воля Ваша :)

                  А ssh не считаю панацеей. Юзаю ВПН и сплю спокойней, паранойя спасет мир.
                    0
                    Надеюсь, VPN с использованием транспортом SSL или хотя бы IPSEC? А то знаете ли, если у вас просто PPTP, возможны неприятные сюрпризы для вашей паранойи ;)
                +5
                Хотите фокус? Внешний сервер не нужен!
                Используйте PWNAT — http: // samy.pl / pwnat /
                (посмотрите как оно работает — весьма интересно!).
                  0
                  Этот «фокус» пройдет только с IP-NAT, т.е. только если внешний порт останется таким же как внутренний — 2222.
                  Через PNAT (коих 99%) фокус не пройдет — если только случайно порт не оттранслируется в те же 2222.
                  Собственно промежуточный хост в STUN в основном и нужен для того, чтобы внешние порты друг друга сторонам сообщить, IP и через какой-нибудь фокус (вроде этого) можно было протолкнуть.
                  –1
                  Спасибо. Обязательно посмотрю внимательно.
                  Но эта штука точно сможет соединить 2-е машины, и обе за firewall-ом, без промежуточного сервера?
                    +5
                    Прочитайте внимательно описание на указанном сайте.
                    Надо запускать две копии pwnat — в каждой сетке одну — одну как сервер, другую как клиент.
                    У меня нет кармы даже для того, чтобы вывешивать URL, так что переведу своими словами принцип действия:
                    1) Запускаем на машине в сетке А сервер — он будет просто слушать (не секьюрно — он будет слушать всех! — о безопасности заботьтесь сами).
                    2) Запускаем клиента в сетке B.
                    Что происходит?
                    — когда сервер запускается, он начинает отправку фиксированных ICMP «эхо
                    Запрос» пакетов на фиксированный адрес 3.3.3.3. Мы ожидаем, что эти пакеты
                    не будут возвращены.
                    — Теперь 3.3.3.3 НЕ есть тот хост, с которым мы хотим связаться! Но мы его ЗНАЕМ!
                    — Когда клиент хочет подключиться — он послылает ICMP «Время истекло» пакет якобы с информацией 3.3.3.3 от своего IP.
                    на адрес роутера сети А
                    И они попадают серверу в сети А, как якобы ответы на отлуп от 3.3.3.3! Но с дополнительным полезным содержимым (а именно IP адресом клиента и клиентской сети) внутри.
                    Таким образом, сервер получил IP клиента и его сетки.
                    Далее
                    3) Cервер начинает бомбить IP роутера клиента UDP пакетами, скажем, на порт 2222. Его роутер сети А замечает это и открывает обратный маршрут для ответов на этот же порт. Что нам и нужно.
                    Таким образом, мы получили двусторонний канал UDP пакетов, в который далее можно упихать что угодно — TCP сессии и т.д.

                    Дублирую источник информации — http: // samy.pl / pwnat /

                      0
                      Интересно. Большое спасибо.
                        0
                        Есть собранный клиент для win32 с сорцами, если кому интересно будет.
                        • НЛО прилетело и опубликовало эту надпись здесь
                            0
                            Насчет безопасности, в режиме сервера есть ключи "[[allowed host]:[allowed port] ...]", название которых нам какбы намекают.
                          0
                          Буквально 20 минут назад решал эту задачу, как попасть на свой собственный же сервер, который стоит на работе и доступ к которому имеют только другие сервера, которые стоят на работе.
                          Пришлось через сервер клиента зайти и уже через него на маршрутизаторе разрешить вход для себя с удалённого компьютера. Задача проста, но заставлять подумать.
                            +1
                            для простоты все машины работают под Linux.
                            Ну в таком случае даже VDS не нужен, да и без скриптов в кроне вполне можно обойтись.
                            Прибить к домашней машине домен с dyndns не составляет никаких трудностей (не все же берут статику), так что подцепиться можно напрямую к дому. А чтобы при разрыве соединение само восстанавливалось, коннектимся не с помощью ssh, а autossh, который вешаем в screen/tmux. При желании можно даже в автозагрузку кинуть.
                              0
                              ps. А еще есть IPv6 (:
                              0
                              openvpn (который умеет работать через прокси, поддерживающие метод connect) + realip на удалённом сервере рулит =)
                              а ещё есть несколько техник типа icmp/dns-тоннелей xgu.ru/wiki/Firewall_Piercing
                              через ssh всё таки изврат обратный коннект делать, но тоже идея. идея главная в том, что не висит постоянного коннекта.
                              с точки зрения обезопашивания себя от корпоративных безопасников — это тру.
                                0
                                Объясните мне, молодому и неопытному, почему использование Logmein — это плохо и атата (еще причины, кроме наличия третьей стороны). Мне правда интересно.
                                  0
                                  Однозначного ответа нет. Каждый для себя решает сам. Даже в этом топике есть люди, которые «лучше спят» — если поверх поднят еще и VPN. Все зависит от конкретных обстоятельств и конкретных требований.

                                  Посмотри с точки зрения сисадмина сети. Приходит сотрудник, и начинает на комп ставить всякие программы, которые «дырявят» его систему обороны… Какова будет его реакция? «Запрещено корпоративной политикой!».

                                  Посмотри с точки зрения пользователя. Для того, чтобы установить удаленный стол тебе надо, как минимум, доказать своему сисадмину, что это действительно необходимо. И опять же «запрещено корпоративной политикой».

                                  Но самым главным недостатком подобных программ является их закрытость. Серверную часть тебе все равно прийдется поставить, и что там внутри, знает только разработчик. А чем больше ответственность — тем больше должна быть паранойя. Тогда лучше спится. :)

                                  Вывод такой: если по быстрому соседу поправить антивирус, то logmein — то, что надо! Если серьезно, и там, где хоть теоретически, возможны какие-либо потери — лучше строить доступ самому, и используя проверенные стандарты и протоколы.

                                  Кстати. В описанном способе действительно есть большая дыра. Это момент подключения к VDS серверу клиентом. Здесь вас фактически защищает только пароль VNC протокола. А он, в силу спецификации, — ну очень несекьюрный.
                                  0
                                  Я не слишком в теме (правда, пробовал и Logmein и TeamViewer) но есть мнение, что VNC довольно неоптимально (в сравнении с последними) передает изменения с экрана.
                                    0
                                    >Итак, договоримся, что для простоты все машины работают под Linux.
                                    Хм… и в чем же простота?
                                      0
                                      Ну, например в том, что для Windows надо было бы устанавливать какой-нибудь cron, и в bat файле вместо «SSH» использовать «PLINK.EXE -ssh» и дальше по тексту…
                                        0
                                        Bitvise Tunnelier + WinSSHD и все работает.

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                    Самое читаемое