Het opstarten van een VPN-server achter provider NAT

Een artikel over hoe ik het heb weten te laten werken VPN-server achter de NAT van mijn internetprovider (zonder wit IP-adres). Ik wil meteen zeggen dat de werkbaarheid van deze implementatie sterk afhankelijk is van het type NAT dat door uw provider wordt gebruikt, evenals de router..
Dus, ik had de noodzaak om vanaf mijn Android-smartphone verbinding te maken met mijn thuiscomputer, beide apparaten zijn via de NAT van de provider met het internet verbonden, bovendien is de computer aangesloten via een thuisrouter, die ook de verbindingen NAT'te.
De klassieke optie met een gehuurde VPS/VDS met een wit IP-adres, evenals het huren van een wit IP-adres van de provider, werd om verschillende redenen niet overwogen.
Gezien ervaring uit eerdere artikelen, na verschillende experimenten met STUN en de NAT van de providers. Ik besloot om een klein experiment uit te voeren door het commando uit te voeren op de thuisrouter die draait op de OpenWRT-firmware:

$ stun stun.sipnet.ru

ik kreeg het resultaat:

STUN client versie 0.97
Primair: Onafhankelijke mapping, Onafhankelijk filter, willekeurige poort, zal hairpin
De teruggegeven waarde is 0x000002

Letterlijke vertaling:
Onafhankelijke mapping — onafhankelijke mapping
Onafhankelijk filter — onafhankelijk filter
willekeurige poort — willekeurige poort
zal hairpin — zal hairpin
Door een soortgelijk commando op mijn PC uit te voeren, kreeg ik:

STUN client versie 0.97
Primair: Onafhankelijke mapping, poortafhankelijke filter, willekeurige poort, zal hairpin
De teruggegeven waarde is 0x000006

Poortafhankelijke filter — poortafhankelijk filter
Het verschil in de resultaten van de commando-uitvoer gaf aan dat de thuisrouter 'zijn bijdrage' leverde aan het proces van het vertalen van pakketten vanuit het internet, dit manifesteerde zich in het feit dat bij het uitvoeren van het commando op de computer:

stun stun.sipnet.ru -p 11111 -v

ik kreeg het resultaat:

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

op dit moment werd er tijdelijk een UDP-sessie geopend, als je op dat moment een UDP-verzoek verstuurde (bijvoorbeeld: netcat XX.1XX.1X4.2XX 4398 -u), kwam het verzoek op de thuisrouter aan, wat werd bevestigd door TCPDump dat daar werd uitgevoerd, maar het verzoek bereikte de computer niet — IPtables als NAT-vertaler op de router dropten het.
VPN-server starten achter de NAT van de provider
Maar het feit dat het UDP-verzoek door de NAT van de provider ging, gaf hoop op succes. Aangezien de router onder mijn jurisdictie valt, loste ik het probleem op door de UDP/11111-poort naar de computer om te leiden:

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

Hierdoor kreeg ik de mogelijkheid om een UDP-sessie te initiëren en verzoeken uit het internet te ontvangen vanaf elk IP-adres. Op dat moment startte ik de OpenVPN-server (vooraf geconfigureerd) die luisterde op UDP/11111 poort, ik gaf op mijn smartphone het externe IP-adres en poort (XX.1XX.1X4.2XX:4398) op en kon succesvol verbinding maken van mijn smartphone met de computer. Maar in deze implementatie deed zich een probleem voor: ik moest de UDP-sessie in stand houden tot het moment dat de OpenVPN-client verbinding maakte met de server. De optie om periodiek de STUN-client te starten beviel me niet - ik wilde de STUN-servers niet onnodig belasten.
Ik merkte ook de opname «zal hairpin — zal hairpin«, deze modus

Hairpinning stelt één machine in een lokaal netwerk achter NAT in staat toegang te krijgen tot een andere machine in hetzelfde netwerk via het externe adres van de router.

VPN-server starten achter de NAT van de provider
Uiteindelijk loste ik het probleem van het in stand houden van de UDP-sessie eenvoudig op - ik startte de client op dezelfde computer als de server.
Het werkte als volgt:

  • ik startte de STUN-client met lokale poort 11111
  • ik ontving een antwoord met het externe IP-adres en poort XX.1XX.1X4.2XX:4398
  • ik stuurde gegevens met het externe IP-adres en poort naar de e-mail (elke andere service is mogelijk) die was ingesteld op de smartphone
  • ik startte de OpenVPN-server op de computer met het luisteren op UDP/11111 poort
  • ik startte de OpenVPN-client op de computer met de opgave van XX.1XX.1X4.2XX:4398 voor verbinding
  • ik startte op elk moment de OpenVPN-client op de smartphone met de opgave van het IP-adres en de poort (in mijn geval veranderde het IP-adres niet) voor verbinding

VPN-server starten achter de NAT van de provider
Zo kreeg ik de mogelijkheid om verbinding te maken met mijn computer vanaf mijn smartphone. Deze implementatie stelt elke OpenVPN-client in staat om verbinding te maken.

Praktijk

Benodigheden:

# apt install openvpn stun-client sendemail

Door een paar scripts en configuratiebestanden te schrijven, en de noodzakelijke certificaten te genereren (aangezien de client op de smartphone alleen werkt met certificaten) kreeg ik een standaardimplementatie van de 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 naar 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"

Configuratiebestand van de 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

Configuratiebestand van de 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

De certificaten werden gegenereerd volgens dit artikel.
Script starten:

# ./vpn11.sh

Voorafgaand aan het uitvoerbaar maken

# chmod +x vpn11.sh

Aan de smartphonezijde

De app geïnstalleerd OpenVPN voor Android, de configuratiebestanden, certificaten gekopieerd en ingesteld, kreeg ik het volgende:
Op de smartphone controleer ik de e-mailVPN-server starten achter de NAT van de provider
Ik pas het poortnummer aan in de instellingenVPN-server starten achter de NAT van de provider
Ik start de client en maak verbindingVPN-server starten achter de NAT van de provider

Tijdens het schrijven van het artikel heb ik de configuratie van de computer naar de Raspberry Pi 3 overgezet en geprobeerd dit alles op een LTE-modem te starten, maar dat lukte niet! Het resultaat van de opdracht

# stun stun.ekiga.net -p 11111

STUN client versie 0.97
Primair: Onafhankelijke mapping, poortafhankelijke filter, willekeurige poort, zal hairpin
De teruggegeven waarde is 0x000006

de waarde Poortafhankelijke filter deed het systeem niet opstarten.
Maar de thuisprovider liet het systeem probleemloos draaien op de Raspberry Pi 3.
In combinatie met de webcam, met VLC voor
het creëren van een RTSP-stream met de 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 de smartphone om te kijken (stream rtsp://10.2.0.1:8554/), kreeg ik een redelijk goed surveillance-systeem op afstand, ik kan ook Samba opzetten, verkeer via VPN routeren, de computer op afstand beheren en nog veel meer...

Uitslag

Zoals de praktijk heeft aangetoond, kun je voor het organiseren van een VPN-server ook zonder extern IP-adres, waarvoor je moet betalen, het is ook hetzelfde voor de gehuurde. VPS/VDS. Maar het hangt allemaal van de provider af. Natuurlijk zou ik meer informatie willen hebben over verschillende providers en de soorten gebruikte NAT, maar dit is pas het begin...
Bedankt voor uw aandacht!

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster