Članak o tome kako sam uspio pokrenuti VPN server iza NAT-a kućnog provajdera (bez bijele IP adrese). Odmah da ti kažem: performanse ove implementacije direktno zavise od tipa NAT-a koji koristi vaš provajder, kao i od rutera.
Dakle, imao sam potrebu da se povežem sa svog Android pametnog telefona na kućni računar, oba uređaja su povezana na Internet preko NAT-a provajdera, plus računar je povezan preko kućnog rutera, koji takođe ima NAT veze.
Klasična shema koja koristi iznajmljeni VPS/VDS sa bijelom IP adresom, kao i iznajmljivanje bijele IP adrese od provajdera, nije razmatrana iz nekoliko razloga.
Uzimajući u obzir
$ stun stun.sipnet.ru
dobio rezultat:
STUN klijent verzija 0.97
Primarni: Nezavisno mapiranje, Nezavisni filter, nasumični port, ukosnica
povratna vrijednost je 0x000002
Doslovni prijevod:
Independent Mapping - nezavisni prikaz
Nezavisni filter - nezavisni filter
random port - slučajni port
će ukosnica - bit će ukosnica
Nakon što sam pokrenuo sličnu komandu na svom računaru, dobio sam:
STUN klijent verzija 0.97
Primarno: Nezavisno mapiranje, Filter zavisan od porta, nasumični port, ukosnica
povratna vrijednost je 0x000006
Port Dependent Filter - filter ovisan o portu
Razlika u rezultatima izlaza komandi je ukazivala da je kućni ruter dao "svoj doprinos" procesu emitovanja paketa sa Interneta, to se manifestovalo u činjenici da kada je naredba izvršena na računaru:
stun stun.sipnet.ru -p 11111 -v
dobio sam rezultat:
...
Mapirana adresa = XX.1XX.1X4.2XX:4398
...
u tom trenutku je neko vreme otvorena UDP sesija, ako je u tom trenutku bio poslat UDP zahtev (na primer: netcat XX.1XX.1X4.2XX 4398 -u), onda je zahtev stigao na kućni ruter, koji je potvrđeno TCPDumpom koji je pokrenut na njemu, ali zahtjev nije stigao do računara - IPtables kao NAT prevodilac na ruteru ga je odbacio.
Ali sama činjenica prolaska UDP zahtjeva kroz NAT provajdera dala je nadu u uspjeh. Pošto je ruter u mojoj nadležnosti, problem sam riješio tako što sam UDP / 11111 port preusmjerio na računar:
iptables -t nat -A PREROUTING -i eth1 -p udp -d 10.1XX.2XX.XXX --dport 11111 -j DNAT --to-destination 192.168.X.XXX
Tako sam dobio priliku da iniciram UDP sesiju i primam zahteve sa Interneta sa bilo koje IP adrese. U ovom trenutku sam pokrenuo OpenVPN-server (nakon što sam ga konfigurisao) slušajući UDP/11111 port, pokazao eksternu IP adresu i port (XX.1XX.1X4.2XX:4398) na pametnom telefonu i uspešno se povezao sa pametnog telefona na kompjuter. Ali u ovoj implementaciji se pojavio problem, bilo je potrebno nekako održavati UDP sesiju dok se OpenVPN klijent ne poveže sa serverom, nije mi se svidjela opcija periodičnog pokretanja STUN klijenta - nisam htio učitavati STUN servere uzalud.
Takođe je skrenuo pažnju na unos "
Hairpinding omogućava jednoj mašini na lokalnoj mreži iza NAT-a da pristupi drugoj mašini na istoj mreži na eksternoj adresi rutera.
Kao rezultat toga, jednostavno sam riješio problem održavanja UDP sesije - pokrenuo sam klijenta na istom računaru sa serverom.
Funkcionisalo je ovako:
- pokrenut STUN klijent sa lokalnim portom 11111
- primljen odgovor sa eksternom IP adresom i portom XX.1XX.1X4.2XX:4398
- poslao podatke sa eksternom IP adresom i portom na mail (moguća je bilo koja druga usluga) konfigurisanim na pametnom telefonu
- pokrenuo OpenVPN server na računaru koji sluša UDP/11111 port
- pokrenuo OpenVPN klijent na računaru navodeći XX.1XX.1X4.2XX:4398 za povezivanje
- u svakom trenutku pokrenuo OpenVPN klijent na pametnom telefonu, navodeći IP adresu i port (u mom slučaju, IP adresa se nije promijenila) za povezivanje
Tako sam dobio priliku da se povežem sa svojim računarom sa pametnog telefona. Ova implementacija vam omogućava da povežete bilo koji OpenVPN klijent.
Praksa
Potrebno je:
# apt install openvpn stun-client sendemail
Nakon pisanja par skripti, par konfiguracionih fajlova, generisanja potrebnih sertifikata (pošto klijent na pametnom telefonu radi samo sa sertifikatima), dobili smo uobičajenu implementaciju OpenVPN servera.
Glavna skripta na računaru
# 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
Skripta za slanje e-pošte:
# 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"
Konfiguracijski fajl servera:
# 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
Konfiguracioni fajl klijenta:
# 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
Certifikati su generirani prema
Pokretanje skripte:
# ./vpn11.sh
Prvo ga učinite izvršnim
# chmod +x vpn11.sh
Na strani pametnog telefona
Instaliranjem aplikacije Otvorite VPN za Android, kopirajući konfiguracijski fajl, certifikate i konfigurirajući ga, ispalo je ovako:
Provjeravam e-poštu na mom pametnom telefonu
Uređujem broj porta u postavkama
Pokrećem klijenta i povezujem se
U procesu pisanja članka, prebacio sam konfiguraciju sa računara na Raspberry Pi 3 i pokušao sve pokrenuti na LTE modemu, ali nije išlo! rezultat komande
# stun stun.ekiga.net -p 11111
STUN klijent verzija 0.97
Primarno: Nezavisno mapiranje, Filter zavisan od porta, nasumični port, ukosnica
povratna vrijednost je 0x000006
značenje Filter zavisan od porta spriječilo pokretanje sistema.
Ali domaći provajder je pustio da sistem radi na Raspberry Pi 3 bez ikakvih problema.
U kombinaciji sa web kamerom, sa VLC za
kreiranje RTSP toka sa web kamere
$ 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
i VLC na pametnom telefonu za gledanje (stream rtsp://10.2.0.1:8554/), ispostavilo se da nije loš sistem video nadzora na daljinu, možete podesiti i Sambu, usmjeriti promet preko VPN-a, daljinski upravljati računarom i mnogo više ...
zaključak
Kao što je praksa pokazala, za organizaciju VPN servera možete bez eksterne IP adrese za koju morate platiti, kao i za iznajmljeni VPS / VDS. Ali sve zavisi od provajdera. Naravno, želio sam dobiti više informacija o različitim provajderima i tipovima NAT-ova koji se koriste, ali ovo je samo početak...
Spasibo za vnimanie!
izvor: www.habr.com