Едноставно пробивање на UDP дупка користејќи IPIP тунел како пример

Добар дел од денот!

Во оваа статија сакам да ви кажам како имплементирав (уште еден) Bash скрипта за поврзување на два компјутери лоцирани зад NAT користејќи UDP технологија за пробивање дупки користејќи Ubuntu/Debian OS како пример.

Воспоставувањето врска се состои од неколку чекори:

  1. Започнување на јазол и чекање далечинскиот јазол да биде подготвен;
  2. Одредување на надворешна IP адреса и UDP порта;
  3. Пренесување на надворешна IP адреса и UDP порта на оддалечен домаќин;
  4. Добивање надворешна IP адреса и UDP порта од оддалечен домаќин;
  5. Организација на IPIP тунел;
  6. Мониторинг на поврзување;
  7. Ако врската е изгубена, избришете го IPIP тунелот.

Долго размислував и сè уште мислам што може да се користи за размена на податоци помеѓу јазли, наједноставно и најбрзо за мене во моментов е работата преку Yandex.disk.

  • Прво, лесно е да се користи - ви требаат 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

За да ја одредите надворешната IP адреса и UDP портата, користете ја командата stun-client:

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

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

apt install stun-client

За да се организира тунел, се користат стандардни оперативни алатки од пакетот iproute2. Постои многу тунели што може да се подигне со користење на стандардни средства (L2TPv3, GRE, итн.), но го избрав IPIP бидејќи создава минимално дополнително оптоварување на системот. Пробав L2TPv3 преку UDP и се разочарав, брзината падна 10 пати, но тоа може да се разни ограничувања поврзани со провајдерите или нешто друго. Бидејќи IPIP тунелот работи на ниво на IP, тунелот FOU се користи за работа на ниво на порта UDP. За да организирате IPIP тунел ви треба:

— вчитајте го модулот FOU:

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 адреси на тунелот:

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

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

ip link del dev fou$name

ip fou del port $localport

Состојбата на тунелот се следи со периодично ping на внатрешната IP адреса на тунелот на оддалечениот јазол со командата:

ping -c 1 $peerip -s 0

Потребен е периодичен пинг првенствено за одржување на каналот, инаку, кога тунелот е неактивен, NAT табелите на рутерите може да се исчистат и тогаш врската ќе се прекине.

Ако пингот исчезне, тогаш IPIP тунелот се брише и чека подготвеност од далечинскиот хост.

Самото сценарио:

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

Би сакал да го привлечам вашето внимание на фактот дека IPIP тунелот е небезбеден од гледна точка на фактот дека сообраќајот не е шифриран, но тоа може лесно да се реши со користење на IPsec преку овој напис, ми се чинеше едноставно и разбирливо.

Ја користам оваа скрипта за поврзување со работен компјутер веќе неколку недели и не забележав никакви проблеми. Практично во смисла на поставување и заборавање.

Можеби ќе имате коментари и предлози, ќе ми биде драго да слушам.

Ви благодариме!

Извор: www.habr.com

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