Итак, возникла у меня необходимость подключаться со своего 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
я получал результат:
…в это момент на некоторое время открывалась UDP-сессия, если в этот момент послать UDP-запрос (например: netcat XX.1XX.1X4.2XX 4398 -u), то запрос приходил на домашний роутер, что подтвердил TCPDump запущенный на нем, но запрос не доходил до компьютера — IPtables в качестве NAT-транслятора на роутере дропал его.
MappedAddress = XX.1XX.1X4.2XX:4398
...
Но сам факт прохождения 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 получить доступ к другой машине в той же сети по внешнему адресу маршрутизатора.
В итоге проблему поддержания 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значение Port Dependent Filter не позволило запуститься системе.
Primary: Independent Mapping, Port Dependent Filter, random port, will hairpin
Return value is 0x000006
Но домашний провайдер без проблем дал запуститься системе на Raspberry Pi 3.
В связке с вэб-камерой, сVLC для
$ 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)
NeoBeZ
06.01.2020 00:46Странно, имею две сим:
мтс
мегафон
И там и там белая динамика
Dimasmir0
06.01.2020 11:39+1Уверены?
Белый ipv4 дадут юридическому лицу за доп плату. Мне кажется физические лица не могут получить.lv333
07.01.2020 16:59+1Динамический белый IP… да большинство так и делают, причем он имеет очень длительное время аренды у проводных провайдеров, фактически почти фиксированный белый IP если не менять мак адрес устройства с которого устанавливается подключение. С мобильными не все так радужно, но тем не менее динамический белый IP тоже как правило дают.
lubezniy
07.01.2020 19:32Могут (есть, и даже постоянный белый). Только сейчас провайдеры не очень-то охотно их выдают.
maledog
07.01.2020 18:18+1Что-то мне подсказывает, что владельцы скоро прикроют свои stun серверы, если такое использование стает массовым. Наверняка в лицензионном соглашении где-то есть пункт, о вариантах возможного использования.
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
maledog
07.01.2020 22:31+1Тогда уже логично будет разместить в этой точке vpn-сервер и весь смысл в сложных решениях со stun пропадает.
ИМХО в этом плане tinc несколько удобнее openvpn, хоть и менее функционален и безопасен, он позволяет держать несколько нод с белым ip объединяющих все подключенные устройства в единую L2 — сеть. Таким образом при пропадание одной серверной ноды клиенты легко переподключатся ко второй.Winseven Автор
07.01.2020 22:39К примеру: у меня есть служебный STUN-сервер (на работе), но это не дает возможности поднимать VPN-сервер и передавать через него личные данные. С точки зрения моей паранойи соединение точка — точка более безопасно, по сравнению с точка — сервер (VPS) — точка, также без сервера сложнее произвести атаку на сервер (касаемо моей прошлой статьи)))), более надежно с точки зрения уменьшения количества возможных точек отказа.
Я противник «в единую L2 — сеть» с точки зрения лишней нагрузки на сети (трансляция кадров в замен пакетов), предпочитаю динамическую маршрутизацию, чем Spanning Tree Protocol. Хотя L2 полезен и необходим в некоторых случая, например при передачи тегированного трафика.
К сожалению, не знал о Tinc и его функционале, до момента написания второй статьи…maledog
07.01.2020 23:01С чем-то согласен. Но адрес и порт сервера известен yandex. Кроме того, есть еще одно место TLS. Если на клиенте сильно сбилось время, то связь с сервером не будет установлена, еще DPI могут повлиять на установку соединения пытаясь вмешаться в TLS.
krylov_sn
на роутере Keenetic развернул L2TP VPN. Белого IP нет — использую DDNS. все работает — но, как было написано в статье, зависит от провайдера.
Winseven Автор
Да, такое возможно, работает принцип UDP hole punching, при условии, что провайдер NAT'ит порт-в-порт, то есть внутренний порт сопоставлен с внешним, но увы, как показывает практика не все провайдеры одинаково полезны)
krylov_sn
Убедился в этом на собственном опыте. На одном роутере у другого провайдера никак не работало. Заработало только когда провайдер сменил оборудование
Winseven Автор
Некоторые провайдеры специально блокирую такую возможность, например провайдеры мобильного интернета.
krylov_sn
Проводной, но, думаю, за белый ip хотели денег
Winseven Автор
Да, это очевидно, на фоне дефицита IPv4, почему-то провайдеры не особо торопятся на IPv6, потому что с приходом IPv6 в каждый дом, многие сервисы (Хостинг, VPN-сервисы и т.п.) просто станут не нужными…
nevzorofff
Ага, именно поэтому статические адреса некоторые за полтос в месяц раздают
happy-cat
Я за белый статичный IP от МГТС плачу 179 руб/мес, но никак не полтос...
TerekhinNI
Кек, Монтон телеком (уже Ростелеком, но тарифы старые) — Москва — 500р в месяц.
Winseven Автор
С такой ценой
можно VPS (4 vCPU процессор /4 ГБпамять / 60 ГБ SSDдиск / безлимитный трафик / KVM виртуализация) с белым IP-арендовать)))lubezniy
С чего бы вдруг станут не нужными? В частности, тот же хостинг — сайты хостить перестанут, все серверы развезут по домам и офисам?
Winseven Автор
В контексте «многие сервисы (Хостинг, VPN-сервисы и т.п.)» имелось ввиду те, что используются для организации VPN-соединений.
lubezniy
Сомневаюсь, если честно. Считаю, что для связи локальных подсетей VPN всё равно останутся. Может быть, даже будет гонять внутри VPN IPv4 для старых устройств вроде принтеров или какого-то производственного оборудования, менять которое на новое (с поддержкой IPv6) будет дорого.
Winseven Автор
VPN останется и будет всегда, я имел ввиду, что с приходом IPv6 отпадет потребность в аренде VPS/VDS для организации VPN между сетями находящимися за NAT, не будет понятия серый/белый IP-адрес. Можно будет соединять сети напрямую без VPS/VDS. Существуют разные протоколы типа IPv4 over IPv6…