प्रोहोस्टर > ब्लॉग > प्रशासन > प्रदाताओं के NAT के माध्यम से कंप्यूटरों के बीच सीधी वीपीएन सुरंग (VPS के बिना, STUN सर्वर और Yandex.disk का उपयोग करके)
प्रदाताओं के NAT के माध्यम से कंप्यूटरों के बीच सीधी वीपीएन सुरंग (VPS के बिना, STUN सर्वर और Yandex.disk का उपयोग करके)
विस्तार लेख इस बारे में कि मैं NAT प्रदाताओं के पीछे स्थित दो कंप्यूटरों के बीच एक सीधी वीपीएन सुरंग कैसे व्यवस्थित करने में कामयाब रहा। पिछले लेख में एक तीसरे पक्ष की मदद से कनेक्शन व्यवस्थित करने की प्रक्रिया का वर्णन किया गया था - एक मध्यस्थ (एक किराए का वीपीएस एक STUN सर्वर और कनेक्शन के लिए एक नोड डेटा ट्रांसमीटर की तरह कार्य करता है)। इस लेख में मैं आपको बताऊंगा कि मैंने VPS के बिना कैसे प्रबंधन किया, लेकिन मध्यस्थ बने रहे और वे STUN सर्वर और Yandex.Disk थे...
परिचय
पिछली पोस्ट की टिप्पणियों को पढ़ने के बाद, मुझे एहसास हुआ कि कार्यान्वयन का मुख्य दोष एक मध्यस्थ का उपयोग था - एक तृतीय पक्ष (वीपीएस) जो नोड के वर्तमान मापदंडों को इंगित करता था, कहां और कैसे कनेक्ट करना है। इस STUN का उपयोग करने की अनुशंसाओं पर विचार करते हुए (जिनमें से बहुत सारे हैं) वर्तमान कनेक्शन पैरामीटर निर्धारित करने के लिए। सबसे पहले, मैंने पैकेट की सामग्री को देखने के लिए टीसीपीडम्प का उपयोग करने का निर्णय लिया जब STUN सर्वर क्लाइंट के साथ काम कर रहा था और पूरी तरह से अपठनीय सामग्री प्राप्त कर रहा था। गूगल पर मुझे जो प्रोटोकॉल मिला, वह मिला प्रोटोकॉल का वर्णन करने वाला आलेख. मुझे एहसास हुआ कि मैं अपने दम पर STUN सर्वर के लिए अनुरोध लागू नहीं कर सका और विचार को "दूरस्थ बॉक्स" में डाल दिया।
Теория
हाल ही में मुझे पैकेज से डेबियन पर STUN सर्वर स्थापित करना पड़ा
# apt install stun-server
और निर्भरता में मैंने स्टन-क्लाइंट पैकेज देखा, लेकिन किसी तरह मैंने इस पर ध्यान नहीं दिया। लेकिन बाद में मुझे स्टन-क्लाइंट पैकेज के बारे में याद आया और मैंने यह पता लगाने का फैसला किया कि यह कैसे काम करता है, गूगल पर खोजने और यांडेक्स में खोजने के बाद मुझे मिला:
स्टन क्लाइंट संस्करण 0.97
एफडी 21234 के साथ पोर्ट 3 खोला गया
एफडी 21235 के साथ पोर्ट 4 खोला गया
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 0
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
प्राप्त स्तब्ध संदेश: 92 बाइट्स
मैप्डएड्रेस = <मेरा आईपी>:2885
स्रोत पता = 216.93.246.18:3478
बदला हुआ पता = 216.93.246.17:3479
अज्ञात विशेषता: 32800
सर्वरनाम = Vovida.org 0.98-सीपीसी
257 id=1 प्रकार का संदेश प्राप्त हुआ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 0
लेन 28 का संदेश 216.93.246.17:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 0
लेन 28 का संदेश <माई आईपी>:2885 पर भेजने वाला हूं
प्राप्त स्तब्ध संदेश: 28 बाइट्स
चेंज रिक्वेस्ट = 0
1 id=11 प्रकार का संदेश प्राप्त हुआ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 0
लेन 28 का संदेश 216.93.246.17:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
प्राप्त स्तब्ध संदेश: 92 बाइट्स
मैप्डएड्रेस = <मेरा आईपी>:2885
स्रोत पता = 216.93.246.17:3479
बदला हुआ पता = 216.93.246.18:3478
अज्ञात विशेषता: 32800
सर्वरनाम = Vovida.org 0.98-सीपीसी
257 id=10 प्रकार का संदेश प्राप्त हुआ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 4
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
स्टन संदेश एन्कोडिंग:
एन्कोडिंग चेंज रिक्वेस्ट: 2
लेन 28 का संदेश 216.93.246.18:3478 पर भेजने वाला हूँ
परीक्षण मैं = 1
परीक्षण II = 0
परीक्षण III = 0
परीक्षण I(2) = 1
नेट = 1 है
मैप किया गया आईपी समान = 1
हेयरपिन = 1
प्रिज़र्वर पोर्ट = 0
प्राथमिक: स्वतंत्र मैपिंग, पोर्ट डिपेंडेंट फ़िल्टर, रैंडम पोर्ट, विल हेयरपिन
वापसी मान 0x000006 है
मूल्य के साथ स्ट्रिंग
मैप्डएड्रेस = <मेरा आईपी>:2885
बस आपको क्या चाहिए! इसने स्थानीय यूडीपी पोर्ट 21234 पर कनेक्शन की वर्तमान स्थिति प्रदर्शित की। लेकिन यह केवल आधी लड़ाई है; सवाल यह उठा कि इस डेटा को दूरस्थ होस्ट में कैसे स्थानांतरित किया जाए और वीपीएन कनेक्शन को व्यवस्थित किया जाए। मेल प्रोटोकॉल, या शायद टेलीग्राम का उपयोग करना?! कई विकल्प हैं और जब से मुझे यह जानकारी मिली, मैंने Yandex.disk का उपयोग करने का निर्णय लिया Yandex.disk के साथ WebDav के माध्यम से कर्ल कार्य करने के बारे में लेख. कार्यान्वयन के बारे में सोचने के बाद, मैं निम्नलिखित योजना लेकर आया:
Yandex.disk पर टाइमस्टैम्प के साथ एक विशिष्ट फ़ाइल की उपस्थिति से संकेत मिलता है कि नोड्स कनेक्शन स्थापित करने के लिए तैयार हैं;
यदि नोड्स तैयार हैं, तो STUN सर्वर से वर्तमान पैरामीटर प्राप्त करें;
Yandex.disk पर वर्तमान सेटिंग्स अपलोड करें;
Yandex.disk पर किसी फ़ाइल से दूरस्थ नोड की उपस्थिति की जाँच करें और पैरामीटर पढ़ें;
OpenVPN का उपयोग करके दूरस्थ होस्ट के साथ कनेक्शन स्थापित करना।
अभ्यास
थोड़ा सोचने के बाद, पिछले लेख के अनुभव को ध्यान में रखते हुए, मैंने तुरंत एक स्क्रिप्ट लिखी। हमें ज़रूरत होगी:
# apt install openvpn stun-client curl
स्क्रिप्ट स्वयं:
मूल संस्करण
# 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
स्क्रिप्ट पर काम करने के लिए आपको चाहिए:
क्लिपबोर्ड पर कॉपी करें और संपादक में पेस्ट करें, उदाहरण के लिए:
# nano vpn8.sh
Yandex.disk के लिए उपयोगकर्ता नाम और पासवर्ड निर्दिष्ट करें।
फ़ील्ड में "-ifconfig 10.45.54.(1 या 2) 255.255.255.252" इंटरफ़ेस का आंतरिक आईपी पता निर्दिष्ट करें
दूरस्थ नोड पर, वही करें, सुरंग और कनेक्शन आईडी का संबंधित आंतरिक आईपी पता निर्दिष्ट करें।
चालू होने पर स्क्रिप्ट को स्वचालित रूप से चलाने के लिए, मैं फ़ाइल /etc/ में निहित कमांड "nohup / <स्क्रिप्ट का पथ>/vpn10.sh nZbVGBuX5dtturD > /var/log/vpn10.log 2>/dev/null &" का उपयोग करता हूं। rc.स्थानीय
निष्कर्ष
स्क्रिप्ट काम करती है, उबंटू (18.04, 19.10, 20.04) और डेबियन 9 पर परीक्षण किया गया। आप ट्रांसमीटर के रूप में किसी अन्य सेवा का उपयोग कर सकते हैं, लेकिन अनुभव के लिए मैंने Yandex.disk का उपयोग किया।
प्रयोगों के दौरान, यह पता चला कि कुछ प्रकार के NAT प्रदाता कनेक्शन स्थापित करने की अनुमति नहीं देते हैं। मुख्य रूप से मोबाइल ऑपरेटरों से जहां टोरेंट अवरुद्ध हैं।
मैं इनमें सुधार करने की योजना बना रहा हूं:
हर बार जब आप प्रारंभ करते हैं, तो गुप्त कुंजी की स्वचालित पीढ़ी, एन्क्रिप्ट करें और दूरस्थ नोड में स्थानांतरण के लिए Yandex.disk पर कॉपी करें (अद्यतन संस्करण को ध्यान में रखते हुए)
इंटरफेस के आईपी पते का स्वचालित असाइनमेंट
Yandex.disk पर अपलोड करने से पहले डेटा एन्क्रिप्ट करना
कोड अनुकूलन
हर घर में IPv6 हो!
अपडेट किया गया! नवीनतम फ़ाइलें और DEB पैकेज यहाँ - यांडेक्स.डिस्क