Spuštění VPN serveru za NAT poskytovatele

Článek o tom, jak se mi podařilo spustit VPN server za NATem domácího poskytovatele (bez veřejné IP adresy). Hned na úvod podotýkám, že funkčnost tohoto řešení závisí přímo na typu NAT, který používá váš poskytovatel a také router.
Takže jsem potřeboval připojit svůj smartphone Android k domácímu počítači, oba zařízení jsou připojena k internetu přes poskytovatelské NAT, navíc je počítač připojen přes domácí router, který také NATil spojení.
Klasická schéma s použitím pronajatého VPS/VDS s veřejnou IP adresou, stejně jako pronájem veřejné IP adresy od poskytovatele, nebylo z důvodu několika příčin zvažováno.
S ohledem na zkušenosti z předchozích článků, po několika experimentech se STUN a NAT různých poskytovatelů. Rozhodl jsem se pro malý experiment a provedl jsem příkaz na domácím routeru běžící na firmware OpenWRT:

$ stun stun.sipnet.ru

dostal jsem výsledek:

STUN client verze 0.97
Primary: Independent Mapping, Independent Filter, random port, will hairpin
Návratová hodnota je 0x000002

Doslovný překlad:
Independent Mapping — nezávislé mapování
Independent Filter — nezávislý filtr
random port — náhodný port
will hairpin — dojde k zpětnému spojení
Prováděním podobného příkazu na svém PC jsem obdržel:

STUN client verze 0.97
Primární: Nezávislé mapování, filtrování podle portu, náhodný port, bude hairpin
Návratová hodnota je 0x000006

Port Dependent Filter — filtr závislý na portu
Rozdíl v výsledcích výstupu příkazů ukazoval na to, že domácí router přispíval „svou měrou“ do procesu překladu paketů z internetu, což se projevovalo tím, že při provádění příkazu na počítači:

stun stun.sipnet.ru -p 11111 -v

jsem dostal výsledek:

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

v tomto okamžiku se na chvilku otevřela UDP relace; pokud v tomto okamžiku pošlu UDP požadavek (například: netcat XX.1XX.1X4.2XX 4398 -u), požadavek dorazil na domácí router, což potvrdil TCPDump spuštěný na něm, ale požadavek nedorazil k počítači — IPtables na routeru jako NAT translator jej zablokoval.
Spuštění VPN serveru za NAT poskytovatele
Ale samotný fakt, že UDP požadavek prošel poskytovatelským NAT, dával naději na úspěch. Vzhledem k tomu, že router je v mé jurisdikci, vyřešil jsem problém přesměrováním UDP/11111 portu na počítač:

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

Tím jsem získal možnost iniciovat UDP relaci a přijímat dotazy z internetu z jakékoli IP adresy. V tu chvíli jsem spustil OpenVPN server (předem nakonfigurovaný), který naslouchal na portu UDP/11111, zadal jsem na smartphonu externí IP adresu a port (XX.1XX.1X4.2XX:4398) a úspěšně se připojil ze smartphonu k počítači. Ale v této implementaci vznikl problém, bylo třeba nějakým způsobem udržovat UDP relaci do doby připojení OpenVPN klienta k serveru, varianta s periodickým spuštěním STUN klienta se mi nelíbila – nechtěl jsem zbytečně zatěžovat STUN servery.
Také jsem si všiml záznamu „will hairpin — dojde k zpětnému spojení„, tento režim

Hairpinning umožňuje jednomu počítači v lokální síti za NAT přistupovat k jinému počítači ve stejné síti prostřednictvím externí adresy routeru.

Spuštění VPN serveru za NAT poskytovatele
Nakonec jsem problém s udržováním UDP relace vyřešil jednoduše – spustil jsem klienta na tomto stejném počítači se serverem.
Pracovalo to takto:

  • spustil jsem STUN klienta s lokálním portem 11111
  • dostal jsem odpověď s externí IP adresou a portem XX.1XX.1X4.2XX:4398
  • odesílal jsem data s externí IP adresou a portem na email (možná jakoukoli jinou službu), nastavenou na smartphonu
  • spustil jsem OpenVPN server na počítači s nasloucháním na portu UDP/11111
  • spustil jsem OpenVPN klienta na počítači se zadáním XX.1XX.1X4.2XX:4398 pro připojení
  • v jakoukoli dobu jsem spustil OpenVPN klienta na smartphonu se zadáním IP adresy a portu (v mém případě se IP adresa neměnila) pro připojení

Spuštění VPN serveru za NAT poskytovatele
Tím jsem získal možnost připojit se ke svému počítači ze smartphonu. Tato implementace umožňuje připojení jakéhokoli OpenVPN klienta.

Praxe

Bude potřeba:

# apt install openvpn stun-client sendemail

Napsáním několika skriptů, pár konfiguračních souborů, generováním potřebných certifikátů (protože klient na smartphonu funguje pouze se certifikáty) jsem vytvořil běžnou implementaci OpenVPN serveru.

Hlavní skript na počítači

# 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

Skript pro odesílání dat na 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"

Konfigurační soubor serveru:

# 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

Konfigurační soubor klienta:

# cat client.conf
klient
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

Generování certifikátů probíhalo podle tomto článku.
Spuštění skriptu:

# ./vpn11.sh

Nejprve jsem ho učinil spustitelným

# chmod +x vpn11.sh

Na straně smartphonu

Nainstaloval jsem aplikaci OpenVPN pro Android, zkopírováním konfiguračního souboru, certifikátů a jeho nastavením, to dopadlo takto:
Na smartphonu kontroluji e-mailSpuštění VPN serveru za NAT poskytovatele
Opravuji číslo portu v nastaveníSpuštění VPN serveru za NAT poskytovatele
Spouštím klienta a připojuji seSpuštění VPN serveru za NAT poskytovatele

Během psaní článku jsem přenesl konfiguraci z počítače na Raspberry Pi 3 a zkusil spustit všechno na LTE modemu, ale nepodařilo se! Výsledek příkazu

# stun stun.ekiga.net -p 11111

STUN client verze 0.97
Primární: Nezávislé mapování, filtrování podle portu, náhodný port, bude hairpin
Návratová hodnota je 0x000006

hodnotu Port Dependent Filter neumožnilo systému spustit se.
Ale domácí poskytovatel bez problémů umožnil systému spustit se na Raspberry Pi 3.
V kombinaci s webovou kamerou, s VLC pro
vytvoření RTSP streamu z webové kamery

$ 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

a VLC na smartphonu pro sledování (stream rtsp:\/\/10.2.0.1:8554\/), vybudoval se slušný systém pro dozor na dálku, také je možné zvednout Samba, směrovat provoz přes VPN, vzdáleně ovládat počítač a mnoho dalšího…

Výstup

Jak ukázala praxe, pro organizaci VPN serveru se dá obejít i bez veřejné IP adresy, za kterou se musí platit, stejně jako za pronajímanou dedikované servery. Ale všechno závisí na poskytovateli. Samozřejmě jsem chtěl získat více informací o různých poskytovatelích a typech používaných NAT, ale to je zatím jen začátek...
Děkujeme za pozornost!

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster