Direkter VPN-Tunnel zwischen Computern über die NATs der Anbieter (ohne VPS, mithilfe eines STUN-Servers und Yandex.Disk)

Fortsetzung des Artikels wie es mir gelungen ist, einen direkten VPN-Tunnel zwischen zwei Computern, die hinter den NATs der Anbieter stehen, einzurichten. Im vorherigen Artikel wurde der Prozess der Verbindung über einen Mittelsmann beschrieben (gemietete VPS der die Rolle eines STUN-Servers und Datenübertragungs-Knotens für die Verbindung übernahm). In diesem Artikel werde ich erläutern, wie ich ohne VPS ausgekommen bin, aber die Mittelsmänner blieben und waren STUN-Server und Yandex.Disk…
Direkter VPN-Tunnel zwischen Computern über NATs der Anbieter (ohne VPS, mit Hilfe eines STUN-Servers und Yandex.Disk)

Einführung

Nachdem ich die Kommentare zum vorherigen Beitrag gelesen hatte, wurde mir klar, dass der Hauptnachteil der Implementierung die Nutzung eines Mittelsmanns – einer dritten Partei (VPS) war, die die aktuellen Parameter des Knotens angab, zu dem und wie man sich verbinden sollte. Unter Berücksichtigung der Empfehlungen, einen echten STUN zu verwenden (von denen es viele gibt) zur Bestimmung der aktuellen Verbindungsparameter. Zuerst wollte ich mit TCPDump den Inhalt der Pakete zu sehen, während der STUN-Server mit den Clients arbeitete, und erhielt völlig unleserliche Inhalte. Nach einer Google-Suche über das Protokoll stieß ich auf einen Artikel mit einer Beschreibung des Protokolls. Mir wurde klar, dass ich nicht in der Lage war, selbst eine Anfrage an den STUN-Server zu implementieren, und ich legte die Idee in eine "ferne Schublade".

Theorie

Kürzlich musste ich einen STUN-Server auf Debian aus dem Paket installieren

# apt install stun-server

und in den Abhängigkeiten sah ich das Paket stun-client, aber ich schenkte dem nicht viel Aufmerksamkeit. Später erinnerte ich mich jedoch an das Paket stun-client und beschloss, herauszufinden, wie es funktioniert. Nach einem Googeln und Yandexen erhielt ich:

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

In Antwort erhielt ich:

STUN-Client-Version 0.97
Port 21234 mit fd 3 geöffnet
Port 21235 mit fd 4 geöffnet
Stun-Nachricht wird codiert:
ChangeRequest codieren: 0

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
STUN-Nachricht empfangen: 92 Bytes
MappedAddress = :2885
SourceAddress = 216.93.246.18:3478
ChangedAddress = 216.93.246.17:3479
Unbekanntes Attribut: 32800
ServerName = Vovida.org 0.98-CPC
Nachricht des Typs 257 id=1 empfangen
Stun-Nachricht wird codiert:
ChangeRequest codieren: 0

Bereit, eine Nachricht der Länge 28 an 216.93.246.17:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 0

Bereit, eine Nachricht der Länge 28 an :2885 zu senden
STUN-Nachricht empfangen: 28 Bytes
ChangeRequest = 0
Nachricht des Typs 1 id=11 empfangen
Stun-Nachricht wird codiert:
ChangeRequest codieren: 0

Bereit, eine Nachricht der Länge 28 an 216.93.246.17:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
STUN-Nachricht empfangen: 92 Bytes
MappedAddress = :2885
SourceAddress = 216.93.246.17:3479
ChangedAddress = 216.93.246.18:3478
Unbekanntes Attribut: 32800
ServerName = Vovida.org 0.98-CPC
Nachricht des Typs 257 id=10 empfangen
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 4

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
Stun-Nachricht wird codiert:
ChangeRequest codieren: 2

Bereit, eine Nachricht der Länge 28 an 216.93.246.18:3478 zu senden
test I = 1
test II = 0
test III = 0
test I(2) = 1
ist nat = 1
mapped IP gleich = 1
hairpin = 1
port-preserving = 0
Primär: Unabhängige Zuordnung, Portabhängiger Filter, zufälliger Port, wird Hairpinning durchführen
Rückgabewert ist 0x000006

Zeichenkette mit Wert

MappedAddress = :2885

