Tere päevast!
Selles artiklis tahan rääkida, kuidas ma rakendasin () Bash skripti kahe arvuti ühendamiseks, mis asuvad NAT-i taga, kasutades UDP hole punching tehnoloogiat Ubuntu/Debiani operatsioonisüsteemi näitel.
Ühenduse loomine koosneb mitmest etapist:
- Node käivitamine ja kaugkiibi valmiduse ootamine;
- Väline IP-aadress ja UDP-port määramine;
- Välist IP-aadressi ja UDP-porti edastamine kaugkiibile;
- Väline IP-aadress ja UDP-port kaugkiibilt vastuvõtmine;
- IPIP-tunneli loomine;
- Ühenduse jälgimine;
- Ühenduse katkestamise korral IPIP tunneli eemaldamine.
Mõtlesin kaua ja mõtlen endiselt, mida kasutada sõnumite vahetamiseks node'ide vahel, praegu tundub mulle kõige lihtsam ja kiirem variandina kasutada Yandex.Disc.
- Esiteks, see on kasutamislihtsus — vajate kolme toimingut: loomine, lugemine, kustutamine. Curl'i abil on see:
Loo:curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folderLoe:
curl -s --user "$usename:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$folderKusta:
curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder - Teiseks, see on lihtne seadistada:
apt install curl
Välise IP-aadressi ja UDP-pordi määramiseks kasutage stun-client käsku:
stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress"Installimine käsuga:
apt install stun-clientTunnelite korraldamiseks kasutatakse operatsioonisüsteemi standardilisi tööriistu paketist iproute2. On olemas mida saab üles tõsta standardsete tööriistadega (L2TPv3, GRE jne), aga valisin IPIP, kuna see tekitab süsteemile minimaalselt lisakoormust. Olen proovinud L2TPv3 UDP peal ja pettunud, kiirus langes kümme korda, kuid see võib olla seotud pakkumise või millegi muuga. Kuna IPIP-tunnel töötab IP-tasandil, kasutatakse UDP-portide tasandil töötamiseks FOU-tunnelit. IPIP-tunneli loomiseks on vaja:
— laadida FOU moodul:
modprobe fou— kuulata kohalikku porti:
ip fou add port $localport ipproto 4— luua tunnel:
ip link add name fou$name type ipip remote $remoteip local $localip encap fou encap-sport $localport encap-dport $remoteport— tõsta tunnelite ühendus üles:
ip link set up dev fou$name— määrata tunneli sisemine kohaliku ja kaug-IP-aadress:
ip addr add $intIP peer $peerip dev fou$nameTunnel kustutatakse:
ip link del dev fou$nameip fou del port $localportTunnel'i seisundi jälgimine toimub perioodilise pingiga kauguspunkti tunnel'i sisemise IP-aadressi abil, käsuga:
ping -c 1 $peerip -s 0Perioodiline ping on vajalik eelkõige kanali säilitamiseks, vastasel juhul võivad marsruutijates NAT-tabelid tühjeneda, mis põhjustab ühenduse katkestamise.
Kui ping kaob, siis IPIP-tunnel eemaldatakse ja ootab kauguspunkti valmidust.
Tegelik skript:
#!/bin/bash
username="username@yandex.ru"
password="password"
folder="vpnid"
intip="10.0.0.1"
localport=`shuf -i 10000-65000 -n 1`
cid=`shuf -i 10000-99999 -n 1`
tid=`shuf -i 10-99 -n 1`
function yaread {
curl -s --user "$1:$2" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$3 | sed 's/></>n</g' | grep "displayname" | sed 's/<d:displayname>//g' | sed 's/</d:displayname>//g' | grep -v $3 | grep -v $4 | sort -r
}
function yacreate {
curl -s -X MKCOL --user "$1:$2" https://webdav.yandex.ru/$3
}
function yadelete {
curl -s -X DELETE --user "$1:$2" https://webdav.yandex.ru/$3
}
function myipport {
stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress" | sort | uniq | awk '{print $3}' | head -n1
}
function tunnel-up {
modprobe fou
ip fou add port $4 ipproto 4
ip link add name fou$7 type ipip remote $1 local $3 encap fou encap-sport $4 encap-dport $2
ip link set up dev fou$7
ip addr add $6 peer $5 dev fou$7
}
function tunnel-check {
sleep 10
pings=0
until [[ $pings == 4 ]]; do
if ping -c 1 $1 -s 0 &>/dev/null;
then echo -n .; n=0
else echo -n !; ((pings++))
fi
sleep 15
done
}
function tunnel-down {
ip link del dev fou$1
ip fou del port $2
}
trap 'echo -e "nDisconnecting..." && yadelete $username $password $folder; tunnel-down $tunnelid $localport; echo "IPIP tunnel disconnected!"; exit 1' 1 2 3 8 9 14 15
until [[ -n $end ]]; do
yacreate $username $password $folder
until [[ -n $ip ]]; do
mydate=`date +%s`
timeout="60"
list=`yaread $username $password $folder $cid | head -n1`
yacreate $username $password $folder/$mydate:$cid
for l in $list; do
if [ `echo $l | sed 's/:/ /g' | awk {'print $1'}` -ge $(($mydate-65)) ]; then
#echo $list
myipport=`myipport $localport`
yacreate $username $password $folder/$mydate:$cid:$myipport:$intip:$tid
timeout=$(( $timeout + `echo $l | sed 's/:/ /g' | awk {'print $1'}` - $mydate + 3 ))
ip=`echo $l | sed 's/:/ /g' | awk '{print $3}'`
port=`echo $l | sed 's/:/ /g' | awk '{print $4}'`
peerip=`echo $l | sed 's/:/ /g' | awk '{print $5}'`
peerid=`echo $l | sed 's/:/ /g' | awk '{print $6}'`
if [[ -n $peerid ]]; then tunnelid=$(($peerid*$tid)); fi
fi
done
if ( [[ -z "$ip" ]] && [ "$timeout" -gt 0 ] ) ; then
echo -n "!"
sleep $timeout
fi
done
localip=`ip route get $ip | head -n1 | sed 's|.*src ||' | cut -d' ' -f1`
tunnel-up $ip $port $localip $localport $peerip $intip $tunnelid
tunnel-check $peerip
tunnel-down $tunnelid $localport
yadelete $username $password $folder
unset ip port myipport
done
exit 0Muutujad username, password ja kaust peavad olema mõlemal pool samad, kuid intip on erinevad, näiteks: 10.0.0.1 ja 10.0.0.2. Kauguspunktide kellaaeg peab olema sünkroonitud. Skripti saab käivitada järgmiselt:
nohup script.sh &Tahan tähelepanu juhtida, et IPIP-tunnel ei ole turvaline, sest liiklus ei ole krüpteeritud, kuid selle võib lihtsalt lahendada IPsec'i abil , ta näib mulle lihtne ja arusaadav.
Olen seda skripti kasutanud tööarvutile ühendamiseks juba mitu nädalat ja mingeid probleeme pole tähele pannud. Mugav on see, et seadistasin ja unustasin.
Võib-olla on teil mingeid märkusi ja ettepanekuid, olen avatud kuulama.
Aitäh tähelepanu eest!
Allikas: habr.com
