Tunnel VPN diretto tra computer attraverso i NAT dei provider (senza VPS, usando un server STUN e Yandex.Disk)

Continuazione articolo su come sono riuscito a organizzare un tunnel diretto VPN- tra due computer che si trovano dietro i NAT dei provider. Nell'articolo precedente ho descritto il processo di stabilire una connessione utilizzando una terza parte - un intermediario (affittato VPS che svolge il ruolo di qualcosa simile a un server STUN e un trasmettitore di dati per la connessione). In questo articolo parlerò di come sono riuscito a farne a meno di un VPS, ma gli intermediari sono rimasti ed erano il server STUN e Yandex.Disk...
Tunnel VPN diretto tra computer attraverso i provider NAT (senza VPS, utilizzando un server STUN e Yandex.Disk)

Introduzione

Leggendo i commenti del post precedente, ho capito che il principale svantaggio della realizzazione era l'utilizzo di un intermediario - una terza parte (VPS) che indicava i parametri attuali del nodo, dove e come collegarsi. Considerando le raccomandazioni di utilizzare un vero STUN (ce ne sono davvero molti) per determinare i parametri attuali di connessione. Per prima cosa, ho deciso di controllare con TCPDump il contenuto dei pacchetti mentre il server STUN lavorava con i clienti e ho ottenuto un contenuto completamente illeggibile. Ricercando il protocollo, mi sono imbattuto in un articolo che descrive il protocollo. Ho capito che non posso implementare autonomamente una richiesta a un server STUN e ho messo l'idea in un «cassetto remoto».

Teoria

Recentemente ho dovuto installare un server STUN su Debian dagli ambiti di pacchetto

# apt install stun-server

e nelle dipendenze ho visto il pacchetto stun-client, ma in un certo senso non gli ho dato valore. Ma successivamente mi sono ricordato del pacchetto stun-client e ho deciso di capire come funziona; dopo aver fatto una ricerca su Google e Yandex, ho ottenuto:

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

In risposta ho ricevuto:

Versione del client STUN 0.97
Porta 21234 aperta con fd 3
Porta 21235 aperta con fd 4
Codifica messaggio STUN:
Codifica ChangeRequest: 0

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Messaggio STUN ricevuto: 92 byte
MappedAddress = :2885
SourceAddress = 216.93.246.18:3478
ChangedAddress = 216.93.246.17:3479
Attributo sconosciuto: 32800
ServerName = Vovida.org 0.98-CPC
Messaggio ricevuto di tipo 257 id=1
Codifica messaggio STUN:
Codifica ChangeRequest: 0

In procinto di inviare msg di lunghezza 28 a 216.93.246.17:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 0

In procinto di inviare msg di lunghezza 28 a :2885
Messaggio STUN ricevuto: 28 byte
ChangeRequest = 0
Messaggio ricevuto di tipo 1 id=11
Codifica messaggio STUN:
Codifica ChangeRequest: 0

In procinto di inviare msg di lunghezza 28 a 216.93.246.17:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Messaggio STUN ricevuto: 92 byte
MappedAddress = :2885
SourceAddress = 216.93.246.17:3479
ChangedAddress = 216.93.246.18:3478
Attributo sconosciuto: 32800
ServerName = Vovida.org 0.98-CPC
Messaggio ricevuto di tipo 257 id=10
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 4

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
Codifica messaggio STUN:
Codifica ChangeRequest: 2

In procinto di inviare msg di lunghezza 28 a 216.93.246.18:3478
test I = 1
test II = 0
test III = 0
test I(2) = 1
is nat = 1
mapped IP same = 1
hairpin = 1
preserver port = 0
Primario: Mappatura Indipendente, Filtro Dipendente dalla Porta, porta casuale, sarà hairpin
Il valore di ritorno è 0x000006

Stringa con valore

MappedAddress = :2885

