Avvio del server VPN dietro NAT del provider

Articolo su come sono riuscito a avviare server VPN dietro il NAT del provider domestico (senza indirizzo IP pubblico). Preciso fin da subito che la funzionalità di questa implementazione dipende direttamente dal tipo di NAT utilizzato dal tuo provider, così come dal router.
Quindi, avevo la necessità di connettermi dal mio smartphone Android al computer di casa, entrambi i dispositivi connessi a Internet tramite NAT del provider, inoltre il computer è collegato tramite un router domestico che anch'esso NAT-ta le connessioni.
La classica soluzione con l'uso di un VPS/VDS affittato con un indirizzo IP pubblico, nonché l'affitto di un indirizzo IP pubblico dal provider, non è stata considerata per vari motivi.
Tenendo conto dell'esperienza di articoli precedenti, dopo aver effettuato diversi esperimenti con STUN e NAT dei provider. Ho deciso di fare un piccolo esperimento, eseguendo il comando sul router domestico con firmware OpenWRT:

$ stun stun.sipnet.ru

ho ottenuto il risultato:

Versione del client STUN 0.97
Primario: Mapping Indipendente, Filtro Indipendente, porta casuale, sarà hairpin
Il valore di ritorno è 0x000002

Traduzione letterale:
Mapping Indipendente — mapping indipendente
Filtro Indipendente — filtro indipendente
porta casuale — porta casuale
sarà hairpin — sarà una pinza
Eseguendo un comando simile sul mio PC, ho ottenuto:

Versione del client STUN 0.97
Primario: Mappatura Indipendente, Filtro Dipendente dalla Porta, porta casuale, sarà hairpin
Il valore di ritorno è 0x000006

Filtro Dipendente dalla Porta — filtro dipendente dalla porta
La differenza nei risultati delle comandi indicava che il router domestico stava contribuendo al processo di traduzione dei pacchetti da Internet, manifestandosi nel fatto che, eseguendo il comando sul computer:

stun stun.sipnet.ru -p 11111 -v

ricevevo il risultato:


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

in quel momento si apriva temporaneamente una sessione UDP, e se in quel momento inviavo una richiesta UDP (ad esempio: netcat XX.1XX.1X4.2XX 4398 -u), la richiesta arrivava al router domestico, come confermato da TCPDump in esecuzione su di esso, ma la richiesta non arrivava al computer — IPtables, in qualità di traduttore NAT sul router, la bloccava.
Avvio di un server VPN dietro NAT del fornitore
Ma il fatto stesso che la richiesta UDP passasse attraverso il NAT del provider dava speranza di successo. Poiché il router è sotto la mia giurisdizione, ho risolto il problema reindirizzando la porta UDP/11111 al 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

In questo modo ho avuto la possibilità di avviare una sessione UDP e ricevere richieste da Internet da qualsiasi indirizzo IP. A questo punto ho avviato il server OpenVPN (dopo averlo configurato) ascoltando la porta UDP/11111, ho specificato sullo smartphone l'indirizzo IP esterno e la porta (XX.1XX.1X4.2XX:4398) e mi sono connesso con successo dal telefono al computer. Tuttavia, in questa implementazione è emerso un problema: era necessario mantenere la sessione UDP fino al momento in cui il client OpenVPN si connetteva al server. La soluzione di avviare periodicamente il client STUN non mi è piaciuta: non volevo sovraccaricare inutilmente i server STUN.
Ho anche notato la registrazione «sarà hairpin — sarà una pinza«, questa modalità

Hairpinning consente a un computer nella rete locale dietro NAT di accedere a un altro computer nella stessa rete tramite l'indirizzo esterno del router.

Avvio di un server VPN dietro NAT del fornitore
Alla fine, ho risolto il problema del mantenimento della sessione UDP semplicemente avviando il client sullo stesso computer del server.
Funzionava in questo modo:

  • lanciavo il client STUN con la porta locale 11111
  • ricevevo una risposta con l'indirizzo IP esterno e la porta XX.1XX.1X4.2XX:4398
  • inviavo i dati all'indirizzo IP esterno e alla porta tramite email (è possibile utilizzare qualsiasi altro servizio), configurato sullo smartphone.
  • ho avviato un server OpenVPN sul computer in ascolto sulla porta UDP/11111
  • ho avviato un client OpenVPN sul computer specificando XX.1XX.1X4.2XX:4398 per connettermi
  • ho eseguito il client OpenVPN sullo smartphone in qualsiasi momento specificando l'indirizzo IP e la porta (nel mio caso l'indirizzo IP non è cambiato) per la connessione

Avvio di un server VPN dietro NAT del fornitore
Così ho ottenuto la possibilità di collegarmi al mio computer dallo smartphone. Questa implementazione permette di connettere qualsiasi client OpenVPN.

Pratica

Occorrerà:

# apt install openvpn stun-client sendemail

Scrivendo alcuni script, alcuni file di configurazione, generando i certificati necessari (dato che il client sullo smartphone funziona solo con certificati) ho ottenuto una normale implementazione di un server OpenVPN.

Script principale sul 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 per inviare i dati via email:

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

File di configurazione del server:

# 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

File di configurazione del 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

La generazione dei certificati è stata eseguita per questo articolo.
Esecuzione dello script:

# ./vpn11.sh

Prima di renderlo eseguibile

# chmod +x vpn11.sh

Sul lato dello smartphone

Installando l'applicazione OpenVPN per Android, copiando il file di configurazione, i certificati e impostandolo, è riuscito a funzionare così:
Controllo la posta sullo smartphoneAvvio di un server VPN dietro NAT del fornitore
Modifico il numero di porta nelle impostazioniAvvio di un server VPN dietro NAT del fornitore
Avvio il client e mi connettoAvvio di un server VPN dietro NAT del fornitore

Durante la scrittura dell'articolo, ho trasferito la configurazione dal computer a un Raspberry Pi 3 e ho provato a eseguire tutto questo con un modem LTE, ma non ci sono riuscito! Risultato del comando

# stun stun.ekiga.net -p 11111

Versione del client STUN 0.97
Primario: Mappatura Indipendente, Filtro Dipendente dalla Porta, porta casuale, sarà hairpin
Il valore di ritorno è 0x000006

valore Filtro Dipendente dalla Porta non ha permesso al sistema di avviarsi.
Ma il provider domestico ha permesso senza problemi al sistema di avviarsi su Raspberry Pi 3.
Insieme alla webcam, con VLC per
creare uno stream RTSP dalla webcam

$ 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

e VLC sullo smartphone per la visione (streaming rtsp://10.2.0.1:8554/), è stata realizzata una buona sistema di videosorveglianza a distanza, si può anche configurare Samba, instradare il traffico tramite VPN, gestire il computer da remoto e molto altro ancora…

Risultato

Come ha dimostrato la pratica, per organizzare un server VPN si può fare a meno di un indirizzo IP pubblico per il quale è necessario pagare, così come per quello affittato. VPS/VDS. Ma tutto dipende dal fornitore. Certamente vorrei avere maggiori informazioni sui vari fornitori e sui tipi di NAT utilizzati, ma questo è solo l'inizio…
Grazie per l'attenzione!

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster