Једноставно УДП бушење рупа користећи ИПИП тунел као пример

Добар дан дана!

У овом чланку желим да вам кажем како сам имплементирао (други) Басх скрипта за повезивање два рачунара која се налазе иза НАТ-а користећи УДП технологију бушења рупа користећи Убунту/Дебиан ОС као пример.

Успостављање везе се састоји од неколико корака:

  1. Покретање чвора и чекање да удаљени чвор буде спреман;
  2. Одређивање екстерне ИП адресе и УДП порта;
  3. Преношење екстерне ИП адресе и УДП порта на удаљени хост;
  4. Добијање екстерне ИП адресе и УДП порта са удаљеног хоста;
  5. Организација ИПИП тунела;
  6. Мониторинг везе;
  7. Ако се веза изгуби, избришите ИПИП тунел.

Дуго сам размишљао и још увек размишљам шта може да се користи за размену података између чворова, најједноставнији и најбржи за мене тренутно је рад преко Иандек.диск.

  • Прво, једноставан је за употребу - потребне су вам 3 акције: креирање, читање, брисање. Са цурл-ом ово је:
    Креирај:

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

    Читати:

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

    Избриши:

    curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder
  • Друго, лако се инсталира:
    apt install curl

Да бисте одредили спољну ИП адресу и УДП порт, користите команду стун-цлиент:

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

Инсталација са командом:

apt install stun-client

За организовање тунела користе се стандардни ОС алати из пакета ипроуте2. Постоји много тунела који се може подићи стандардним средствима (Л2ТПв3, ГРЕ итд.), али сам изабрао ИПИП јер ствара минимално додатно оптерећење на систему. Пробао сам Л2ТПв3 преко УДП-а и био сам разочаран, брзина је пала 10 пута, али то могу бити разна ограничења везана за провајдере или нешто друго. Пошто ИПИП тунел ради на ИП нивоу, ФОУ тунел се користи за рад на нивоу УДП порта. Да бисте организовали ИПИП тунел потребно вам је:

— учитајте ФОУ модул:

modprobe fou

— слушајте локални порт:

ip fou add port $localport ipproto 4

— направите тунел:

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

— подићи интерфејс тунела:

ip link set up dev fou$name

— додели интерне локалне и интерне удаљене ИП адресе тунела:

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

Избришите тунел:

ip link del dev fou$name

ip fou del port $localport

Стање тунела се прати периодичним пинговањем интерне ИП адресе тунела удаљеног чвора командом:

ping -c 1 $peerip -s 0

Периодични пинг је потребан првенствено за одржавање канала, у супротном, када је тунел неактиван, НАТ табеле на рутерима могу бити обрисане и тада ће веза бити прекинута.

Ако пинг нестане, онда се ИПИП тунел брише и чека спремност са удаљеног хоста.

Сама скрипта:

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

Променљиве корисничко име, лозинка и фасцикла требало би да буде исто са обе стране, али интип - различите, на пример: 10.0.0.1 и 10.0.0.2. Време на чворовима мора бити синхронизовано. Скрипту можете покренути овако:

nohup script.sh &

Скрећем вам пажњу да ИПИП тунел није безбедан са становишта чињенице да саобраћај није шифрован, али се то лако може решити коришћењем ИПсец-а преко Овај чланак, чинило ми се једноставно и разумљиво.

Користим ову скрипту за повезивање са радним рачунаром већ неколико недеља и нисам приметио никакве проблеме. Погодно у смислу подешавања и заборављања.

Можда ћете имати коментаре и сугестије, биће ми драго да их саслушам.

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

Извор: ввв.хабр.цом

Додај коментар