Đường hầm VPN trực tiếp giữa các máy tính thông qua NAT của nhà cung cấp (không có VPS, sử dụng máy chủ STUN và Yandex.disk)

Extension Điều về cách tôi quản lý để tổ chức đường hầm VPN trực tiếp giữa hai máy tính nằm phía sau nhà cung cấp NAT. Bài viết trước đã mô tả quy trình tổ chức kết nối với sự trợ giúp của bên thứ ba - một bên trung gian (VPS được thuê hoạt động như một máy chủ STUN và bộ truyền dữ liệu nút cho kết nối). Trong bài viết này, tôi sẽ cho bạn biết cách tôi quản lý mà không cần VPS, nhưng các bên trung gian vẫn là máy chủ STUN và Yandex.Disk...
Đường hầm VPN trực tiếp giữa các máy tính thông qua NAT của nhà cung cấp (không có VPS, sử dụng máy chủ STUN và Yandex.disk)

Giới thiệu

Sau khi đọc các nhận xét của bài đăng trước, tôi nhận ra rằng nhược điểm chính của việc triển khai là việc sử dụng một bên trung gian - bên thứ ba (VPS) chỉ ra các tham số hiện tại của nút, vị trí và cách kết nối. Xem xét các khuyến nghị để sử dụng STUN này (trong đó có rất nhiều) để xác định các tham số kết nối hiện tại. Trước hết, tôi quyết định sử dụng TCPDump để xem nội dung của các gói khi máy chủ STUN đang làm việc với máy khách và nhận được nội dung hoàn toàn không thể đọc được. Tìm kiếm giao thức tôi đã xem qua bài viết mô tả giao thức. Tôi nhận ra rằng tôi không thể tự mình thực hiện yêu cầu tới máy chủ STUN và đưa ý tưởng vào một “hộp từ xa”.

Теория

Gần đây tôi phải cài đặt máy chủ STUN trên Debian từ gói

# apt install stun-server

và trong phần phụ thuộc, tôi thấy gói stun-client, nhưng không hiểu sao tôi lại không chú ý đến nó. Nhưng sau đó tôi nhớ đến gói stun-client và quyết định tìm hiểu cách thức hoạt động của nó, sau khi tìm kiếm trên Google và Yandex, tôi nhận được:

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

Đáp lại tôi nhận được:

Máy khách STUN phiên bản 0.97
Đã mở cổng 21234 với fd 3
Đã mở cổng 21235 với fd 4
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 0

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Đã nhận được tin nhắn gây choáng: 92 byte
MappedAddress = <IP của tôi>:2885
Địa chỉ nguồn = 216.93.246.18:3478
Địa chỉ đã thay đổi = 216.93.246.17:3479
Thuộc tính không xác định: 32800
Tên máy chủ = Vovida.org 0.98-CPC
Đã nhận được tin nhắn loại 257 id=1
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 0

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.17:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 0

Chuẩn bị gửi tin nhắn len 28 tới <My IP>:2885
Đã nhận được tin nhắn gây choáng: 28 byte
Yêu cầu thay đổi = 0
Đã nhận được tin nhắn loại 1 id=11
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 0

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.17:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Đã nhận được tin nhắn gây choáng: 92 byte
MappedAddress = <IP của tôi>:2885
Địa chỉ nguồn = 216.93.246.17:3479
Địa chỉ đã thay đổi = 216.93.246.18:3478
Thuộc tính không xác định: 32800
Tên máy chủ = Vovida.org 0.98-CPC
Đã nhận được tin nhắn loại 257 id=10
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 4

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
Mã hóa thông báo choáng:
Mã hóa Yêu cầu thay đổi: 2

Chuẩn bị gửi tin nhắn len 28 tới 216.93.246.18:3478
kiểm tra tôi = 1
kiểm tra II = 0
kiểm tra III = 0
kiểm tra I(2) = 1
là nat = 1
IP được ánh xạ giống nhau = 1
kẹp tóc = 1
cổng bảo quản = 0
Chính: Ánh xạ độc lập, Bộ lọc phụ thuộc cổng, cổng ngẫu nhiên, sẽ kẹp tóc
Giá trị trả về là 0x000006

Chuỗi có giá trị

MappedAddress = <IP của tôi>:2885

