IPIP хонгилыг жишээ болгон ашиглан энгийн UDP нүх гаргах

Сайхан өдөр!

Энэ нийтлэлд би хэрхэн хэрэгжүүлсэнээ хэлэхийг хүсч байна (дахиад нэг) жишээ болгон Ubuntu/Debian OS ашиглан UDP цоолборлох технологийг ашиглан NAT-ийн ард байрлах хоёр компьютерийг холбох Bash скрипт.

Холболтыг бий болгох нь хэд хэдэн үе шатаас бүрдэнэ.

  1. Зангилаа эхлүүлж, алсын зангилаа бэлэн болтол хүлээж байна;
  2. Гадаад IP хаяг болон UDP портыг тодорхойлох;
  3. Гадаад IP хаяг болон UDP портыг алсын хост руу шилжүүлэх;
  4. Алсын хостоос гадаад IP хаяг болон UDP портыг авах;
  5. IPIP хонгилын зохион байгуулалт;
  6. Холболтын хяналт;
  7. Хэрэв холболт тасарсан бол IPIP туннелийг устгана уу.

Би удаан хугацааны турш бодсон боловч зангилааны хооронд өгөгдөл солилцоход юу ашиглаж болох талаар бодож байгаа бөгөөд одоогоор миний хувьд хамгийн энгийн бөгөөд хурдан нь Yandex.disk-ээр дамжуулан ажиллаж байна.

  • Нэгдүгээрт, ашиглахад хялбар - танд 3 үйлдэл хэрэгтэй: үүсгэх, унших, устгах. Curl-ийн хувьд энэ нь:
    Үүсгэх:

    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

Тунелийн төлөвийг дараах тушаалаар алсын зангилааны хонгилын дотоод IP хаяг руу үе үе ping хийх замаар хянадаг.

ping -c 1 $peerip -s 0

Сувгийг хэвийн байлгахын тулд үе үе ping хийх шаардлагатай байдаг, эс тэгвээс туннель ажиллахгүй байх үед чиглүүлэгч дээрх 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

Хувьсагчид хэрэглэгчийн нэр, нууц үг и хавтас хоёр талдаа адилхан байх ёстой, гэхдээ intip - өөр, жишээлбэл: 10.0.0.1 ба 10.0.0.2. Зангилаанууд дээрх цагийг синхрончлох ёстой. Та скриптийг дараах байдлаар ажиллуулж болно:

nohup script.sh &

IPIP туннель нь траффик шифрлэгдээгүй тул аюулгүй биш гэдгийг би та бүхний анхаарлыг татахыг хүсч байна, гэхдээ үүнийг IPsec ашиглан хялбархан шийдэж болно. энэ нийтлэл, энэ нь надад энгийн бөгөөд ойлгомжтой санагдсан.

Би энэ скриптийг хэдэн долоо хоногийн турш ажлын компьютерт холбохдоо ашиглаж байгаа бөгөөд ямар ч асуудал анзаараагүй байна. Тохируулах, мартах тал дээр эвтэйхэн.

Магадгүй танд санал хүсэлт байх болно, би сонсохдоо баяртай байх болно.

Таны анхаарлын төвд баярлалаа!

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх