Esecuzione di un server VPN dietro il NAT del provider

Un articolo su come sono riuscito a gestire un server VPN dietro il NAT del mio provider di casa (senza indirizzo IP bianco). Vorrei fare subito una prenotazione: quello le prestazioni di questa implementazione dipendono direttamente dal tipo di NAT utilizzato dal tuo provider, nonché dal router.
Quindi, dovevo connettermi dal mio smartphone Android al mio computer di casa, entrambi i dispositivi sono connessi a Internet tramite provider NAT, inoltre il computer è collegato tramite un router domestico, che è anche connessioni NAT.
Lo schema classico che utilizza un VPS/VDS noleggiato con un indirizzo IP bianco, nonché il noleggio di un indirizzo IP bianco da un provider, non è stato preso in considerazione per diversi motivi.
In vista di esperienza dagli articoli precedenti, avendo condotto diversi esperimenti con STUN e NAT di fornitori. Ho deciso di fare un piccolo esperimento eseguendo il comando su un router domestico con firmware OpenWRT:

$ stun stun.sipnet.ru

ottenuto il risultato:

Versione client STUN 0.97
Primario: mappatura indipendente, filtro indipendente, porta casuale, tornante
Il valore restituito è 0x000002

Traduzione letterale:
Mappatura indipendente: mappatura indipendente
Filtro indipendente: filtro indipendente
porta casuale - porta casuale
sarà una forcina - ci sarà una forcina
Eseguendo un comando simile sul mio PC, ho ottenuto:

Versione client STUN 0.97
Primario: mappatura indipendente, filtro dipendente dalla porta, porta casuale, tornante
Il valore restituito è 0x000006

Filtro dipendente dalla porta: filtro dipendente dalla porta
La differenza nei risultati dell'output del comando indicava che il router domestico stava dando il "suo contributo" al processo di trasmissione dei pacchetti da Internet; ciò si manifestava nel fatto che durante l'esecuzione del comando sul computer:

stun stun.sipnet.ru -p 11111 -v

Stavo ottenendo il risultato:

...
Indirizzo mappato = XX.1XX.1X4.2XX:4398
...

in questo momento è stata aperta una sessione UDP da qualche tempo, se in questo momento invii una richiesta UDP (ad esempio: netcat XX.1XX.1X4.2XX 4398 -u), la richiesta è arrivata al router di casa, che è stato confermato da TCPDump in esecuzione su di esso, ma la richiesta non ha raggiunto il computer: IPtables, come traduttore NAT sul router, l'ha eliminata.
Esecuzione di un server VPN dietro il NAT del provider
Ma il fatto stesso che la richiesta UDP sia passata attraverso il NAT del provider ha dato speranza di successo. Poiché il router si trova nella 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 potuto avviare una sessione UDP e ricevere richieste da Internet da qualsiasi indirizzo IP. In questo momento, ho avviato il server OpenVPN (avendolo precedentemente configurato) ascoltando la porta UDP/11111, ho indicato l'indirizzo IP esterno e la porta (XX.1XX.1X4.2XX:4398) sullo smartphone e mi sono connesso con successo dallo smartphone a il computer. Ma in questa implementazione è sorto un problema: era necessario in qualche modo mantenere la sessione UDP finché il client OpenVPN non si connetteva al server; non mi piaceva l'opzione di avviare periodicamente il client STUN - non volevo sprecare il carico su i server STUN.
Ho notato anche la voce “sarà una forcina - ci sarà una forcina", questa modalità

L'hairpinning consente a una macchina su una rete locale dietro un NAT di accedere a un'altra macchina sulla stessa rete all'indirizzo esterno del router.

Esecuzione di un server VPN dietro il NAT del provider
Di conseguenza, ho semplicemente risolto il problema del mantenimento della sessione UDP: ho avviato il client sullo stesso computer con il server.
Ha funzionato così:

  • lanciato il client STUN sulla porta locale 11111
  • ha ricevuto una risposta con un indirizzo IP esterno e una porta XX.1XX.1X4.2XX:4398
  • dati inviati con un indirizzo IP esterno e una porta per l'e-mail (è possibile qualsiasi altro servizio) configurati sullo smartphone
  • ha avviato il server OpenVPN su un computer in ascolto sulla porta UDP/11111
  • avviato il client OpenVPN sul computer specificando XX.1XX.1X4.2XX:4398 per connettersi
  • in ogni momento avviate il client OpenVPN sullo smartphone indicando l'indirizzo IP e la porta (nel mio caso l'indirizzo IP non è cambiato) per connettervi

Esecuzione di un server VPN dietro il NAT del provider
In questo modo ho potuto connettermi al mio computer dal mio smartphone. Questa implementazione ti consente di connettere qualsiasi client OpenVPN.

Pratica

Avrete bisogno di:

# apt install openvpn stun-client sendemail

Dopo aver scritto un paio di script, un paio di file di configurazione e generato i certificati necessari (poiché il client su uno smartphone funziona solo con certificati), abbiamo ottenuto la consueta 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 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 cliente:

# 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

I certificati sono stati generati utilizzando questo articolo.
Esecuzione dello script:

# ./vpn11.sh

Rendendolo prima eseguibile

# chmod +x vpn11.sh

Lato smartphone

Installando l'applicazione OpenVPN per Android, dopo aver copiato il file di configurazione, i certificati e averlo configurato, è risultato così:
Controllo la posta elettronica sullo smartphoneEsecuzione di un server VPN dietro il NAT del provider
Modifico il numero di porta nelle impostazioniEsecuzione di un server VPN dietro il NAT del provider
Lancio il client e mi connettoEsecuzione di un server VPN dietro il NAT del provider

Mentre scrivevo questo articolo, ho trasferito la configurazione dal mio computer al Raspberry Pi 3 e ho provato a eseguire il tutto su un modem LTE, ma non ha funzionato! Risultato del comando

# stun stun.ekiga.net -p 11111

Versione client STUN 0.97
Primario: mappatura indipendente, filtro dipendente dalla porta, porta casuale, tornante
Il valore restituito è 0x000006

значение Filtro dipendente dalla porta non ha consentito l'avvio del sistema.
Ma il provider locale ha consentito l'avvio del sistema sul Raspberry Pi 3 senza problemi.
In combinazione con una webcam, con VLC per
creando un flusso RTSP da una 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 su uno smartphone per la visualizzazione (stream rtsp://10.2.0.1:8554/), si è rivelato un buon sistema di videosorveglianza remota, puoi anche installare Samba, instradare il traffico tramite VPN, controllare da remoto il tuo computer e molto altro ancora Di più...

conclusione

Come ha dimostrato la pratica, per organizzare un server VPN si può fare a meno di un indirizzo IP esterno, per il quale è necessario pagare, proprio come con un VPS/VDS noleggiato. Ma tutto dipende dal fornitore. Naturalmente volevo avere maggiori informazioni sui diversi provider e sui tipi di NAT utilizzati, ma questo è solo l'inizio...
Grazie!

Fonte: habr.com

Aggiungi un commento