Vazhdim artikullit rreth mënyrës se si arrita të organizoj një VPN-tunel midis dy kompjuterëve që ndodhen pas NAT’ëve të ofruesëve. 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 i cili luante rolin e diçkaje si server STUN dhe transmetues të të dhënave për lidhje). Në këtë artikull do të tregoj si funksionova pa VPS, por ndërmjetësit mbetën dhe ata ishin serveri STUN dhe Yandex.Disk...
Hyrje
Pas leximit të komenteve të postit të kaluar, kuptova se disavantazhi kryesor i zbatimit ishte përdorimi i një ndërmjetësi — palës së tretë (VPS) e cila tregonte parametrat aktualë të nodit, ku dhe si të lidhen. Duke marrë parasysh rekomandimet për të përdorur një STUN të vërtetë (të cilët janë shumë të shumtë) për të përcaktuar parametrat aktualë të lidhjes. E para që bëra ishte të shihja me ndihmën e TCPDump përmbajtjen e paketave gjatë punës së serverit STUN me klientët dhe mora një përmbajtje krejtësisht të papërshkrueshme. Duke kërkuar në Google për protokollin, u ndesha me një artikull që përshkruan protokollin. Kuptova se që nuk mund ta realizoj vetë kërkesën për serverin STUN dhe e vendosa idenë në "kutinë e largët".
Teoria
Kohët e fundit, më shpërnguli të instaloj serverin STUN në Debian nga paketa
# apt install stun-serverdhe në varësi kam parë paketën stun-client, por nuk i dhamë shumë rëndësi. Më vonë m'u kujtua për paketën stun-client dhe vendosa të kuptoj se si funksionon, duke kërkuar në Google dhe Yandex kam marrë:
# apt install stun-client
# stun stun.ekiga.net -p 21234 -v
Në përgjigje kam marrë:
Versioni i klientit STUN 0.97
Hapja e portit 21234 me fd 3
Hapja e portit 21235 me fd 4
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 0Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Mora një mesazh STUN: 92 bytes
MappedAddress = :2885
SourceAddress = 216.93.246.18:3478
ChangedAddress = 216.93.246.17:3479
Atribut i panjohur: 32800
ServerName = Vovida.org 0.98-CPC
Mora një mesazh me tip 257 id=1
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 0Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.17:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 0Duke u dërguar një mesazh me gjatësi 28 në :2885
Mora një mesazh STUN: 28 bytes
ChangeRequest = 0
Mora një mesazh me tip 1 id=11
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 0Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.17:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Mora një mesazh STUN: 92 bytes
MappedAddress = :2885
SourceAddress = 216.93.246.17:3479
ChangedAddress = 216.93.246.18:3478
Atribut i panjohur: 32800
ServerName = Vovida.org 0.98-CPC
Mora një mesazh me tip 257 id=10
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 4Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
Kodimi i mesazhit STUN:
Kodimi i ChangeRequest: 2Duke u dërguar një mesazh me gjatësi 28 në 216.93.246.18:3478
test I = 1
test II = 0
test III = 0
test I(2) = 1
is nat = 1
mapped IP i njëjtë = 1
hairpin = 1
preserver port = 0
Primar: Hartim i Pavarur, Filtri i Varësisë së Portit, port i rastësishëm, do të hairpin
Vlera e kthimit është 0x000006
String me vlerën
MappedAddress = :2885
pikërisht ajo që duhet! Ajo shfaqte gjendjen aktuale për lidhjen në portin lokal UDP 21234. Por kjo është vetëm gjysma e punës, lind pyetjes si të transferojmë këto të dhëna te nodi i largët dhe të organizojmë një lidhje VPN. Përdorimi i protokollit të postës, ndoshta Telegram?! Ka shumë mundësi dhe vendosa të përdor Yandex.Disk, sepse më ishte paraqitur artikulli për funksionimin e Curl përmes WebDav me Yandex.Disk. Duke menduar për realizimin erdha në këtë skemë:
- Të sinjalizosh gatishmërinë e nodëve për të instaluar lidhjen me praninë e një skedari të caktuar me një timestamp në Yandex.Disk;
- Nëse nodët janë gati, atëherë të marrë parametrit aktual nga serveri STUN;
- Të eksportosh parametrat aktualë në Yandex.Disk;
- Të kontrollosh praninë dhe të lexosh parametrat e nodit të largët nga skedari në Yandex.Disk;
- Krijimi i lidhjes me nodin e largët duke përdorur OpenVPN.
Praktika
Pas disa reflektimesh, duke marrë parasysh përvojën e artikullit të kaluam, shkrova një skenar shpejt. Na nevojitet:
# apt install openvpn stun-client curl Vërtet skenari vetë:
Këtu është versioni 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 skenari nevojitet:
- Kopjoni në bufer dhe ngjisni në redaktor, për shembull:
# nano vpn8.sh - të specifikoni emrin e përdoruesit dhe fjalëkalimin për Yandex.Disk.
- në fushën «—ifconfig 10.45.54.(1 ose 2) 255.255.255.252» përcaktoni adresën IP të brendshme të ndërfaqes
- krijoni secret.key komandën:
# openvpn --genkey --secret secret.key - bëni skriptin ekzekutues:
# chmod +x vpn8.sh - startoni skriptin:
# ./vpn8.sh nZbVGBuX5dtturDku nZbVGBuX5dtturD — ID-llaku i gjeneruar këtu
Në host-in e largët bëni gjithçka të njëjtë, përveç gjenerimit të secret.key dhe ID-llakut, ato duhet të jenë identike.
Versioni i përmirë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 skenari nevojitet:
- Kopjoni në bufer dhe ngjisni në redaktor, për shembull:
# nano vpn10.sh - në përcaktoni emrin e përdoruesit (rreshti 2) dhe fjalëkalimin e Yandex.disk (rreshti 3).
- në përcaktoni adresën IP të brendshme të tunelit (rreshti 4).
- bëni skriptin ekzekutues:
# chmod +x vpn10.sh - startoni skriptin:
# ./vpn10.sh nZbVGBuX5dtturDku nZbVGBuX5dtturD — ID-llaku i gjeneruar këtu
Në host-in e largët bëni gjithçka të njëjtë, përcaktoni përkatësisht brendshëm IP-adresa tunelit dhe ID-llakut.
Për të aktivizuar skriptin automatikisht në ndezje unë përdor komandën «nohup //vpn10.sh nZbVGBuX5dtturD > /var/log/vpn10.log 2>/dev/null &» që gjendet në dosjen /etc/rc.local
Përfundimi
Skripti punon, është provuar në Ubuntu (18.04, 19.10, 20.04) dhe Debian 9. Si transmetues mund të përdorni çdo shërbim tjetër, por për eksperiencë kam përdorur Yandex.disk.
Gjatë eksperimenteve u zbulua se disa lloje NAT të ofruesve nuk lejojnë organizimin e lidhjes. Kryesisht te operatorët celularë, ku torrentet janë të bllokuara.
Po planifikim për të përmirësuar në aspektin e:
- Krijimit automatitik të secret.key çdo herë që nis, encryptimi dhe kopjimi në Yandex.disk për transferim në nyjën e largët (merrni parasysh në versionin e përmirësuar)
- Caktimit automatik të adresave IP të ndërfaqeve
- Enkriptimi i të dhënave para se të ngarkohet në Yandex.disk
- Optimizimi i kodit
Të ketë IPv6 në çdo shtëpi!
E përditësuar! Skedarët e fundit dhe paketa DEB këtu — yandex.disk
Burimi: habr.com