Genau das, was ich brauche! Sie zeigte den aktuellen Zustand der Verbindung am lokalen UDP-Port 21234 an. Aber das ist nur die halbe Miete, es stellte sich die Frage, wie man die Daten an den entfernten Knoten überträgt und eine VPN-Verbindung einrichtet. Die Verwendung eines E-Mail-Protokolls oder vielleicht Telegram?! Es gibt viele Möglichkeiten, und ich habe mich entschieden, Yandex.Disk zu verwenden, da ich darauf gestoßen bin. einen Artikel über die Verwendung von Curl über WebDav mit Yandex.Disk.Nachdem ich über die Implementierung nachgedacht hatte, kam ich zu diesem Schema:

  1. Die Knoten signalisieren ihre Bereitschaft zur Verbindung durch das Vorhandensein einer bestimmten Datei mit einem Zeitstempel auf Yandex.Disk;
  2. Wenn die Knoten bereit sind, die aktuellen Parameter vom STUN-Server abrufen;
  3. Die aktuellen Parameter auf Yandex.Disk hochladen;
  4. Prüfen, ob die Parameter des entfernten Knotens in der Datei auf Yandex.Disk vorhanden sind und diese auslesen;
  5. Die Verbindung mit dem entfernten Knoten über OpenVPN herstellen.

 

Praxis

Nachdem ich darüber nachgedacht hatte, schrieb ich, basierend auf den Erfahrungen aus dem vorherigen Artikel, fix einen Skript. Wir benötigen:

# apt install openvpn stun-client curl 

Hier ist das eigentliche Skript:

Vorabversion

# 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

Für die Funktion des Skripts ist es notwendig:

  1. In die Zwischenablage kopieren und in den Editor einfügen, zum Beispiel:
    # nano vpn8.sh 
  2. Geben Sie den Benutzernamen und das Passwort von Yandex.Disk an.
  3. Im Feld „—ifconfig 10.45.54.(1 oder 2) 255.255.255.252“ die interne IP-Adresse des Interfaces angeben.
  4. erstellen secret.key mit dem Befehl:
    # openvpn --genkey --secret secret.key 
  5. das Skript ausführbar machen:
    # chmod +x vpn8.sh
  6. das Skript ausführen:
    # ./vpn8.sh nZbVGBuX5dtturD

    wo nZbVGBuX5dtturD — die generierte Verbindungs-ID. hier

Am entfernten Knoten alles genauso durchführen, mit Ausnahme der Erstellung von secret.key und Verbindungs-ID, die identisch sein müssen.

Aktualisierte Version (für eine korrekte Funktion muss die Zeit synchronisiert sein):

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

Für die Funktion des Skripts ist es notwendig:

  1. In die Zwischenablage kopieren und in den Editor einfügen, zum Beispiel:
    # nano vpn10.sh 
  2. Benutzernamen (2. Zeile) und Passwort von Yandex.Disk (3. Zeile) angeben.
  3. Die interne IP-Adresse des Tunnels (4. Zeile) angeben.
  4. das Skript ausführbar machen:
    # chmod +x vpn10.sh
  5. das Skript ausführen:
    # ./vpn10.sh nZbVGBuX5dtturD

    wo nZbVGBuX5dtturD — die generierte Verbindungs-ID. hier

Am entfernten Knoten alles genauso durchführen, die entsprechende interne IP-Adresse Tunnel- und Verbindungs-ID angeben.

Für den automatischen Start des Skripts beim Einschalten verwende ich den Befehl „nohup //vpn10.sh nZbVGBuX5dtturD > /var/log/vpn10.log 2>/dev/null &“, der in der Datei /etc/rc.local enthalten ist.

Fazit

Das Skript funktioniert, getestet auf Ubuntu (18.04, 19.10, 20.04) und Debian 9. Als Sender kann jeder andere Dienst verwendet werden, aber für den Test habe ich Yandex.Disk verwendet.
Während der Experimente wurde festgestellt, dass einige Arten von NAT-Anbietern keine Verbindung ermöglichen. Dies betrifft hauptsächlich Mobilfunkanbieter, bei denen Torrents blockiert sind.

Ich plane, dies in Bezug auf folgende Punkte weiter zu entwickeln:

  • Automatische Generierung des secret.key bei jedem Start, Verschlüsselung und Kopieren auf Yandex.Disk zur Übertragung auf einen entfernten Knoten (Berücksichtigt in der aktualisierten Version)
  • Automatische Zuweisung von IP-Adressen für Schnittstellen
  • Verschlüsselung von Daten vor dem Hochladen auf Yandex.Disk
  • Code-Optimierung

Möge IPv6 in jedem Haus sein!

Aktualisiert! Neueste Dateien und DEB-Paket hieryandex.disk

Quelle: habr.com

60GB SSD 8Gb DDR4