Starten eines VPN-Servers hinter dem NAT eines Anbieters

Ein Artikel darüber, wie ich es geschafft habe, einen VPN-Server hinter dem NAT eines Heimanbieters zu betreiben (ohne weiße IP-Adresse). Lassen Sie mich Ihnen gleich sagen: Die Leistung dieser Implementierung hängt direkt von der Art des von Ihrem Provider verwendeten NAT sowie vom Router ab.
Ich musste also eine Verbindung von meinem Android-Smartphone zu meinem Heimcomputer herstellen. Beide Geräte sind über Provider-NATs mit dem Internet verbunden, und der Computer ist über einen Heimrouter verbunden, der auch NAT-Verbindungen herstellt.
Das klassische Schema mit einem geleasten VPS/VDS mit weißer IP-Adresse sowie dem Mieten einer weißen IP-Adresse vom Anbieter wurde aus mehreren Gründen nicht in Betracht gezogen.
Überlegen Erfahrungen aus vergangenen Artikeln, nachdem er mehrere Experimente mit STUNs und NATs von Anbietern durchgeführt hatte. Ich entschied mich für ein kleines Experiment, indem ich den Befehl auf einem Heimrouter mit OpenWRT-Firmware ausführte:

$ stun stun.sipnet.ru

habe das Ergebnis erhalten:

STUN-Client-Version 0.97
Primär: Unabhängige Zuordnung, unabhängiger Filter, zufälliger Port, Haarnadelkurve
Rückgabewert ist 0x000002

Wörtliche Übersetzung:
Unabhängige Zuordnung – unabhängige Anzeige
Unabhängiger Filter – unabhängiger Filter
Zufälliger Port – zufälliger Port
wird eine Haarnadelkurve - es wird eine Haarnadelkurve geben
Nachdem ich einen ähnlichen Befehl auf meinem PC ausgeführt hatte, bekam ich:

STUN-Client-Version 0.97
Primär: Unabhängige Zuordnung, portabhängiger Filter, zufälliger Port, Haarnadelkurve
Rückgabewert ist 0x000006

Portabhängiger Filter – portabhängiger Filter
Der Unterschied in den Ergebnissen der Befehlsausgabe deutete darauf hin, dass der Heimrouter „seinen Beitrag“ zum Prozess der Übertragung von Paketen aus dem Internet geleistet hat. Dies zeigte sich darin, dass bei der Ausführung des Befehls auf dem Computer:

stun stun.sipnet.ru -p 11111 -v

Ich habe das Ergebnis erhalten:

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

In diesem Moment wurde für eine Weile eine UDP-Sitzung geöffnet. Wenn in diesem Moment eine UDP-Anfrage gesendet wurde (zum Beispiel: netcat XX.1XX.1X4.2XX 4398 -u), dann kam die Anfrage an den Heimrouter, der war bestätigt durch darauf ausgeführtes TCPDump, aber die Anfrage erreichte den Computer nicht – IPtables als NAT-Übersetzer auf dem Router hat sie verworfen.
Starten eines VPN-Servers hinter dem NAT eines Anbieters
Aber allein die Tatsache, dass eine UDP-Anfrage über das NAT des Anbieters weitergeleitet wurde, gab Hoffnung auf Erfolg. Da der Router in meinem Zuständigkeitsbereich liegt, habe ich das Problem gelöst, indem ich den UDP/11111-Port auf den Computer umgeleitet habe:

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

Dadurch hatte ich die Möglichkeit, eine UDP-Sitzung zu starten und von jeder IP-Adresse Anfragen aus dem Internet zu empfangen. In diesem Moment habe ich den OpenVPN-Server gestartet (nachdem ich ihn konfiguriert hatte), den UDP/11111-Port abhörte, die externe IP-Adresse und den Port (XX.1XX.1X4.2XX:4398) auf dem Smartphone angegeben und erfolgreich eine Verbindung vom Smartphone zum hergestellt Computer. Bei dieser Implementierung trat jedoch ein Problem auf: Es war notwendig, die UDP-Sitzung irgendwie aufrechtzuerhalten, bis der OpenVPN-Client eine Verbindung zum Server herstellte. Die Option, den STUN-Client regelmäßig zu starten, gefiel mir nicht – ich wollte keine STUN-Server laden vergeblich.
Habe auch auf den Eintrag aufmerksam gemacht „wird eine Haarnadelkurve - es wird eine Haarnadelkurve geben", dieser Modus

