Статья о том, как мне удалось запустить VPN-сервер за NAT'ом домашнего провайдера (без белого IP-адреса). Сразу оговорюсь: что работоспособность данной реализация напрямую зависит от типа NAT используемого Вашим провайдером, а также роутером.
Итак, возникла у меня необходимость подключаться со своего Android-смартфона к домашнему компьютеру, оба девайса подключены к Интернету через провайдерские NAT'ы, плюсом компьютер подключен через домашний роутер, который тоже NAT'ил соединения.
Классическая схема с использованием арендованного VPS/VDS с белым IP-адресом, а также аренда белого IP-адреса у провайдера не рассматривалась по нескольким причинам.
С учетом опыта прошлых статей, проведя несколько опытов со STUNами и NAT'ами провайдеров. Решился на небольшой эксперимент, выполнив команду на домашнем роутере работающем на прошивке OpenWRT:
$ stun stun.sipnet.ru

получил результат:
STUN client version 0.97
Primary: Independent Mapping, Independent Filter, random port, will hairpin
Return value is 0x000002

Дословный перевод:
Independent Mapping — независимое отображение
Independent Filter — независимый фильтр
random port — случайный порт
will hairpin — будет шпилька
Выполнив аналогичную команду на своем ПК, получил:
STUN client version 0.97
Primary: Independent Mapping, Port Dependent Filter, random port, will hairpin
Return value is 0x000006

Port Dependent Filter — порт зависимый фильтр
Разница в результатах вывода команд говорила о том, что домашний роутер вносил «свою лепту» в процесс трансляции пакетов из Интернета, это проявлялось в том, что при выполнении команды на компьютере:
stun stun.sipnet.ru -p 11111 -v

я получал результат:

MappedAddress = XX.1XX.1X4.2XX:4398
...
в это момент на некоторое время открывалась UDP-сессия, если в этот момент послать UDP-запрос (например: netcat XX.1XX.1X4.2XX 4398 -u), то запрос приходил на домашний роутер, что подтвердил TCPDump запущенный на нем, но запрос не доходил до компьютера — IPtables в качестве NAT-транслятора на роутере дропал его.

Но сам факт прохождения UDP запроса через провайдерский NAT давал надежду на успех. Так как роутер находится в моей юрисдикции, решил проблему перенаправлением UDP/11111 порта на компьютер:
iptables -t nat -A PREROUTING -i eth1 -p udp -d 10.1XX.2XX.XXX --dport 11111 -j DNAT --to-destination 192.168.X.XXX
Тем самым получил возможность инициировать UDP-сессию и получать запросы из Интернета с любого IP-адреса. В этот момент запустил OpenVPN-server (предварительно сконфигурировав) слушая UDP/11111 порт, указал на смартфоне внешний IP-адрес и порт (XX.1XX.1X4.2XX:4398) и успешно подключился со смартфона к компьютеру. Но в данной реализации возникла проблема, нужно было как-то поддерживать UDP-сессию до момента подключения OpenVPN-клиента к серверу, вариант с периодическим запуском STUN-клиента мне не понравился — не хотелось впусту нагружать STUN-серверы.
Так же обратил внимание на запись "will hairpin — будет шпилька", данный режим
Hairpinning позволяет одной машине в локальной сети за NAT получить доступ к другой машине в той же сети по внешнему адресу маршрутизатора.

image
В итоге проблему поддержания UDP-сессии решил просто — запустил клиента на этом же компьютере с сервером.
Работало это так:
  • запускал STUN-клиента с локальным портом 11111
  • получал ответ с внешним IP-адресом и портом XX.1XX.1X4.2XX:4398
  • отправлял данные с внешним IP-адресом и портом на почту (возможен любой другой сервис), настроенную на смартфоне
  • запускал OpenVPN-сервер на компьютере с прослушкой UDP/11111 порта
  • запускал OpenVPN-клиента на компьютере с указанием XX.1XX.1X4.2XX:4398 для подключения
  • в любое время запускал OpenVPN-клиента на смартфоне с указанием IP-адреса и порта (в моем случае IP-адрес не менялся) для подключения


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