đúng thứ bạn cần! Nó hiển thị trạng thái hiện tại của kết nối trên cổng UDP cục bộ 21234. Nhưng đây mới chỉ là một nửa trận chiến, câu hỏi đặt ra là làm thế nào để chuyển dữ liệu này đến máy chủ từ xa và tổ chức kết nối VPN. Sử dụng giao thức thư, hoặc có thể là Telegram?! Có nhiều lựa chọn và tôi quyết định sử dụng Yandex.disk, vì tôi đã xem qua bài viết về cách làm việc Curl qua WebDav với Yandex.disk. Sau khi suy nghĩ về việc thực hiện, tôi đã đưa ra phương án sau:

  1. Báo hiệu rằng các nút đã sẵn sàng thiết lập kết nối bằng sự hiện diện của một tệp cụ thể có dấu thời gian trên Yandex.disk;
  2. Nếu các nút đã sẵn sàng thì sẽ nhận các tham số hiện tại từ máy chủ STUN;
  3. Tải cài đặt hiện tại lên Yandex.disk;
  4. Kiểm tra sự hiện diện và đọc các tham số của nút từ xa từ một tệp trên Yandex.disk;
  5. Thiết lập kết nối với máy chủ từ xa bằng OpenVPN.

Tập luyện

Sau khi suy nghĩ một chút, tính đến kinh nghiệm của bài viết vừa rồi, tôi nhanh chóng viết kịch bản. Chúng ta sẽ cần:

# apt install openvpn stun-client curl 

Bản thân kịch bản:

phiên bản gốc

# 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

Để tập lệnh hoạt động, bạn cần:

  1. Sao chép vào clipboard và dán vào trình soạn thảo, ví dụ:
    # nano vpn8.sh 
  2. chỉ định tên người dùng và mật khẩu cho Yandex.disk.
  3. trong trường "—ifconfig 10.45.54.(1 hoặc 2) 255.255.255.252" chỉ định địa chỉ IP nội bộ của giao diện
  4. tạo nên chìa khoá bí mật bằng lệnh:
    # openvpn --genkey --secret secret.key 
  5. làm cho tập lệnh có thể thực thi được:
    # chmod +x vpn8.sh
  6. chạy tập lệnh:
    # ./vpn8.sh nZbVGBuX5dtturD

    trong đó nZbVGBuX5dtturD là ID kết nối được tạo đây

Trên nút từ xa, thực hiện mọi thứ tương tự ngoại trừ việc tạo secret.key và ID kết nối, chúng phải giống hệt nhau.

Phiên bản cập nhật (phải đồng bộ thời gian để hoạt động chính xác):

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

Để tập lệnh hoạt động, bạn cần:

  1. Sao chép vào clipboard và dán vào trình soạn thảo, ví dụ:
    # nano vpn10.sh 
  2. cho biết thông tin đăng nhập (dòng thứ 2) và mật khẩu cho Yandex.disk (dòng thứ 3).
  3. chỉ định địa chỉ IP nội bộ của đường hầm (dòng thứ 4).
  4. làm cho tập lệnh có thể thực thi được:
    # chmod +x vpn10.sh
  5. chạy tập lệnh:
    # ./vpn10.sh nZbVGBuX5dtturD

    trong đó nZbVGBuX5dtturD là ID kết nối được tạo đây

Trên nút từ xa, thực hiện tương tự, chỉ định địa chỉ IP nội bộ tương ứng của đường hầm và ID kết nối.

Để autorun script khi bật lên, mình dùng lệnh “nohup /<path to the script>/vpn10.sh nZbVGBuX5dtturD > /var/log/vpn10.log 2>/dev/null &” có trong file /etc/ rc.local

Kết luận

Tập lệnh hoạt động, đã được thử nghiệm trên Ubuntu (18.04, 19.10, 20.04) và Debian 9. Bạn có thể sử dụng bất kỳ dịch vụ nào khác làm bộ phát, nhưng để có trải nghiệm, tôi đã sử dụng Yandex.disk.
Trong quá trình thử nghiệm, người ta phát hiện ra rằng một số loại nhà cung cấp NAT không cho phép thiết lập kết nối. Chủ yếu là từ các nhà khai thác di động nơi torrent bị chặn.

Tôi dự định cải thiện về mặt:

  • Tự động tạo secret.key mỗi khi bạn khởi động, mã hóa và sao chép vào Yandex.disk để chuyển sang nút từ xa (Có tính đến phiên bản cập nhật)
  • Tự động gán địa chỉ IP của giao diện
  • Mã hóa dữ liệu trước khi tải lên Yandex.disk
  • Tối ưu hóa mã

Hãy để IPv6 đến mọi nhà!

Đã cập nhật! File mới nhất và gói DEB tại đây - yandex.disk

Nguồn: www.habr.com

Thêm một lời nhận xét