Een VPN-server draaien achter de NAT van de provider

Een artikel over hoe ik erin slaagde een VPN-server achter de NAT van mijn thuisprovider te laten draaien (zonder wit IP-adres). Laat ik meteen een reservering maken: dat de prestaties van deze implementatie zijn rechtstreeks afhankelijk van het type NAT dat door uw provider wordt gebruikt, evenals van de router.
Ik moest dus verbinding maken tussen mijn Android-smartphone en mijn thuiscomputer. Beide apparaten zijn verbonden met internet via NAT's van de provider, en de computer is verbonden via een thuisrouter, die ook NAT's verbindt.
Het klassieke plan waarbij gebruik werd gemaakt van een gehuurde VPS/VDS met een wit IP-adres en het huren van een wit IP-adres bij een provider, werd om verschillende redenen niet overwogen.
Rekening houdend met ervaring uit eerdere artikelen, nadat ik verschillende experimenten had uitgevoerd met STUN's en NAT's van providers. Ik besloot een klein experiment uit te voeren door de opdracht uit te voeren op een thuisrouter met OpenWRT-firmware:

$ stun stun.sipnet.ru

kreeg het resultaat:

STUN-clientversie 0.97
Primair: Onafhankelijke mapping, Onafhankelijk filter, willekeurige poort, zal hairpin zijn
Retourwaarde is 0x000002

Letterlijke vertaling:
Onafhankelijke mapping - onafhankelijke mapping
Onafhankelijk filter - onafhankelijk filter
willekeurige poort - willekeurige poort
zal haarspeld - er zal een haarspeld zijn
Als ik een soortgelijk commando op mijn pc uitvoerde, kreeg ik:

STUN-clientversie 0.97
Primair: Onafhankelijke mapping, poortafhankelijk filter, willekeurige poort, zal haarspeld worden
Retourwaarde is 0x000006

Poortafhankelijk filter - poortafhankelijk filter
Het verschil in de resultaten van de opdrachtuitvoer gaf aan dat de thuisrouter "zijn bijdrage" leverde aan het proces van het verzenden van pakketten vanaf internet; dit kwam tot uiting in het feit dat bij het uitvoeren van de opdracht op de computer:

stun stun.sipnet.ru -p 11111 -v

Ik kreeg het resultaat:

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

op dit moment is er enige tijd een UDP-sessie geopend, als u op dit moment een UDP-verzoek verzendt (bijvoorbeeld: netcat XX.1XX.1X4.2XX 4398 -u), dan kwam het verzoek naar de thuisrouter, die was bevestigd door TCPDump die erop draaide, maar het verzoek bereikte de computer niet - IPtables, als NAT-vertaler op de router, liet het vallen.
Een VPN-server draaien achter de NAT van de provider
Maar juist het feit dat het UDP-verzoek via de NAT van de provider ging, gaf hoop op succes. Omdat de router zich in mijn rechtsgebied bevindt, heb ik het probleem opgelost door de UDP/11111-poort om te leiden naar de 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

Zo kon ik een UDP-sessie starten en vanaf elk IP-adres verzoeken van internet ontvangen. Op dit moment lanceerde ik de OpenVPN-server (nadat ik deze eerder had geconfigureerd), luisterend naar de UDP/11111-poort, gaf ik het externe IP-adres en de poort (XX.1XX.1X4.2XX:4398) op de smartphone aan en maakte met succes verbinding vanaf de smartphone met de computer. Maar bij deze implementatie deed zich een probleem voor: het was nodig om op de een of andere manier de UDP-sessie in stand te houden totdat de OpenVPN-client verbinding maakte met de server; ik hield niet van de optie om periodiek de STUN-client te starten - ik wilde de last niet verspillen aan de STUN-servers.
Ik zag ook de vermelding “zal haarspeld - er zal een haarspeld zijn", deze modus

Met hairpinning kan één machine op een lokaal netwerk achter een NAT toegang krijgen tot een andere machine op hetzelfde netwerk op het externe adres van de router.