Практика


Понадобится:
# apt install openvpn stun-client sendemail

Написав пару скриптов, пару конфигурационных файлов, сгенерировав необходимые сертификаты (так как клиент на смартфоне работает только по сертификатам) получилась обычная реализация OpenVPN-сервера.

Основной скрипт на компьютере


# cat vpn11.sh

#!/bin/bash
until [[ -n "$iftosrv" ]]; do echo "$(date) Определяю сетевой интерфейс"; iftosrv=`ip route get 8.8.8.8 | head -n 1 | sed 's|.*dev ||' | awk '{print $1}'`; sleep 5; done
ABSOLUTE_FILENAME=`readlink -f "$0"`
DIR=`dirname "$ABSOLUTE_FILENAME"`
localport=11111
until [[ $a ]]; do
	address=`stun stun.sipnet.ru -v -p $localport 2>&1 | grep "MappedAddress" | sort | uniq | head -n 1 | sed 's/:/ /g' | awk '{print $3" "$4}'`
        ip=`echo "$address" | awk {'print $1'}`
        port=`echo "$address" | awk {'print $2'}`
	srv="openvpn --config $DIR/server.conf --port $localport --daemon"
	$srv
	echo "$(date) Сервер запущен с внешним адресом $ip:$port"
	$DIR/sendemail.sh "OpenVPN-Server" "$ip:$port"
	sleep 1
	openvpn --config $DIR/client.conf --remote $ip --port $port
	echo "$(date) Cоединение клиента с сервером разорвано"
	for i in `ps xa | grep "$srv" | grep -v grep | awk '{print $1}'`; do
		kill $i && echo "$(date) Завершен процесс сервера $i ($srv)"
		done
	echo "Жду 15 сек"
	sleep 15
	done

Скрипт отправки данных на почту:
# cat sendemail.sh 

#!/bin/bash
from="От кого"
pass="Пароль"
to="Кому"
theme="$1"
message="$2"
server="smtp.yandex.ru:587"
sendEmail -o tls=yes -f "$from" -t "$to" -s "$server" -xu "$from" -xp "$pass" -u "$theme" -m "$message"

Конфигурационный файл сервера:
# cat server.conf

proto udp
dev tun
ca      /home/vpn11-srv/ca.crt
cert    /home/vpn11-srv/server.crt
key     /home/vpn11-srv/server.key
dh      /home/vpn11-srv/dh2048.pem
server 10.2.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
tls-server
tls-auth /home/vpn11-srv/ta.key 0
tls-timeout 60
auth    SHA256
cipher  AES-256-CBC
client-to-client
keepalive 10 30
comp-lzo
max-clients 10
user nobody
group nogroup
persist-key
persist-tun
log /var/log/vpn11-server.log
verb 3
mute 20

Конфигурационный файл клиента:
# cat client.conf

client
dev tun
proto udp
ca      "/home/vpn11-srv/ca.crt"
cert    "/home/vpn11-srv/client1.crt"
key     "/home/vpn11-srv/client1.key"
tls-client
tls-auth "/home/vpn11-srv/ta.key" 1
auth SHA256
cipher AES-256-CBC
auth-nocache
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
log /var/log/vpn11-clent.log
verb 3
mute 20
ping 10
ping-exit 30

Генерация сертификатов производилась по этой статье.
Запуск скрипта:
# ./vpn11.sh

Предварительно сделав его исполняемым
# chmod +x vpn11.sh

На стороне смартфона


Установив приложение OpenVPN для Android, скопировав конфигурационный файл, сертификаты и настроив его, получилось так:
На смартфоне проверяю почту

Правлю номер порта в настройках

Запускаю клиента и подключаюсь


В процессе написания статьи я перенес конфигурацию с компьютера на Raspberry Pi 3 и попробовал запустить всё это дело на LTE модеме, но не получилось! Результат команды
# stun stun.ekiga.net -p 11111

