Rularea unui server VPN în spatele NAT-ului furnizorului

Un articol despre cum am reușit să rulez un server VPN în spatele NAT-ului furnizorului meu de acasă (fără o adresă IP albă). Lasă-mă să fac o rezervare imediat: asta performanța acestei implementări depinde direct de tipul de NAT utilizat de furnizorul dvs., precum și de router.
Așadar, trebuia să mă conectez de pe smartphone-ul meu Android la computerul meu de acasă, ambele dispozitive sunt conectate la Internet prin NAT-uri furnizorului, plus computerul este conectat printr-un router de acasă, care face și conexiuni NAT.
Schema clasică care folosește un VPS/VDS închiriat cu o adresă IP albă, precum și închirierea unei adrese IP albe de la un furnizor, nu a fost luată în considerare din mai multe motive.
Tinand cont experiență din articolele anterioare, după ce a efectuat mai multe experimente cu STUN-uri și NAT-uri ale furnizorilor. Am decis să fac un mic experiment rulând comanda pe un router de acasă care rulează firmware OpenWRT:

$ stun stun.sipnet.ru

a obtinut rezultatul:

Versiunea client STUN 0.97
Primar: cartografiere independentă, filtru independent, port aleatoriu, ac de păr
Valoarea de returnare este 0x000002

Traducere literala:
Independent Mapping - cartografiere independentă
Filtru independent - filtru independent
random port - port aleatoriu
will hairpin - va fi un ac de păr
Rulând o comandă similară pe computerul meu, am primit:

Versiunea client STUN 0.97
Primar: cartografiere independentă, filtru dependent de port, port aleatoriu, ac de păr
Valoarea de returnare este 0x000006

Port Dependent Filter - filtru dependent de port
Diferența dintre rezultatele ieșirii comenzii a indicat că routerul de acasă își aducea „contribuția” la procesul de transmitere a pachetelor de pe Internet; acest lucru s-a manifestat prin faptul că, la executarea comenzii pe computer:

stun stun.sipnet.ru -p 11111 -v

Primeam rezultatul:

...
MappedAddress = XX.1XX.1X4.2XX:4398
...

în acest moment, o sesiune UDP a fost deschisă de ceva timp, dacă în acest moment trimiteți o cerere UDP (de exemplu: netcat XX.1XX.1X4.2XX 4398 -u), atunci cererea a venit la routerul de acasă, care a fost confirmat de TCPDump care rulează pe el, dar cererea nu a ajuns la computer - IPtables, ca traducător NAT pe router, a scăpat-o.
Rularea unui server VPN în spatele NAT-ului furnizorului
Dar chiar faptul de a trece o solicitare UDP prin NAT-ul furnizorului a dat speranță de succes. Deoarece routerul se află în jurisdicția mea, am rezolvat problema redirecționând portul UDP/11111 către computer:

iptables -t nat -A PREROUTING -i eth1 -p udp -d 10.1XX.2XX.XXX --dport 11111 -j DNAT --to-destination 192.168.X.XXX

Astfel, am reușit să inițiez o sesiune UDP și să primesc solicitări de pe Internet de la orice adresă IP. În acest moment, am lansat OpenVPN-server (configurat-o anterior) ascultând portul UDP/11111, am indicat adresa IP externă și portul (XX.1XX.1X4.2XX:4398) pe smartphone și conectat cu succes de pe smartphone la calculatorul. Dar în această implementare a apărut o problemă: a fost necesar să se mențină cumva sesiunea UDP până când clientul OpenVPN se conectează la server; nu mi-a plăcut opțiunea de a lansa periodic clientul STUN - nu am vrut să irosesc sarcina pe serverele STUN.
Am observat și intrarea „will hairpin - va fi un ac de păr", acest mod

Hairpinning permite unei mașini dintr-o rețea locală din spatele unui NAT să acceseze o altă mașină din aceeași rețea la adresa externă a routerului.

Rularea unui server VPN în spatele NAT-ului furnizorului
Drept urmare, am rezolvat pur și simplu problema menținerii unei sesiuni UDP - am lansat clientul pe același computer cu serverul.
A funcționat așa:

  • a lansat clientul STUN pe portul local 11111
  • a primit un răspuns cu o adresă IP externă și un port XX.1XX.1X4.2XX:4398
  • a trimis date cu o adresă IP externă și un port către e-mail (este posibil orice alt serviciu) configurat pe smartphone
  • a lansat serverul OpenVPN pe un computer care asculta portul UDP/11111
  • a lansat clientul OpenVPN pe computer, specificând XX.1XX.1X4.2XX:4398 pentru conexiune
  • am lansat în orice moment clientul OpenVPN pe smartphone indicând adresa IP și portul (în cazul meu adresa IP nu s-a schimbat) pentru a vă conecta

Rularea unui server VPN în spatele NAT-ului furnizorului
În acest fel, am putut să mă conectez la computer de pe smartphone. Această implementare vă permite să conectați orice client OpenVPN.

Practică

Veți avea nevoie de:

# apt install openvpn stun-client sendemail

După ce am scris câteva scripturi, câteva fișiere de configurare și am generat certificatele necesare (deoarece clientul de pe un smartphone funcționează numai cu certificate), am obținut implementarea obișnuită a unui server OpenVPN.

Scriptul principal pe computer

# 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

Script pentru trimiterea datelor prin e-mail:

# 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"

Fișier de configurare a serverului:

# 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

Fișier de configurare client:

# 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

Certificatele au fost generate folosind acest articol.
Rularea scriptului:

# ./vpn11.sh

Mai întâi făcându-l executabil

# chmod +x vpn11.sh

Pe partea de smartphone

Prin instalarea aplicației OpenVPN pentru Android, după ce ați copiat fișierul de configurare, certificate și l-am configurat, a rezultat astfel:
Îmi verific e-mailul pe smartphoneRularea unui server VPN în spatele NAT-ului furnizorului
Editez numărul portului în setăriRularea unui server VPN în spatele NAT-ului furnizorului
Lansez clientul și mă conectezRularea unui server VPN în spatele NAT-ului furnizorului

În timp ce scriam acest articol, am transferat configurația de pe computerul meu pe Raspberry Pi 3 și am încercat să rulez totul pe un modem LTE, dar nu a funcționat! Rezultatul comenzii

# stun stun.ekiga.net -p 11111

Versiunea client STUN 0.97
Primar: cartografiere independentă, filtru dependent de port, port aleatoriu, ac de păr
Valoarea de returnare este 0x000006

valoare Filtru dependent de port nu a permis sistemului să pornească.
Dar furnizorul de acasă a permis ca sistemul să pornească pe Raspberry Pi 3 fără probleme.
În combinație cu o cameră web, cu VLC pt
crearea unui flux RTSP de la o cameră web

$ 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

și VLC pe un smartphone pentru vizionare (stream rtsp://10.2.0.1:8554/), s-a dovedit a fi un sistem bun de supraveghere video la distanță, puteți, de asemenea, să instalați Samba, să direcționați traficul prin VPN, să vă controlați computerul de la distanță și multe Mai mult...

Producție

După cum a arătat practica, pentru a organiza un server VPN, puteți face fără o adresă IP externă pentru care trebuie să plătiți, la fel ca pentru un VPS/VDS închiriat. Dar totul depinde de furnizor. Desigur, am vrut să obțin mai multe informații despre diferiții furnizori și tipuri de NAT utilizate, dar acesta este doar începutul...
Vă mulțumim pentru atenție!

Sursa: www.habr.com

Adauga un comentariu