Mirëmengjes!
Në këtë artikull dua të flas se si realizova () skript në Bash për lidhjen e dy kompjuterëve, të cilët ndodhen pas NAT, duke përdorur teknologjinë UDP hole punching në shembullin e OS Ubuntu/Debian.
Organizimi i lidhjes përbëhet nga disa hapa:
- Nisja e nodit dhe pritja për gatishmërinë e nodit të largët;
- Përcaktimi i adresës IP të jashtme dhe portit UDP;
- Shkolla e adresës IP të jashtme dhe portit UDP në nodin e largët;
- Marrja e adresës IP të jashtme dhe portit UDP nga nodi i largët;
- Organizimi i tunelit IPIP;
- Monitorimi i lidhjes;
- Në rast ndërprerjeje të lidhjes, fshij tunelin IPIP.
Kam menduar për një kohë të gjatë dhe ende po mendoj se çfarë mund të përdor për shkëmbimin e të dhënave midis nodëve; më e thjeshta dhe më e shpejtë për mua deri tani është funksionimi përmes Yandex.disk.
- SĂ« pari, Ă«shtĂ« thjeshtĂ«sia nĂ« pĂ«rdorim â kĂ«rkohen 3 veprime: krijo, lexoni, fshini. Me curl, kjo Ă«shtĂ«:
Krijo:curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folderLexo:
curl -s --user "$usename:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$folderFshi:
curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder - Së dyti, është thjeshtësia në instalim:
apt install curl
Për të përcaktuar adresën IP të jashtme dhe portin UDP përdoret stun-client me komandën:
stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress"Instalimi me komandën:
apt install stun-clientPër organizimin e tunelit përdoren mjetet standarde të OS nga paketa iproute2. Ekzistojnë që mund të ngrihen me mjete standarde (L2TPv3, GRE etj.), por unë zgjodha IPIP sepse krijon ngarkesë minimale shtesë në sistem. Kam provuar L2TPv3 mbi UDP dhe u zhgënjeva, shpejtësia ra 10 herë, por mund të jenë kufizime të ndryshme që lidhen me ofruesit ose ndonjë gjë tjetër. Duke qenë se tuneli IPIP funksionon në nivelin IP, përdoret tuneli FOU për të punuar në nivelin e porteve UDP. Për organizimin e tunelit IPIP nevojiten:
â ngarko modulin FOU:
modprobe fouâ dĂ«gjo portin lokal:
ip fou add port $localport ipproto 4â krijo tunelin:
ip link add name fou$name type ipip remote $remoteip local $localip encap fou encap-sport $localport encap-dport $remoteportâ ngri interfacin e tunelit:
ip link set up dev fou$nameâ cakto adresĂ«n e brendshme lokale dhe adresĂ«n e brendshme tĂ« largĂ«t tĂ« tunelit:
ip addr add $intIP peer $peerip dev fou$nameFshi tunelin:
ip link del dev fou$nameip fou del port $localportMonitorimi i gjendjes së tunelit bëhet përmes ping-eve periodike të adresës IP të brendshme të tunelit të nodit të largët, me komandën:
ping -c 1 $peerip -s 0Ping-u periodik është i nevojshëm për të mbajtur kanalin, përndryshe gjatë pushimit të tunelit, mund të pastrohen tabelat NAT në routera dhe atëherë lidhja do të pritet.
Nëse ping-u humbet, atëherë tuneli IPIP fshihet dhe pret gatishmërinë nga nodi i largët.
Vërtet skenari vetë:
#!/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 0Variablat username, password dhe folder duhet tĂ« jenĂ« tĂ« njĂ«jta nĂ« tĂ« dy anĂ«t, ndĂ«rsa intip â tĂ« ndryshme, pĂ«r shembull: 10.0.0.1 dhe 10.0.0.2. Koha nĂ« nodĂ« duhet tĂ« jetĂ« e sinkronizuar. Skriptin mund ta nisin kĂ«shtu:
nohup script.sh &Vërej se tuneli IPIP nuk është i sigurt në aspektin se trafikuesi nuk është i enkriptuar, por kjo zgjidhet lehtë duke përdorur IPsec për , më duket e thjeshtë dhe e kuptueshme.
PĂ«rdor kĂ«tĂ« skript pĂ«r tĂ« lidhur me PC-nĂ« time tĂ« punĂ«s pĂ«r disa javĂ« dhe nuk kam vĂ«nĂ« re probleme. ĂshtĂ« e lehtĂ« nĂ« kuptimin se e kam konfiguruar dhe e kam harruar.
Ndoshta keni ndonjë koment ose propozim, do të jem i lumtur të dëgjoj.
Faleminderit për vëmendjen!
Burimi: habr.com
