تونل مستقیم VPN بین رایانه ها از طریق NAT های ارائه دهندگان (بدون VPS، با استفاده از سرور STUN و Yandex.disk)

توسعه مقاله در مورد اینکه چگونه توانستم یک تونل مستقیم VPN را بین دو کامپیوتر واقع در پشت ارائه دهندگان NAT سازماندهی کنم. مقاله قبلی روند سازماندهی یک اتصال را با کمک یک شخص ثالث - یک واسطه (یک VPS اجاره ای که به عنوان چیزی شبیه سرور STUN و یک فرستنده داده گره برای اتصال عمل می کند) شرح داد. در این مقاله به شما خواهم گفت که چگونه بدون VPS مدیریت کردم، اما واسطه ها باقی ماندند و آنها سرور STUN و Yandex.Disk بودند.
تونل مستقیم VPN بین رایانه ها از طریق NAT های ارائه دهنده (بدون VPS، با استفاده از سرور STUN و Yandex.disk)

معرفی

پس از خواندن نظرات پست قبلی، متوجه شدم که اشکال اصلی پیاده سازی استفاده از یک واسطه است - یک شخص ثالث (VPS) که پارامترهای فعلی گره، مکان و نحوه اتصال را نشان می دهد. با توجه به توصیه های استفاده از این STUN (که تعداد زیادی از آنها وجود دارد) برای تعیین پارامترهای اتصال فعلی. اول از همه، من تصمیم گرفتم از TCPDump برای مشاهده محتویات بسته ها زمانی که سرور STUN با کلاینت ها کار می کرد و محتوای کاملاً ناخوانا دریافت می کرد، استفاده کنم. با جستجوی پروتکل به آن برخوردم مقاله ای که پروتکل را توصیف می کند. متوجه شدم که نمی‌توانم به تنهایی درخواستی را برای سرور STUN اجرا کنم و این ایده را در یک "جعبه دور" قرار دهم.

Теория

اخیراً مجبور شدم سرور STUN را روی دبیان از بسته نصب کنم

# apt install stun-server

و در وابستگی ها بسته stun-client را دیدم، اما به نوعی به آن توجه نکردم. اما بعداً به یاد بسته stun-client افتادم و تصمیم گرفتم بفهمم چگونه کار می کند، پس از جستجو و جستجو در Yandex به دستم رسید:

# apt install stun-client
# stun stun.ekiga.net -p 21234 -v

در پاسخ دریافت کردم:

STUN کلاینت نسخه 0.97
پورت 21234 با fd 3 باز شد
پورت 21235 با fd 4 باز شد
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 0

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
دریافت پیام شگفت انگیز: 92 بایت
MappedAddress = <IP من>:2885
نشانی منبع = 216.93.246.18:3478
ChangedAddress = 216.93.246.17:3479
ویژگی ناشناخته: 32800
ServerName = Vovida.org 0.98-CPC
پیام دریافتی از نوع 257 id=1
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 0

در حال ارسال پیام len 28 به 216.93.246.17:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 0

در شرف ارسال پیام len 28 به <My IP>:2885
دریافت پیام شگفت انگیز: 28 بایت
ChangeRequest = 0
پیام دریافتی از نوع 1 id=11
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 0

در حال ارسال پیام len 28 به 216.93.246.17:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
دریافت پیام شگفت انگیز: 92 بایت
MappedAddress = <IP من>:2885
نشانی منبع = 216.93.246.17:3479
ChangedAddress = 216.93.246.18:3478
ویژگی ناشناخته: 32800
ServerName = Vovida.org 0.98-CPC
پیام دریافتی از نوع 257 id=10
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 4

در حال ارسال پیام len 28 به 216.93.246.18:3478
رمزگذاری پیام stun:
درخواست تغییر رمزگذاری: 2

در حال ارسال پیام len 28 به 216.93.246.18:3478
تست I = 1
تست II = 0
آزمون III = 0
تست I(2) = 1
nat = 1 است
نگاشت IP یکسان = 1
سنجاق سر = 1
پورت محافظ = 0
اولیه: نقشه‌برداری مستقل، فیلتر وابسته به پورت، پورت تصادفی، سنجاق سر
مقدار بازگشتی 0x000006 است

رشته با ارزش

MappedAddress = <IP من>:2885

