Uruchamianie serwera VPN za NAT dostawcy

Artykuł o tym jak udało mi się uruchomić serwer VPN za NAT mojego domowego dostawcy (bez białego adresu IP). Pozwólcie, że od razu dokonam rezerwacji: to wydajność tej implementacji zależy bezpośrednio od typu NAT używanego przez Twojego dostawcę, a także od routera.
Musiałem więc połączyć się ze smartfona z Androidem z komputerem domowym, oba urządzenia są podłączone do Internetu za pośrednictwem NAT dostawcy, a komputer jest podłączony przez router domowy, który również obsługuje połączenia NAT.
Klasyczny schemat wykorzystujący dzierżawiony VPS/VDS z białym adresem IP, a także wynajęcie białego adresu IP od dostawcy, nie był brany pod uwagę z kilku powodów.
Biorąc pod uwagę doświadczenia z poprzednich artykułów, po przeprowadzeniu kilku eksperymentów z STUN i NAT dostawców. Postanowiłem przeprowadzić mały eksperyment, uruchamiając polecenie na routerze domowym z oprogramowaniem OpenWRT:

$ stun stun.sipnet.ru

otrzymałem wynik:

Wersja klienta STUN 0.97
Podstawowy: Niezależne mapowanie, niezależny filtr, losowy port, spinka do włosów
Wartość zwracana to 0x000002

Dosłowne tłumaczenie:
Niezależne mapowanie - niezależne mapowanie
Niezależny filtr - niezależny filtr
losowy port - losowy port
będzie spinka do włosów - będzie spinka do włosów
Uruchamiając podobne polecenie na moim komputerze, otrzymałem:

Wersja klienta STUN 0.97
Podstawowy: Niezależne mapowanie, filtr zależny od portu, losowy port, spinka do włosów
Wartość zwracana to 0x000006

Filtr zależny od portu - filtr zależny od portu
Różnica w wynikach wyjścia polecenia wskazywała, że ​​router domowy „wnosił swój wkład” w proces przesyłania pakietów z Internetu, objawiając się tym, że podczas wykonywania polecenia na komputerze:

stun stun.sipnet.ru -p 11111 -v

Otrzymałem wynik:

...
Mapowany adres = XX.1XX.1X4.2XX:4398
...

w tym momencie sesja UDP była otwarta przez jakiś czas, jeśli w tym momencie wyślesz żądanie UDP (na przykład: netcat XX.1XX.1X4.2XX 4398 -u), to żądanie przyszło do routera domowego, który był potwierdzone przez działający na nim protokół TCPDump, ale żądanie nie dotarło do komputera - IPtables, jako tłumacz NAT na routerze, porzucił je.
Uruchamianie serwera VPN za NAT dostawcy
Ale sam fakt, że żądanie UDP przeszło przez NAT dostawcy, dawał nadzieję na sukces. Ponieważ router znajduje się na terenie mojej jurysdykcji, rozwiązałem problem, przekierowując port UDP/11111 na komputer:

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

Dzięki temu mogłem zainicjować sesję UDP i odbierać żądania z Internetu z dowolnego adresu IP. W tym momencie uruchomiłem serwer OpenVPN (po wcześniejszym skonfigurowaniu) nasłuchując portu UDP/11111, wskazałem zewnętrzny adres IP i port (XX.1XX.1X4.2XX:4398) na smartfonie i pomyślnie nawiązałem połączenie ze smartfona do komputer. Ale w tej implementacji pojawił się problem: trzeba było jakoś utrzymać sesję UDP do czasu połączenia klienta OpenVPN z serwerem; nie podobała mi się opcja okresowego uruchamiania klienta STUN - nie chciałem marnować obciążenia serwery STUN.
Zauważyłem też wpis „będzie spinka do włosów - będzie spinka do włosów", ten tryb

Hairpinning umożliwia jednej maszynie w sieci lokalnej za NAT dostęp do innej maszyny w tej samej sieci pod zewnętrznym adresem routera.