Durch Hairpinning kann ein Computer in einem lokalen Netzwerk hinter NAT über die externe Adresse des Routers auf einen anderen Computer im selben Netzwerk zugreifen.

Starten eines VPN-Servers hinter dem NAT eines Anbieters
Dadurch habe ich das Problem der Aufrechterhaltung einer UDP-Sitzung einfach gelöst: Ich habe den Client auf demselben Computer wie den Server gestartet.
Es hat so funktioniert:

  • STUN-Client mit lokalem Port 11111 gestartet
  • Antwort mit externer IP-Adresse und Port XX.1XX.1X4.2XX:4398 erhalten
  • Senden Sie Daten mit einer externen IP-Adresse und einem auf dem Smartphone konfigurierten Port an die E-Mail (jeder andere Dienst ist möglich).
  • einen OpenVPN-Server auf einem Computer gestartet, der den UDP/11111-Port überwacht
  • hat einen OpenVPN-Client auf einem Computer gestartet und dabei XX.1XX.1X4.2XX:4398 angegeben, um eine Verbindung herzustellen
  • Ich habe jederzeit den OpenVPN-Client auf dem Smartphone gestartet und dabei die IP-Adresse und den Port (in meinem Fall hat sich die IP-Adresse nicht geändert) für die Verbindung angegeben

Starten eines VPN-Servers hinter dem NAT eines Anbieters
Dadurch hatte ich die Möglichkeit, von einem Smartphone aus eine Verbindung zu meinem Computer herzustellen. Mit dieser Implementierung können Sie jeden OpenVPN-Client verbinden.

Praxis

Sie benötigen:

# apt install openvpn stun-client sendemail

Nachdem wir ein paar Skripte und ein paar Konfigurationsdateien geschrieben und die notwendigen Zertifikate generiert hatten (da der Client auf dem Smartphone nur mit Zertifikaten funktioniert), bekamen wir die übliche Implementierung des OpenVPN-Servers.

Hauptskript auf dem 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

E-Mail-Versandskript:

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

Serverkonfigurationsdatei:

# 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

Client-Konfigurationsdatei:

# 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

Zertifikate wurden entsprechend erstellt Dieser Artikel.
Ausführen des Skripts:

# ./vpn11.sh

Zuerst ausführbar machen

# chmod +x vpn11.sh

Auf der Smartphone-Seite

Durch die Installation der Anwendung Öffnen Sie VPN für AndroidNachdem ich die Konfigurationsdatei und die Zertifikate kopiert und konfiguriert hatte, stellte sich Folgendes heraus:
E-Mails auf meinem Smartphone checkenStarten eines VPN-Servers hinter dem NAT eines Anbieters
Ich bearbeite die Portnummer in den EinstellungenStarten eines VPN-Servers hinter dem NAT eines Anbieters
Ich starte den Client und verbinde michStarten eines VPN-Servers hinter dem NAT eines Anbieters

Während ich den Artikel schrieb, habe ich die Konfiguration vom Computer auf den Raspberry Pi 3 übertragen und versucht, das Ganze auf einem LTE-Modem laufen zu lassen, aber es hat nicht funktioniert! Befehlsergebnis

# stun stun.ekiga.net -p 11111

STUN-Client-Version 0.97
Primär: Unabhängige Zuordnung, portabhängiger Filter, zufälliger Port, Haarnadelkurve
Rückgabewert ist 0x000006

Wert Portabhängiger Filter verhinderte den Systemstart.
Doch der heimische Anbieter ließ das System problemlos auf dem Raspberry Pi 3 laufen.
In Verbindung mit einer Webcam, mit VLC für
Erstellen eines RTSP-Streams von einer 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

und VLC auf einem Smartphone zum Ansehen (Stream rtsp://10.2.0.1:8554/), es stellte sich heraus, dass es sich um kein schlechtes Videoüberwachungssystem aus der Ferne handelt, Sie können auch Samba einrichten, den Datenverkehr über VPN weiterleiten und einen Computer fernsteuern und vieles mehr ...

Abschluss

Wie die Praxis gezeigt hat, können Sie für die Organisation eines VPN-Servers auf eine kostenpflichtige externe IP-Adresse sowie auf einen gemieteten VPS/VDS verzichten. Aber es hängt alles vom Anbieter ab. Natürlich wollte ich mehr Informationen über die verschiedenen Anbieter und Arten der verwendeten NATs erhalten, aber das ist nur der Anfang ...
Danke!

Source: habr.com

Kommentar hinzufügen