سوراخ کردن ساده UDP با استفاده از یک تونل IPIP به عنوان مثال

وقت خوب روز!

در این مقاله می خواهم به شما بگویم که چگونه پیاده سازی کردم (یکی دیگه) یک اسکریپت Bash برای اتصال دو کامپیوتر پشت NAT با استفاده از فناوری سوراخ کردن UDP با استفاده از سیستم عامل اوبونتو/دبیان به عنوان مثال.

ایجاد یک اتصال شامل چندین مرحله است:

  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

وضعیت تونل با پینگ دوره ای آدرس 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 over می توان این مشکل را به راحتی حل کرد. این مقاله، برای من ساده و قابل درک به نظر می رسید.

من چندین هفته است که از این اسکریپت برای اتصال به رایانه شخصی استفاده می کنم و هیچ مشکلی متوجه نشده ام. از نظر تنظیم و فراموش کردن آن راحت است.

شاید نظرات و پیشنهاداتی داشته باشید، خوشحال می شوم گوش کنم.

با تشکر از شما!

منبع: www.habr.com

اضافه کردن نظر