proprio ciò di cui hai bisogno! Mostrava lo stato attuale della connessione sulla porta UDP locale 21234. Ma questo è solo metà del lavoro, si è posto il problema di come trasferire questi dati a un nodo remoto e organizzare una connessione VPN. Usare un protocollo di posta, o forse Telegram?! Ci sono molte opzioni e ho deciso di usare Yandex.Disk, visto che mi era capitato di vedere un articolo sul funzionamento di Curl tramite WebDav con Yandex.Disk. Pensando alla realizzazione sono giunto a questo schema:

  1. Segnalare la disponibilità dei nodi per stabilire una connessione tramite la presenza di un file con un timestamp su Yandex.Disk;
  2. Se i nodi sono pronti, ricevere i parametri attuali dal server STUN;
  3. Caricare i parametri attuali su Yandex.Disk;
  4. Controllare la presenza e leggere i parametri del nodo remoto dal file su Yandex.Disk;
  5. Stabilire una connessione con il nodo remoto usando OpenVPN.

 

Pratica

Dopo aver riflettuto un attimo, tenendo conto dell'esperienza dell'articolo precedente, ho scritto un rapido script. Ci servirà:

# apt install openvpn stun-client curl 

In effetti, lo script stesso:

Versione iniziale

# 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

Per far funzionare lo script è necessario:

  1. Copiare negli appunti e incollare in un editor, ad esempio:
    # nano vpn8.sh 
  2. specificare il login e la password di Yandex.Disk.
  3. nel campo «ifconfig 10.45.54.(1 o 2) 255.255.255.252» specificare l'indirizzo IP interno dell'interfaccia
  4. creare secret.key con il comando:
    # openvpn --genkey --secret secret.key 
  5. rendere eseguibile lo script:
    # chmod +x vpn8.sh
  6. eseguire lo script:
    # ./vpn8.sh nZbVGBuX5dtturD

    dove nZbVGBuX5dtturD è l'ID di connessione generato qui

Sullo host remoto eseguire tutto lo stesso, eccetto per la generazione di secret.key e ID di connessione, che devono essere identici.

Versione aggiornata (per un funzionamento corretto l'ora deve essere sincronizzata):

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

Per far funzionare lo script è necessario:

  1. Copiare negli appunti e incollare in un editor, ad esempio:
    # nano vpn10.sh 
  2. specificare il nome utente (2a riga) e la password di Yandex.Disk (3a riga).
  3. specificare l'indirizzo IP interno del tunnel (4a riga).
  4. rendere eseguibile lo script:
    # chmod +x vpn10.sh
  5. eseguire lo script:
    # ./vpn10.sh nZbVGBuX5dtturD

    dove nZbVGBuX5dtturD è l'ID di connessione generato qui

Sullo host remoto eseguire tutto lo stesso, specificare il corrispondente interno Indirizzo IP del tunnel e ID di connessione.

Per l'avvio automatico dello script all'accensione, utilizzo il comando «nohup //vpn10.sh nZbVGBuX5dtturD > /var/log/vpn10.log 2>/dev/null &» contenuto nel file /etc/rc.local

Conclusione

Lo script funziona, testato su Ubuntu (18.04, 19.10, 20.04) e Debian 9. Come trasmettitore, si può usare qualsiasi altro servizio, ma per l'esperienza ho utilizzato Yandex.Disk.
Durante gli esperimenti è emerso che alcuni tipi di provider NAT non consentono di stabilire una connessione. Questo è particolarmente comune tra gli operatori di telefonia mobile, dove i torrent sono bloccati.

Ho in programma di migliorare quanto segue:

  • Generazione automatica di secret.key ogni volta che si avvia, crittografia e copia su Yandex.Disk per il trasferimento al nodo remoto (incluso nella versione aggiornata)
  • Assegnazione automatica degli indirizzi IP alle interfacce
  • Crittografia dei dati prima del caricamento su Yandex.Disk
  • Ottimizzazione del codice

Che ci sia IPv6 in ogni casa!

Aggiornato! Ultimi file e pacchetto DEB quiyandex.disk

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster