Vazhdimi artikulli për mënyrën se si arrita të organizoj një VPN-tunel midis dy kompjuterëve që ndodhen pas NAT-eve të ofruesve. Në artikullin e kaluar u përshkrua procesi i organizimit të lidhjes me ndihmën e një pale të tretë - ndërmjetësi (me qira) VPS duke luajtur rol, diçka si STUN-server dhe transmetues të të dhënave të nyjave për lidhjen. Në këtë artikull do të tregoj si arrita të shmang për përdorimin e VPS, por ndërmjetësit mbetën dhe ata ishin STUN-server dhe Yandex.Disk...
Hyrje
Pas leximit të komenteve të postimit të kaluar, kuptova se disavantazhi kryesor i realizimit ishte përdorimi i një ndërmjetësi - një pale të tretë (VPS) që tregonte parametrat aktualë të nyjës, se ku dhe si të lidhemi. Duke pasur parasysh rekomandimet për të përdorur një STUN të vërtetë (të cilat ka shumë) për të përcaktuar parametrat aktualë të lidhjes. E para që kam bërë ishte të shihja me ndihmën e TCPDump përmbajtjen e paketeve gjatë punës së STUN-serverit me klientët dhe mora një përmbajtje krejtësisht të paqartë. Pasi kërkova në Google për protokollin, godita në një artikull që përshkruan protokollin. Kuptova se nuk do të mundja të realizoja një kërkesë ndaj STUN-serverit dhe e hoqa idenë në 'kutinë e largët'.
Teoria
Së fundmi më duhej të instalonja STUN-server në Debian nga paketa
# apt install stun-serverdhe në varësi pashë paketën stun-client, por ndonjëherë nuk i kushtova rëndësi. Por më vonë më erdhi në mendje për paketën stun-client dhe vendosa të kuptoj se si funksionon, duke kërkuar në Google dhe Yandex munda të merrja:
# apt install stun-client
# stun stun.ekiga.net -p 21234 -v
Në përgjigje mora:
STUN client version 0.97
Porti 21234 u hap me fd 3
Porti 21235 u hap me fd 4
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 0Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Mesazhi i reçuar i stun: 92 byte
MappedAddress = :2885
SourceAddress = 216.93.246.18:3478
ChangedAddress = 216.93.246.17:3479
Atribut i panjohur: 32800
ServerName = Vovida.org 0.98-CPC
Mesazhi i marrë me tipin 257 id=1
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 0Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.17:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 0Deri te dërgimi i mesazhit me gjatësi 28 te :2885
Mesazhi i marrë i stun: 28 byte
ChangeRequest = 0
Mesazhi i marrë me tipin 1 id=11
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 0Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.17:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Mesazhi i reçuar i stun: 92 byte
MappedAddress = :2885
SourceAddress = 216.93.246.17:3479
ChangedAddress = 216.93.246.18:3478
Atribut i panjohur: 32800
ServerName = Vovida.org 0.98-CPC
Mesazhi i marrë me tipin 257 id=10
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 4Deri te dërgimi i mesazhit me gjatësi 28 te 216.93.246.18:3478
Duke koduar mesazhin e stun:
Duke koduar ChangeRequest: 2Deri te dërgimi i mesazhit me gjatësi 28 te 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
Primary: Mapping të Pavarur, Filtri të Varur nga Porta, port rastësor, do të hairpin
Vlera e kthimit është 0x000006
String me vlerë
MappedAddress = :2885
pikërisht ajo që na duhet! Ajo shfaqte gjendjen aktuale për lidhjen në portin lokal UDP 21234. Por kjo është vetëm gjysma e punës, u shfaq pyetja se si të dërgohen këto të dhëna në një nod dhe të organizohet një lidhje VPN. Përdorimi i protokollit të postës, ndoshta Telegram?! Ka shumë alternativa dhe vendosa të përdor Yandex.Disk, pasi më kishte ra në sy artikulli mbi punën e Curl përmes WebDav me Yandex.Disk. Duke menduar për realizimin, arrita në këtë skemë:
- Të sinjalizojmë gatishmërinë e node-ve për të vendosur lidhjen me praninë e një skedari të caktuar me kohëzgjatje në Yandex.Disk;
- Nëse node-t janë të gatshëm, atëherë të marrim parametrat aktualë nga serveri STUN;
- Të shkarkojmë parametrat aktualë në Yandex.Disk;
- Të kontrollojmë praninë dhe të lexojmë parametrat e nodit të largët nga skedari në Yandex.Disk;
- Vendosja e lidhjes me nodin e largët duke përdorur OpenVPN.
Praktika
Pak duke menduar, duke marrë parasysh përvojën e artikullit të kaluar, shkrova një skript në një moment të shpejtë. Na nevojitet:
# apt install openvpn stun-client curl Saktësisht skripti vetë:
Varianti fillestar
# 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
donePër të funksionuar skripti, nevojitet:
- Të kopjojmë në clipboard dhe ta ngjisim në një redaktor, për shembull:
# nano vpn8.sh - të specifikojmë username dhe password për Yandex.Disk.
- në fushën "—ifconfig 10.45.54.(1 ose 2) 255.255.255.252" të specifikojmë adresën IP të brendshme të ndërfaqes
- të krijojmë secret.key me komandën:
# openvpn --genkey --secret secret.key - të bëjmë skriptin ekzekutues:
# chmod +x vpn8.sh - të nisim skriptin:
# ./vpn8.sh nZbVGBuX5dtturDku nZbVGBuX5dtturD është ID-lidhjes e gjeneruar këtu
Në nodin e largët të realizohet gjithçka njësoj përveç gjenerimit të secret.key dhe ID-lidhjes, ato duhet të jenë identike.
Varianti i përditësuar (për funksionim të saktë koha duhet të jetë e sinkronizuar):
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
Për të funksionuar skripti, nevojitet:
- Të kopjojmë në clipboard dhe ta ngjisim në një redaktor, për shembull:
# nano vpn10.sh - të specifikojmë username (rreshti 2) dhe password për Yandex.Disk (rreshti 3).
- të specifikojmë adresën IP të brendshme të tunelit (rreshti 4).
- të bëjmë skriptin ekzekutues:
# chmod +x vpn10.sh - të nisim skriptin:
# ./vpn10.sh nZbVGBuX5dtturDku nZbVGBuX5dtturD është ID-lidhjes e gjeneruar këtu
Në nodin e largët të realizohet gjithçka njësoj, të specifikohet adresa përkatëse e brendshme Adresa IP e tunelit dhe ID-lidhjes.
Për autostartin e skriptit kur ndizet, përdor komandën "nohup //vpn10.sh nZbVGBuX5dtturD > /var/log/vpn10.log 2>/dev/null &" e cila ndodhet në skedarin /etc/rc.local
Përfundim
Skripti funksionon, verifikuar në Ubuntu (18.04, 19.10, 20.04) dhe Debian 9. Si transmetues mund të përdorim çdo shërbim tjetër, por për eksperiencë kam përdorur Yandex.Disk.
Gjatë eksperimentimeve u zbulua se disa lloje NAT-s të ofruesve nuk lejojnë të organizohet lidhja. Kryesisht te operatorët celularë, ku torrentët janë të bllokuar.
Planifikoj ta përmirësoj në aspektin:
- Gjenenerimi automatik i secret.key çdo herë kur niset, enkriptimi dhe kopjimi në Yandex.Disk për të transmetuar në nyjën e largët (e marrë parasysh në versionin e përditësuar)
- Caktimi automatik i adresave IP për ndërfaqet
- Enkriptimi i të dhënave para shkarkimit në Yandex.Disk
- Optimizimi i kodit
Të jetë IPv6 në çdo shtëpi!
Përditësuar! Skedarët më të fundit dhe paketa DEB këtu — yandex.disk
Burimi: habr.com
