Avvio di un server VPN dietro il NAT del provider.

Articolo su come sono riuscito a avviare un server VPN dietro al NAT del provider domestico (senza indirizzo IP pubblico). Mi preme sottolineare che la funzionalità di questa implementazione dipende direttamente dal tipo di NAT utilizzato dal tuo provider, così come dal router.
Quindi, ho avuto la necessità di connettermi dal mio smartphone Android al computer di casa, entrambi i dispositivi sono collegati a Internet tramite NAT del provider, inoltre il computer è collegato tramite un router domestico che fa anch'esso NAT delle connessioni.
Non ho considerato lo schema classico con un VPS/VDS affittato con un indirizzo IP pubblico, così come l'affitto di un indirizzo IP pubblico dal provider, per vari motivi.
Tenendo conto dell'esperienza degli articoli precedenti, dopo aver effettuato alcuni esperimenti con STUN e NAT dei provider. Ho deciso di fare un piccolo esperimento, eseguendo il comando sul mio router di casa funzionante con il firmware OpenWRT:

$ stun stun.sipnet.ru

ho ottenuto il risultato:

STUN client version 0.97
Primary: Independent Mapping, Independent Filter, random port, will hairpin
Il valore di ritorno è 0x000002

Traduzione letterale:
Independent Mapping — mappatura indipendente
Independent Filter — filtro indipendente
random port — porta casuale
will hairpin — farà hairpin
Eseguendo un comando analogo sul mio PC, ho ottenuto:

STUN client version 0.97
Primary: Independent Mapping, Port Dependent Filter, random port, will hairpin
Il valore di ritorno è 0x000006

Port Dependent Filter — filtro dipendente dalla porta
La differenza nei risultati delle uscite dei comandi indicava che il router di casa stava apportando "un suo contributo" al processo di traslazione dei pacchetti da Internet, ciò si manifestava 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 per un breve periodo una sessione UDP; se in quel frangente inviavo una richiesta UDP (ad esempio: netcat XX.1XX.1X4.2XX 4398 -u), la richiesta arrivava al router di casa, come confermato da TCPDump in esecuzione su di esso, ma la richiesta non raggiungeva il computer — IPtables come traslatore NAT nel router la scartava.
Avvio di un server VPN dietro un NAT del provider
Ma il semplice fatto 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 il port 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 ottenuto la possibilità di avviare una sessione UDP e ricevere richieste da Internet da qualsiasi indirizzo IP. In quel momento ho avviato OpenVPN-server (configurato in precedenza) in ascolto della porta UDP/11111, ho indicato sull'app smartphone l'indirizzo IP esterno e la porta (XX.1XX.1X4.2XX:4398) e mi sono connesso con successo dallo smartphone al computer. Ma in questa implementazione si è presentato un problema: dovevo in qualche modo mantenere la sessione UDP fino al momento in cui il client OpenVPN si collegava al server; non mi è piaciuta l'idea di avviare periodicamente un client STUN - non volevo sovraccaricare inutilmente i server STUN.
Ho notato anche la registrazione «will hairpin — farà hairpin«, 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 un NAT del provider
Alla fine ho risolto il problema di mantenere la sessione UDP semplicemente avviando il client sullo stesso computer del server.
Funzionava così:

  • avviavo il client STUN sulla 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
  • avviavo il server OpenVPN sul computer in ascolto della porta UDP/11111
  • avviavo il client OpenVPN sul computer specificando XX.1XX.1X4.2XX:4398 per la connessione
  • in qualsiasi momento avviavo il client OpenVPN sullo smartphone specificando l'indirizzo IP e la porta (nel mio caso l'indirizzo IP non cambiava) per la connessione

Avvio di un server VPN dietro un NAT del provider
In questo modo ho ottenuto la possibilità di connettermi al mio computer dallo smartphone. Questa implementazione consente di collegare qualsiasi client OpenVPN.

Pratica

Occorrerà:

# apt install openvpn stun-client sendemail

Scrivendo un paio di script, un paio di file di configurazione, generando i certificati necessari (poiché il client sullo smartphone funziona solo con certificati) è stata realizzata una normale implementazione di un server OpenVPN.

Lo 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 l'invio di 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 effettuata secondo questo articolo.
Avvio dello script:

# ./vpn11.sh

Facendo prima in modo che sia eseguibile

# chmod +x vpn11.sh

Dalla parte dello smartphone

Installando l'applicazione OpenVPN per Android, copiando il file di configurazione, i certificati e configurandolo, si è ottenuto quanto segue:
Controllo la posta sullo smartphoneAvvio di un server VPN dietro un NAT del provider
Modifico il numero della porta nelle impostazioniAvvio di un server VPN dietro un NAT del provider
Avvio il client e mi connettoAvvio di un server VPN dietro un NAT del provider

Nel corso della stesura dell'articolo, ho trasferito la configurazione dal computer a Raspberry Pi 3 e ho provato a far partire tutto questo su un modem LTE, ma non sono riuscito! Risultato del comando

# stun stun.ekiga.net -p 11111

STUN client version 0.97
Primary: Independent Mapping, Port Dependent Filter, random port, will 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 l'avvio del sistema su Raspberry Pi 3.
Insieme alla webcam, con VLC per
creare un flusso 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 (flusso rtsp://10.2.0.1:8554/), è stato realizzato un buon sistema di videosorveglianza a distanza, è anche possibile attivare Samba, instradare il traffico attraverso VPN, gestire il computer a distanza e molto altro...

Conclusione

Come ha dimostrato la pratica, per organizzare un server VPN si può fare a meno anche di un indirizzo IP pubblico per il quale è necessario pagare, così come per l'affitto VPS/VDS. Ma tutto dipende dal provider. Certamente avrei voluto ottenere più informazioni sui vari provider 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