Punching UDP simplice cù un tunnel IPIP per esempiu

Bon tempu di u ghjornu!

In questu articulu vogliu dì cumu aghju implementatu (unu di più) un script Bash per a cunnessione di dui computer situati daretu à NAT utilizendu a tecnulugia di perforazione UDP cù u Ubuntu / Debian OS cum'è un esempiu.

Stabbilimentu di una cunnessione hè custituita da parechji passi:

  1. Cumincià un node è aspittendu chì u node remotu sia pronta;
  2. Determinà l'indirizzu IP esternu è u portu UDP;
  3. Trasferendu un indirizzu IP esternu è u portu UDP à un host remoto;
  4. Ottene un indirizzu IP esternu è u portu UDP da un host remoto;
  5. Urganizazione di un tunnel IPIP;
  6. surviglianza di cunnessione;
  7. Se a cunnessione hè persa, sguassate u tunnel IPIP.

Pensu per un bellu pezzu è pensu sempre ciò chì pò esse usatu per scambià dati trà i nodi, u più simplice è più veloce per mè in u mumentu hè travagliatu per Yandex.disk.

  • Prima, hè faciule d'utilizà - avete bisognu di 3 azzioni: creà, leghje, sguassà. Cù curl questu hè:
    Crea:

    curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folder

    Leghjite:

    curl -s --user "$usename:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$folder

    Sguassà:

    curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder
  • Siconda, hè faciule d'installà:
    apt install curl

Per determinà l'indirizzu IP esternu è u portu UDP, utilizate u cumandimu stun-client:

stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress"

Installazione cù cumandamentu:

apt install stun-client

Per urganizà un tunnel, sò usati strumenti standard di u sistema operativo da u pacchettu iproute2. Esiste tanti tunnel chì pò esse risuscitatu cù i mezi standard (L2TPv3, GRE, etc.), ma aghju sceltu IPIP perchè crea una carica supplementaria minima in u sistema. Aghju pruvatu L2TPv3 nantu à UDP è era disappuntu, a velocità hè cascata 10 volte, ma queste puderianu esse diverse restrizioni ligati à i fornituri o qualcosa altru. Siccomu u tunnel IPIP opera à u livellu IP, u tunnel FOU hè utilizatu per operà à u livellu di u portu UDP. Per urganizà un tunnel IPIP avete bisognu:

- carica u modulu FOU:

modprobe fou

- ascolta u portu lucale:

ip fou add port $localport ipproto 4

- creà un tunnel:

ip link add name fou$name type ipip remote $remoteip local $localip encap fou  encap-sport $localport encap-dport $remoteport

- elevà l'interfaccia di u tunnel:

ip link set up dev fou$name

- assignà l'indirizzi IP internu lucali è remoti interni di u tunnel:

ip addr add $intIP peer $peerip dev fou$name

Sguassà un tunnel:

ip link del dev fou$name

ip fou del port $localport

U statu di u tunnel hè monitoratu per ping periodicamente l'indirizzu IP internu di u tunnel di u nodu remoto cù u cumandimu:

ping -c 1 $peerip -s 0

U ping periodicu hè necessariu principarmenti per mantene u canali, altrimenti, quandu u tunelu hè inattivu, i tavule NAT nantu à i routers ponu esse sbulicati è poi a cunnessione serà rotta.

Se u ping sparisce, allora u tunnel IPIP hè sguassatu è aspetta a preparazione da l'ospite remoto.

U script stessu:

#!/bin/bash
username="[email protected]"
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 0

Variabili gatti, codice и cartulare duverebbe esse uguali da i dui lati, ma sguardu - differente, per esempiu: 10.0.0.1 è 10.0.0.2. U tempu nantu à i nodi deve esse sincronizatu. Pudete eseguisce u script cusì:

nohup script.sh &

Vogliu chjamà a vostra attenzione à u fattu chì u tunnel IPIP ùn hè micca sicuru da u puntu di vista di u fattu chì u trafficu ùn hè micca criptatu, ma questu pò esse facilmente risoltu cù IPsec sopra. stu articulu, mi paria simplice è comprensibile.

Aghju utilizatu stu script per cunnette à un PC di travagliu per parechje settimane è ùn aghju micca nutatu prublemi. Conveniente in quantu à mette è scurdate.

Forse averete cumenti è suggerimenti, saraghju felice di sente.

Ti ringraziu per a vostra attenzione!

Source: www.habr.com

Add a comment