Vienkārša UDP caurumu caurumošana, piemēram, izmantojot IPIP tuneli

Laba diena!

Šajā rakstā es vēlos jums pastāstīt, kā es ieviesu (cits) Bash skripts divu datoru savienošanai aiz NAT, izmantojot UDP caurumu caurumošanas tehnoloģiju, kā piemēru izmantojot Ubuntu/Debian OS.

Savienojuma izveide sastāv no vairākām darbībām:

  1. Mezgla palaišana un gaidīšana, kamēr attālais mezgls būs gatavs;
  2. Ārējās IP adreses un UDP porta noteikšana;
  3. Ārējās IP adreses un UDP porta pārsūtīšana uz attālo resursdatoru;
  4. Ārējās IP adreses un UDP porta iegūšana no attālā resursdatora;
  5. IPIP tuneļa organizēšana;
  6. Savienojuma uzraudzība;
  7. Ja savienojums tiek zaudēts, izdzēsiet IPIP tuneli.

Es ilgi domāju un joprojām domāju, ko var izmantot datu apmaiņai starp mezgliem, man visvienkāršākais un ātrākais šobrīd ir darbs caur Yandex.disk.

  • Pirmkārt, to ir viegli lietot - jums ir nepieciešamas 3 darbības: izveidojiet, lasiet, dzēsiet. Ar čokurošanos tas ir:
    Izveidot:

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

    Lasīt:

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

    Dzēst:

    curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder
  • Otrkārt, to ir viegli uzstādīt:
    apt install curl

Lai noteiktu ārējo IP adresi un UDP portu, izmantojiet komandu stun-client:

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

Instalēšana ar komandu:

apt install stun-client

Tuneļa organizēšanai tiek izmantoti standarta OS rīki no pakotnes iproute2. Pastāv daudzi tuneļi kuru var pacelt ar standarta līdzekļiem (L2TPv3, GRE utt.), bet izvēlējos IPIP, jo tas rada minimālu papildus slodzi sistēmai. Izmēģināju L2TPv3 pa UDP un biju vīlies, ātrums kritās 10 reizes, bet tie varētu būt dažādi ierobežojumi saistībā ar pakalpojumu sniedzējiem vai kas cits. Tā kā IPIP tunelis darbojas IP līmenī, FOU tunelis tiek izmantots, lai darbotos UDP porta līmenī. Lai organizētu IPIP tuneli, jums ir nepieciešams:

— ielādējiet FOU moduli:

modprobe fou

— klausieties vietējo ostu:

ip fou add port $localport ipproto 4

— izveidot tuneli:

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

— paaugstināt tuneļa saskarni:

ip link set up dev fou$name

— piešķirt tuneļa iekšējās lokālās un iekšējās attālās IP adreses:

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

Dzēst tuneli:

ip link del dev fou$name

ip fou del port $localport

Tuneļa stāvoklis tiek uzraudzīts, periodiski pingot attālā mezgla tuneļa iekšējo IP adresi ar komandu:

ping -c 1 $peerip -s 0

Periodiskā ping ir nepieciešama galvenokārt kanāla uzturēšanai, pretējā gadījumā, kad tunelis ir dīkstāvē, maršrutētāju NAT tabulas var tikt notīrītas un savienojums tiks pārtraukts.

Ja ping pazūd, IPIP tunelis tiek izdzēsts un gaida attālā resursdatora gatavību.

Pats skripts:

#!/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

Mainīgie lietotājvārds, parole и mape jābūt vienādam abās pusēs, bet intip - dažādi, piemēram: 10.0.0.1 un 10.0.0.2. Mezglu laikam jābūt sinhronizētam. Varat palaist skriptu šādi:

nohup script.sh &

Vēlos vērst jūsu uzmanību uz to, ka IPIP tunelis ir nedrošs no tā viedokļa, ka trafiks nav šifrēts, taču to var viegli atrisināt, izmantojot IPsec over. Šis raksts, man tas likās vienkārši un saprotami.

Es jau vairākas nedēļas izmantoju šo skriptu, lai izveidotu savienojumu ar darba datoru, un neesmu pamanījis nekādas problēmas. Ērti tā iestatīšanas un aizmirstības ziņā.

Varbūt jums būs komentāri un ieteikumi, es ar prieku uzklausīšu.

Спасибо за внимание!

Avots: www.habr.com

Pievieno komentāru