وقت خوب روز!
در این مقاله می خواهم به شما بگویم که چگونه پیاده سازی کردم (
ایجاد یک اتصال شامل چندین مرحله است:
- شروع یک گره و انتظار برای آماده شدن گره راه دور.
- تعیین آدرس IP خارجی و پورت UDP.
- انتقال یک آدرس IP خارجی و پورت UDP به یک میزبان راه دور.
- دریافت آدرس IP خارجی و پورت UDP از یک میزبان راه دور.
- سازماندهی یک تونل IPIP؛
- نظارت بر اتصال؛
- اگر اتصال قطع شد، تونل 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 استفاده می شود. وجود دارد
- بارگذاری ماژول 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