Uruchamianie serwera VPN za NAT dostawcy
W rezultacie po prostu rozwiązałem problem utrzymania sesji UDP - uruchomiłem klienta na tym samym komputerze co serwer.
To działało tak:

  • uruchomił klienta STUN na lokalnym porcie 11111
  • otrzymał odpowiedź z zewnętrznym adresem IP i portem XX.1XX.1X4.2XX:4398
  • przesyłane dane z zewnętrznego adresu IP i portu na e-mail (możliwa jest każda inna usługa) skonfigurowanego na smartfonie
  • uruchomił serwer OpenVPN na komputerze nasłuchującym portu UDP/11111
  • uruchomił klienta OpenVPN na komputerze, podając XX.1XX.1X4.2XX:4398 dla połączenia
  • w dowolnym momencie uruchomiłem klienta OpenVPN na smartfonie wskazując adres IP i port (w moim przypadku adres IP się nie zmienił) aby się połączyć

Uruchamianie serwera VPN za NAT dostawcy
W ten sposób mogłem połączyć się z komputerem ze smartfona. Ta implementacja pozwala na podłączenie dowolnego klienta OpenVPN.

Praktyka

Potrzebne będą:

# apt install openvpn stun-client sendemail

Po napisaniu kilku skryptów, kilku plików konfiguracyjnych i wygenerowaniu niezbędnych certyfikatów (ponieważ klient na smartfonie działa tylko z certyfikatami), otrzymaliśmy zwykłą implementację serwera OpenVPN.

Główny skrypt na komputerze

# 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

Skrypt do wysyłania danych e-mailem:

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

Plik konfiguracyjny serwera:

# 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

Plik konfiguracyjny klienta:

# 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

Certyfikaty zostały wygenerowane przy użyciu ten artykuł.
Uruchamianie skryptu:

# ./vpn11.sh

Najpierw czyniąc go wykonywalnym

# chmod +x vpn11.sh

Po stronie smartfona

Instalując aplikację OpenVPN na Androida, po skopiowaniu pliku konfiguracyjnego, certyfikatów i skonfigurowaniu go, wyszło tak:
Sprawdzam pocztę na smartfonieUruchamianie serwera VPN za NAT dostawcy
Edytuję numer portu w ustawieniachUruchamianie serwera VPN za NAT dostawcy
Uruchamiam klienta i łączę sięUruchamianie serwera VPN za NAT dostawcy

Pisząc ten artykuł przeniosłem konfigurację z komputera na Raspberry Pi 3 i próbowałem uruchomić całość na modemie LTE, ale nie udało się! Wynik polecenia

# stun stun.ekiga.net -p 11111

Wersja klienta STUN 0.97
Podstawowy: Niezależne mapowanie, filtr zależny od portu, losowy port, spinka do włosów
Wartość zwracana to 0x000006

значение Filtr zależny od portu nie pozwolił na uruchomienie systemu.
Ale dostawca domowy pozwolił na uruchomienie systemu na Raspberry Pi 3 bez żadnych problemów.
W połączeniu z kamerą internetową, z VLC dla
tworzenie strumienia RTSP z kamery internetowej

$ 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 na smartfonie do przeglądania (strumień rtsp://10.2.0.1:8554/), okazał się dobrym systemem zdalnego nadzoru wideo, można także zainstalować Sambę, kierować ruch przez VPN, zdalnie sterować komputerem i wiele więcej więcej...

Wniosek

Jak pokazała praktyka, aby zorganizować serwer VPN, można obejść się bez zewnętrznego adresu IP, za który trzeba płacić, podobnie jak w przypadku wynajmowanego VPS/VDS. Ale wszystko zależy od dostawcy. Oczywiście chciałem uzyskać więcej informacji na temat różnych dostawców i typów używanych NAT, ale to dopiero początek...
Dziękuję za uwagę!

Źródło: www.habr.com

Dodaj komentarz