فقط آنچه شما نیاز دارید! وضعیت فعلی اتصال را در پورت UDP محلی 21234 نشان می‌دهد. اما این تنها نیمی از نبرد است؛ این سؤال مطرح شد که چگونه می‌توان این داده‌ها را به میزبان راه دور منتقل کرد و اتصال VPN را سازمان‌دهی کرد. استفاده از پروتکل میل یا شاید تلگرام؟! گزینه های زیادی وجود دارد و از زمانی که برخورد کردم تصمیم گرفتم از Yandex.disk استفاده کنم مقاله ای در مورد کارکردن Curl از طریق WebDav با Yandex.disk. پس از فکر کردن در مورد پیاده سازی، به طرح زیر رسیدم:

  1. با وجود یک فایل خاص با مهر زمانی در Yandex.disk، سیگنال آماده شدن گره‌ها برای برقراری ارتباط هستند.
  2. اگر گره ها آماده هستند، پارامترهای فعلی را از سرور STUN دریافت کنید.
  3. آپلود تنظیمات فعلی به Yandex.disk.
  4. وجود و خواندن پارامترهای یک گره راه دور از یک فایل در Yandex.disk را بررسی کنید.
  5. ایجاد ارتباط با میزبان راه دور با استفاده از OpenVPN.

عمل

بعد از کمی تفکر و با در نظر گرفتن تجربه مقاله آخر، سریع فیلمنامه ای نوشتم. ما نیاز خواهیم داشت:

# apt install openvpn stun-client curl 

خود فیلمنامه:

نسخه اصلی

# cat vpn8.sh

#!/bin/bash
######################## Задаем цветной текст ###
WARN='33[37;1;41m'				#
END='33[0m'					#
RED='33[0;31m'         #  ${RED}		#
GREEN='33[0;32m'      #  ${GREEN}		#
#################################################
####################### Проверяем наличие необходымих приложений #########################################################
al="echo readlink dirname grep awk md5sum shuf nc curl sleep openvpn cat stun"
ch=0
for i in $al; do which $i > /dev/null || echo -e "${WARN}Для работы необходим $i ${END}"; which $i > /dev/null || ch=1; done
if (( $ch > 0 )); then echo -e "${WARN}Ой, отсутствуют необходимые для корректной работы приложения${END}"; exit; fi
#######################################################################################################################

if [[ $1 == '' ]]; then echo -e "${WARN}Введите идентификатор соединения (любое уникальное слово, должно быть одинаковое с двух сторон!) ${END} t
${GREEN}Для запуска в автоматическом режиме при включении компьютера можно прописать в /etc/rc.local строку nohup /<путь к файлу>/vpn8.sh  > /var/log/vpn8.log 2>/dev/hull & ${END}"; exit; fi
ABSOLUTE_FILENAME=`readlink -f "$0"`                                                    # полный путь до скрипта
DIR=`dirname "$ABSOLUTE_FILENAME"`                                                      # каталог в котором лежит скрипт
############################### Проверка наличия секретного ключа ##################################
key="$DIR/secret.key"
if [ ! -f "$key" ]; then
				echo -e "${WARN}Секретный ключ VPN-соединения не найден, для генерации ключа выполните: 
openvpn --genkey --secret secret.key Внимание: ключ используется для авторизации и должен 
быть одинаковым с двух сторон!!!${END}
 # ls -l secret.key
 -rw------- 1 root root 637 ноя 27 11:12 secret.key
 # chmod 600 secret.key";
				exit;
				fi
########################################################################################################################

ABSOLUTE_FILENAME=`readlink -f "$0"`                                                    # полный путь до скрипта
DIR=`dirname "$ABSOLUTE_FILENAME"`                                                      # каталог в котором лежит скрипт
name=$(uname -n | md5sum | awk '{print $1}')
vpn=$(echo $1 | md5sum | awk '{print $1}')
stun="stun.ekiga.net" 	# STUN сервер
username="Yandex"	# Логин от Яндекс.диска	
password="Password"	# Пароль от Яндекс.диска
localport=`shuf -i 20000-65000 -n 1`	# генерация локального порта

echo "$(date) Создаю папку на Яндекс.диске"
curl -X MKCOL --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn
echo "$(date) Очищаю папку от всякого мусора"
for i in `curl --silent --user "$username:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname" | sed 's/d:displayname//g' | sed 's/>//g' | sed 's/<//' | sed 's////g' | grep -v $(date +%Y-%m-%d-%H-%M)`; do
	echo "$(date) Delete: $i"
	curl -X DELETE --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn/$i
	done

