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.ruik 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 -vik 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.

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.XXXHierdoor 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.

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

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 sendemailDoor 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
doneScript 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.confproto 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 20Configuratiebestand van de client:
# cat client.confclient
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 30De certificaten werden gegenereerd volgens dit artikel.
Script starten:
# ./vpn11.shVoorafgaand aan het uitvoerbaar maken
# chmod +x vpn11.shAan 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-mail
Ik pas het poortnummer aan in de instellingen
Ik start de client en maak verbinding
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 11111STUN 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-keepen 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
