Запуск VPN-сервера за правайдэрскім NAT'ам

Артыкул аб тым, як мне атрымалася запусціць 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-транслятара на роўтары драпаў яго.
Запуск VPN-сервера за правайдэрскім 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 атрымаць доступ да іншай машыны ў той жа сеткі па вонкавым адрасе маршрутызатара.

Запуск VPN-сервера за правайдэрскім NAT'ам
У выніку праблему падтрымання UDP-сесіі вырашыў проста - запусціў кліента на гэтым жа кампутары з серверам.
Працавала гэта так:

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

Запуск VPN-сервера за правайдэрскім NAT'ам
Такім чынам я атрымаў магчымасць падлучацца да свайго кампутара са смартфона. Дадзеная рэалізацыя дазваляе падлучаць любога 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, скапіяваўшы канфігурацыйны файл, сертыфікаты і наладзіўшы яго, атрымалася так:
На смартфоне правяраю поштуЗапуск VPN-сервера за правайдэрскім NAT'ам
Праўлю нумар порта ў наладахЗапуск VPN-сервера за правайдэрскім NAT'ам
Запускаю кліента і падключаюсяЗапуск VPN-сервера за правайдэрскім NAT'ам

У працэсе напісання артыкула я перанёс канфігурацыю з кампутара на 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'ов, але гэта толькі пачатак…
Дзякуй за ўвагу!

Крыніца: habr.com

Дадаць каментар