until [ $c ];do

	until [[ $b ]]; do
		echo "$(date) Проверяю папку"
		date=`date +%Y-%m-%d-%H-%M`
		mydata=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep $name | grep $date | grep "d:displayname"`
		if [[ -z $mydata ]]; 	then
						echo "$(date) Файл готовности создан"
					        echo "$date" > "/tmp/$date-$name-ready.txt"
					        curl -T "/tmp/$date-$name-ready.txt" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$date-$name-ready.txt
					else
						echo "$(date) Файл готовности уже существует - $date"
					fi
		remote=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep -v $name | grep $date | grep "d:displayname"`
		if [[ -z $remote ]];	then
						echo -e "$(date) ${RED} Удаленный узел не готов ${END}"
						echo "$(date) Жду"
						sleep 20
					else
						echo -e "$(date) ${GREEN} Удаленный узел готов ${END}"
						b=1
						a=''
					fi
	done

	until [ $a ]; do
		echo "$(date) Подключение и получение данных от STUN сервера: $stun"
                mydata=`stun $stun -p $localport -v 2>&1 | grep MappedAddress | sort | uniq`
                echo -e "$(date) ${GREEN}Мои данные соединения: $mydata${END}"
                echo "$mydata" > "$DIR/mydata"
                echo "$(date) Загрузка данных на Яндекс.диск"
                curl -T "$DIR/mydata" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$name.txt
		echo "$(date) Получение файла данных удаленного узла"
		filename=$(curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname>" | grep "txt" | grep -v "$name" | grep -v "ready" | sed 's|.*d:displayname>||' | sed 's/</ /g' | awk '{print $1}')
		echo "$(date) Чтение файла данных удаленного узла: $filename"
		address=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$filename | sort | uniq | head -n1 | sed 's/:/ /g')
		echo "$(date) Определение IP-адреса и порта"
		ip=$(echo "$address" | awk '{print $3}')
		port=$(echo "$address" | awk '{print $4}')
		if [[ -n "$ip" && -n "$port" ]]; then
			echo -e "$(date) ${GREEN} Соединение $ip $port ${END}"
       		 	openvpn --remote $ip --rport $port --lport $localport 
	       	 	    --proto udp --dev tap --float --auth-nocache --verb 3 --mute 20 
	       	 	    --ifconfig 10.45.54.2 255.255.255.252 
	       		    --secret "$DIR/secret.key" 
	       		    --auth SHA256 --cipher AES-256-CBC 
	        	    --ncp-disable --ping 10  --ping-exit 30 
	        	    --comp-lzo yes
			echo -e "$(date) ${WARN} Соединение разорвано${END}"
			a=1
			b=''
			else
			a=1
			b=''
			fi
	done
done

برای اینکه اسکریپت کار کند شما نیاز دارید:

  1. در کلیپ بورد کپی کنید و در ویرایشگر جایگذاری کنید، به عنوان مثال:
    # nano vpn8.sh 
  2. نام کاربری و رمز عبور Yandex.disk را مشخص کنید.
  3. در قسمت "—ifconfig 10.45.54.(1 or 2) 255.255.255.252" آدرس IP داخلی رابط را مشخص کنید
  4. ايجاد كردن راز.کلید دستور:
    # openvpn --genkey --secret secret.key 
  5. اسکریپت را قابل اجرا کنید:
    # chmod +x vpn8.sh
  6. اسکریپت را اجرا کنید:
    # ./vpn8.sh nZbVGBuX5dtturD

    که در آن nZbVGBuX5dtturD شناسه اتصال ایجاد شده است اینجا

در گره راه دور، همه کارها را یکسان انجام دهید، به جز تولید secret.key و شناسه اتصال، آنها باید یکسان باشند.

نسخه به روز شده (زمان باید برای عملکرد صحیح همگام شود):

cat vpn10.sh

#!/bin/bash
stuns="stun.sipnet.ru stun.ekiga.net"   		# Список STUN серверов через пробел
username=" Login "		# Логин от Яндекс.диска
password=" Password "   	# Пароль от Яндекс.диска
intip="10.23.22.1"		# IP-адрес внутреннего интерфейса
WARN='33[37;1;41m'
END='33[0m'
RED='33[0;31m'
GREEN='33[0;32m'
al="ip echo readlink dirname grep awk md5sum openssl sha256sum shuf curl sleep openvpn cat stun"
ch=0
for i in $al; do which $i > /dev/null || echo -e "${WARN}Для работы необходим $i ${END}"; which $i > /dev/null || ch=1; done
if (( $ch > 0 )); then echo -e "${WARN}Ой, отсутствуют необходимые для корректной работы приложения${END}"; exit; fi
if [[ $1 == '' ]];
then
echo -e "${WARN}Введите идентификатор соединения (любое уникальное слово, должно быть одинаковое с двух сторон!) ${END} t
${GREEN}Для запуска в автоматическом режиме при включении компьютера можно прописать в /etc/rc.local строку nohup /<путь к файлу>/vpn10.sh  > /var/log/vpn10.log 2>/dev/hull & ${END}"
exit
fi
ABSOLUTE_FILENAME=`readlink -f "$0"`                                                    # полный путь до скрипта
DIR=`dirname "$ABSOLUTE_FILENAME"`                                                      # каталог в котором лежит скрипт
key="$DIR/secret.key"
until [[ -n "$iftosrv" ]]
do
echo "$(date) Определяю сетевой интерфейс"; iftosrv=`ip route get 8.8.8.8 | head -n 1 | sed 's|.*dev ||' | awk '{print $1}'`
sleep 5
done
timedatectl
name=$(uname -n | md5sum | awk '{print $1}')
vpn=$(echo $1 | md5sum | awk '{print $1}')
echo "$(date) Создаю папку на Яндекс.диске"
curl -X MKCOL --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn
echo "$(date) ID на диске: $vpn"
until [ $c ];do
echo "$(date) Очищаю папку от всякого мусора"
for i in `curl --silent --user "$username:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname" | sed 's/d:displayname//g' | sed 's/>//g' | sed 's/<//' | sed 's////g' | grep -v $(date +%Y-%m-%d-%H-%M)`
do
echo -e "$(date)${RED} Удаляю старый файл: $i${END}"
curl -X DELETE --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn/$i
done
echo "$(date) ID на диске: $vpn"
openvpn --genkey --secret "$key"
passwd=`echo "$vpn-tt" | sha256sum | awk '{print $1}'`
openssl AES-256-CBC -e -in "$key" -out "$DIR/file.enc" -k "$passwd" -base64
curl -T "$DIR/file.enc" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/key.enc
rm "$DIR"/file.enc
echo -e "$(date) ${GREEN}Фаза 1 - Получение готовности удаленного узла${END}"
go=3
localport=`shuf -i 20000-65000 -n 1`    # генерация локального порта
start=''
remote=''
timeout1=''
nextcheck=''
timestart=''
until [[ $b ]]
do
echo "$(date) Проверяю папку"
date=`date +%s`
timeout1=60
echo "$(date) Создание файла готовности $date"
echo "$date" > "/tmp/ready-$date-$name.txt"
curl -T "/tmp/ready-$date-$name.txt" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/ready-$name.txt
readyfile=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep -v $name | grep "ready" | grep "d:displayname" | sed 's/<d:displayname>//g' | sed 's/</d:displayname>//g'`
if [[ -z $readyfile ]]
then
echo -e "$(date) ${RED} Удаленный узел не готов ${END}"
echo "$(date) Жду 60 секунд"
sleep $timeout1
else
remote=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$readyfile)
echo -e "$(date) ${GREEN} Удаленный узел готов ${END}"
start=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep "start" | grep "d:displayname" | sed 's/-/ /g' | awk '{print $2}'`
if [[ -z $start ]]
then
let nextcheck=$timeout1-$date+$remote
let timestart=$date+$timeout1-$nextcheck
go=$nextcheck
echo "$timestart" > "/tmp/start-$date-$name.txt"
curl -T "/tmp/start-$date-$name.txt" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/start-$date-$name.txt
else
echo "$(date) жду $go секунд"
sleep $go
b=1
a=''
fi
fi
done
echo -e "$(date) ${GREEN}Фаза 2 - Обмен данными и установка соединения${END}"
mydata=''
filename=''
address=''
myip=''
ip=''
port=''
ex=0
until [ $a ]; do
until [[ -n "$mydata" ]]; do
k=`echo "$stuns" | wc -w`
x=1
z=`shuf -i 1-$k -n 1`
for st in $stuns; do
if [[ $x == $z ]]; then
stun=$st;
fi;
(( x++ ));
done
echo "$(date) Подключение и получение данных от STUN сервера: $stun"
sleep 5 && for pid in $(ps xa | grep "stun "$stun" 1 -p "$localport" -v" | grep -v grep | awk '{print $1}'); do kill $pid; done &
mydata=`stun "$stun" 1 -p "$localport" -v 2>&1 | grep "MappedAddress" | sort | uniq`
done
echo -e "$(date) ${GREEN}Мои данные соединения: $mydata${END}"
echo "$(date) Загрузка данных на Яндекс.диск"
echo "$mydata" > "$DIR/mydata"
echo "IntIP $intip" >> "$DIR/mydata"
curl -T "$DIR/mydata" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$name-ipport.txt
rm "$DIR/mydata"
sleep 5
echo "$(date) Получение файла данных удаленного узла"
filename=$(curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname>" | grep "ipport" | grep -v "$name" |  sed 's|.*d:displayname>||' | sed 's/</ /g' | awk '{print $1}')
if [[ -n "$filename" ]]
then
echo "$(date) Чтение файла данных удаленного узла: $filename"
address=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$filename | grep "MappedAddress" | head -n1 | sed 's/:/ /g')
intip2=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$filename | grep "IntIP" | head -n1 | awk '{print $2}')
echo "$(date) Определение IP-адреса и порта: $address $sesid2 $tunid2"
ip=$(echo "$address" | awk '{print $3}')
port=$(echo "$address" | awk '{print $4}')
myip=`ip route get "$ip" | head -n 1 | sed 's|.*src ||' | awk '{print $1}'`
if [[ -n "$ip" && -n "$port" && -n "$myip" && -n "$localport" ]];
then
echo -e "$(date) ${GREEN} Соединение $ip $port ${END}"
echo -e  "`date` ${GREEN} $myip:$localport -> $ip:$port ${END}"
curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/key.enc > "$DIR/secret.enc"
openssl AES-256-CBC -d -in "$DIR/secret.enc" -out "$key" -k "$passwd" -base64
chmod 600 "$key"
rm "$DIR/secret.enc"
openvpn --remote $ip --rport $port --lport $localport 
--proto udp --dev tun --float --auth-nocache --verb 3 --mute 20 
--ifconfig "$intip" "$intip2" 
--secret "$key" 
--auth SHA256 --cipher AES-256-CBC 
--ncp-disable --ping 10 --ping-exit 20 
--comp-lzo yes
a=1
b=''
fi
else
if (( $ex >= 5 ))
then
echo "$(date) Сброс"
a=1
b=''
fi
(( ex++ ))
sleep 5
fi
done
done