Een VPN-server draaien achter de NAT van de provider
Als gevolg hiervan heb ik eenvoudigweg het probleem van het onderhouden van een UDP-sessie opgelost: ik heb de client op dezelfde computer als de server gestart.
Het werkte als volgt:

  • lanceerde de STUN-client op lokale poort 11111
  • een antwoord ontvangen met een extern IP-adres en poort XX.1XX.1X4.2XX:4398
  • verzonden gegevens met een extern IP-adres en poort naar e-mail (elke andere dienst is mogelijk) geconfigureerd op de smartphone
  • lanceerde de OpenVPN-server op een computer die naar de UDP/11111-poort luisterde
  • lanceerde de OpenVPN-client op de computer en specificeerde XX.1XX.1X4.2XX:4398 om verbinding te maken
  • lanceerde op elk moment de OpenVPN-client op de smartphone met vermelding van het IP-adres en de poort (in mijn geval veranderde het IP-adres niet) om verbinding te maken

Een VPN-server draaien achter de NAT van de provider
Op deze manier kon ik vanaf mijn smartphone verbinding maken met mijn computer. Met deze implementatie kunt u verbinding maken met elke OpenVPN-client.

Praktijk

Je hebt nodig:

# apt install openvpn stun-client sendemail

Nadat we een paar scripts en een paar configuratiebestanden hadden geschreven en de nodige certificaten hadden gegenereerd (aangezien de client op een smartphone alleen met certificaten werkt), kregen we de gebruikelijke implementatie van een OpenVPN-server.

Hoofdscript op de 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 voor het verzenden van gegevens per e-mail:

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

Serverconfiguratiebestand:

# 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

Clientconfiguratiebestand:

# 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

Certificaten zijn gegenereerd met behulp van dit artikel.
Het script uitvoeren:

# ./vpn11.sh

Door het eerst uitvoerbaar te maken

# chmod +x vpn11.sh

Aan de smartphonekant

Door de applicatie te installeren OpenVPN voor Android, nadat ik het configuratiebestand en de certificaten had gekopieerd en geconfigureerd, bleek het als volgt:
Ik check mijn e-mail op mijn smartphoneEen VPN-server draaien achter de NAT van de provider
Ik bewerk het poortnummer in de instellingenEen VPN-server draaien achter de NAT van de provider
Ik start de client en maak verbindingEen VPN-server draaien achter de NAT van de provider

Terwijl ik dit artikel schreef, heb ik de configuratie van mijn computer naar de Raspberry Pi 3 overgebracht en geprobeerd het geheel op een LTE-modem te laten draaien, maar het werkte niet! Resultaat opdracht

# stun stun.ekiga.net -p 11111

STUN-clientversie 0.97
Primair: Onafhankelijke mapping, poortafhankelijk filter, willekeurige poort, zal haarspeld worden
Retourwaarde is 0x000006

betekenis Poortafhankelijk filter liet het systeem niet opstarten.
Maar de thuisprovider liet het systeem zonder problemen opstarten op de Raspberry Pi 3.
In combinatie met een webcam, met VLC voor
een RTSP-stream maken vanaf een 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

en VLC op een smartphone om te bekijken (stream rtsp://10.2.0.1:8554/), het bleek een goed videobewakingssysteem op afstand, je kunt ook Samba installeren, verkeer via VPN routeren, je computer op afstand bedienen en nog veel meer meer...

Uitgang

Zoals de praktijk heeft geleerd, kun je voor het organiseren van een VPN-server het doen zonder een extern IP-adres waarvoor je moet betalen, net als voor een gehuurde VPS/VDS. Maar het hangt allemaal af van de aanbieder. Natuurlijk wilde ik meer informatie krijgen over de verschillende providers en gebruikte typen NAT's, maar dit is nog maar het begin...
Dank je wel!

Bron: www.habr.com

Voeg een reactie