STUN client version 0.97
Primary: Independent Mapping, Port Dependent Filter, random port, will hairpin
Return value is 0x000006
значение Port Dependent Filter не позволило запуститься системе.
Но домашний провайдер без проблем дал запуститься системе на Raspberry Pi 3.
В связке с вэб-камерой, сVLC для
создания RTSP-потока с вэб-камеры
$ cvlc v4l2:///dev/video0:chroma=h264 :input-slave=alsa://hw:1,0 --sout '#transcode{vcodec=x264,venc=x264{preset=ultrafast,profile=baseline,level=31},vb=2048,fps=12,scale=1,acodec=mpga,ab=128,channels=2,samplerate=44100,scodec=none}:rtp{sdp=rtsp://10.2.0.1:8554/}' --no-sout-all --sout-keep


и VLC на смартфоне для просмотра (поток rtsp://10.2.0.1:8554/), получилась не плохая система видеонаблюдения на расстоянии, так же можно поднять Samba и обмениваться файлами, маршрутизировать трафик через VPN,
удаленно управлять компьютером
и много чего еще…

Вывод


Как показала практика, для оргинизации VPN-сервера можно обойтись и без внешнего IP-адреса за который нужно платить, так же как и за арендуемый VPS/VDS. Но всё зависит от провайдера. Конечно хотелось получить больше информации о различных провайдерах и типах используемых NAT'ов, но ведь это только начало…
Спасибо за внимание!

Комментарии (25)


  1. krylov_sn
    05.01.2020 20:01
    +1

    на роутере Keenetic развернул L2TP VPN. Белого IP нет — использую DDNS. все работает — но, как было написано в статье, зависит от провайдера.


    1. Winseven Автор
      05.01.2020 20:08
      +1

      Да, такое возможно, работает принцип UDP hole punching, при условии, что провайдер NAT'ит порт-в-порт, то есть внутренний порт сопоставлен с внешним, но увы, как показывает практика не все провайдеры одинаково полезны)


      1. krylov_sn
        05.01.2020 20:09
        +1

        Убедился в этом на собственном опыте. На одном роутере у другого провайдера никак не работало. Заработало только когда провайдер сменил оборудование


        1. Winseven Автор
          05.01.2020 20:24
          +1

          Некоторые провайдеры специально блокирую такую возможность, например провайдеры мобильного интернета.


          1. krylov_sn
            05.01.2020 20:29
            +1

            Проводной, но, думаю, за белый ip хотели денег


            1. Winseven Автор
              05.01.2020 20:33

              Да, это очевидно, на фоне дефицита IPv4, почему-то провайдеры не особо торопятся на IPv6, потому что с приходом IPv6 в каждый дом, многие сервисы (Хостинг, VPN-сервисы и т.п.) просто станут не нужными…


              1. nevzorofff
                05.01.2020 21:52
                +1

                Ага, именно поэтому статические адреса некоторые за полтос в месяц раздают


                1. happy-cat
                  06.01.2020 17:27
                  +2

                  Я за белый статичный IP от МГТС плачу 179 руб/мес, но никак не полтос...


                  1. TerekhinNI
                    06.01.2020 22:09
                    +1

                    Кек, Монтон телеком (уже Ростелеком, но тарифы старые) — Москва — 500р в месяц.


                    1. Winseven Автор
                      07.01.2020 22:54

                      С такой ценой

                      500р в месяц
                      можно VPS (4 vCPU процессор /4 ГБпамять / 60 ГБ SSDдиск / безлимитный трафик / KVM виртуализация) с белым IP-арендовать)))


              1. lubezniy
                06.01.2020 00:49
                +1

                С чего бы вдруг станут не нужными? В частности, тот же хостинг — сайты хостить перестанут, все серверы развезут по домам и офисам?


                1. Winseven Автор
                  06.01.2020 01:04

                  В контексте «многие сервисы (Хостинг, VPN-сервисы и т.п.)» имелось ввиду те, что используются для организации VPN-соединений.


                  1. lubezniy
                    06.01.2020 10:12
                    +1

                    Сомневаюсь, если честно. Считаю, что для связи локальных подсетей VPN всё равно останутся. Может быть, даже будет гонять внутри VPN IPv4 для старых устройств вроде принтеров или какого-то производственного оборудования, менять которое на новое (с поддержкой IPv6) будет дорого.


                    1. Winseven Автор
                      06.01.2020 22:17

                      VPN останется и будет всегда, я имел ввиду, что с приходом IPv6 отпадет потребность в аренде VPS/VDS для организации VPN между сетями находящимися за NAT, не будет понятия серый/белый IP-адрес. Можно будет соединять сети напрямую без VPS/VDS. Существуют разные протоколы типа IPv4 over IPv6…


  1. NeoBeZ
    06.01.2020 00:46

    Странно, имею две сим:
    мтс
    мегафон


    И там и там белая динамика


    1. Dimasmir0
      06.01.2020 11:39
      +1

      Уверены?
      Белый ipv4 дадут юридическому лицу за доп плату. Мне кажется физические лица не могут получить.


      1. lv333
        07.01.2020 16:59
        +1

        Динамический белый IP… да большинство так и делают, причем он имеет очень длительное время аренды у проводных провайдеров, фактически почти фиксированный белый IP если не менять мак адрес устройства с которого устанавливается подключение. С мобильными не все так радужно, но тем не менее динамический белый IP тоже как правило дают.


        1. Winseven Автор
          07.01.2020 23:33

          Интересно, попробую узнать у своего сотового оператора…


      1. lubezniy
        07.01.2020 19:32

        Могут (есть, и даже постоянный белый). Только сейчас провайдеры не очень-то охотно их выдают.


      1. NeoBeZ
        08.01.2020 11:51

        мега
        image


  1. maledog
    07.01.2020 18:18
    +1

    Что-то мне подсказывает, что владельцы скоро прикроют свои stun серверы, если такое использование стает массовым. Наверняка в лицензионном соглашении где-то есть пункт, о вариантах возможного использования.


    1. Winseven Автор
      07.01.2020 21:43

      Думаю будут доступны до тех, пор пока нагрузка на STUN не станет ощутима для хозяина сервера… Хотя для тех у кого есть возможность/потребность, белый IP и сервер ничего не стоит его поднять:

      # apt install stun-server
      # nano /etc/default/stun

      START_DAEMON=true
      DAEMON_OPTS=""
      PRIMARY_IP="Первый внешний IP"
      SECONDARY_IP="Второй внешний IP"
      PRIMARY_PORT=3478
      SECONDARY_PORT=3479
      DAEMON_USER=nobody

      # systemctl restart stun.service


      1. maledog
        07.01.2020 22:31
        +1

        Тогда уже логично будет разместить в этой точке vpn-сервер и весь смысл в сложных решениях со stun пропадает.
        ИМХО в этом плане tinc несколько удобнее openvpn, хоть и менее функционален и безопасен, он позволяет держать несколько нод с белым ip объединяющих все подключенные устройства в единую L2 — сеть. Таким образом при пропадание одной серверной ноды клиенты легко переподключатся ко второй.


        1. Winseven Автор
          07.01.2020 22:39

          К примеру: у меня есть служебный STUN-сервер (на работе), но это не дает возможности поднимать VPN-сервер и передавать через него личные данные. С точки зрения моей паранойи соединение точка — точка более безопасно, по сравнению с точка — сервер (VPS) — точка, также без сервера сложнее произвести атаку на сервер (касаемо моей прошлой статьи)))), более надежно с точки зрения уменьшения количества возможных точек отказа.
          Я противник «в единую L2 — сеть» с точки зрения лишней нагрузки на сети (трансляция кадров в замен пакетов), предпочитаю динамическую маршрутизацию, чем Spanning Tree Protocol. Хотя L2 полезен и необходим в некоторых случая, например при передачи тегированного трафика.
          К сожалению, не знал о Tinc и его функционале, до момента написания второй статьи…


          1. maledog
            07.01.2020 23:01

            С чем-то согласен. Но адрес и порт сервера известен yandex. Кроме того, есть еще одно место TLS. Если на клиенте сильно сбилось время, то связь с сервером не будет установлена, еще DPI могут повлиять на установку соединения пытаясь вмешаться в TLS.