برای اینکه اسکریپت کار کند شما نیاز دارید:

  1. در کلیپ بورد کپی کنید و در ویرایشگر جایگذاری کنید، به عنوان مثال:
    # nano vpn10.sh 
  2. ورود به سیستم (خط دوم) و رمز عبور Yandex.disk (خط 2) را نشان دهید.
  3. آدرس IP داخلی تونل (خط 4) را مشخص کنید.
  4. اسکریپت را قابل اجرا کنید:
    # chmod +x vpn10.sh
  5. اسکریپت را اجرا کنید:
    # ./vpn10.sh nZbVGBuX5dtturD

    که در آن nZbVGBuX5dtturD شناسه اتصال ایجاد شده است اینجا

در گره راه دور، همین کار را انجام دهید، آدرس IP داخلی مربوطه تونل و شناسه اتصال را مشخص کنید.

برای اجرای خودکار اسکریپت هنگامی که روشن است، از دستور "nohup /<path to the script>/vpn10.sh nZbVGBuX5dtturD > /var/log/vpn10.log 2>/dev/null &" موجود در فایل /etc/ استفاده می کنم. rc.local

نتیجه

این اسکریپت بر روی اوبونتو (18.04، 19.10، 20.04) و دبیان 9 آزمایش شده است. شما می توانید از هر سرویس دیگری به عنوان فرستنده استفاده کنید، اما برای تجربه من از Yandex.disk استفاده کردم.
در طی آزمایشات، مشخص شد که برخی از انواع ارائه دهندگان NAT اجازه برقراری ارتباط را نمی دهند. عمدتاً از اپراتورهای تلفن همراه که در آن تورنت ها مسدود شده اند.

من قصد دارم از نظر پیشرفت کنم:

  • تولید خودکار Secret.key هر بار که شروع می‌کنید، رمزگذاری کنید و برای انتقال به یک گره راه دور در Yandex.disk کپی کنید (با در نظر گرفتن نسخه به روز شده)
  • تخصیص خودکار آدرس های IP رابط ها
  • رمزگذاری داده ها قبل از آپلود در Yandex.disk
  • بهینه سازی کد

اجازه دهید IPv6 در هر خانه وجود داشته باشد!

به روز شد! آخرین فایل ها و بسته DEB در اینجا - yandex.disk

منبع: www.habr.com

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