इस वर्कस्टेशन से बाहर निकलने का एक रास्ता SOCKS प्रॉक्सी है, और उसके पीछे OpenVPN बिना किसी उपयोगी विवरण के कनेक्ट टाइमआउट की सूचना देता है। उसी मशीन का ब्राउज़र उस प्रॉक्सी से काम करता है, क्रेडेंशियल सही हैं, और पोर्ट जवाब देता है। तीन चीजें इतनी अलग होती हैं कि पहले जाँची जानी चाहिए: प्रॉक्सी जो SOCKS संस्करण बोलता है, क्लाइंट ने जो ट्रांसपोर्ट चुना, और वह जगह जहाँ नाम विश्लेषण होता है। फ़ायरवॉल को दोषी मानने से पहले इनमें से हर एक की पुष्टि करें।

फ़ायरवॉल से पहले SOCKS संस्करण का मिलान करें

समुदायिक OpenVPN socks-proxy के लिए SOCKS5 बोलता है। इसे ऐसी प्रॉक्सी पर लगाएँ जो केवल SOCKS4 देती हो; TCP कनेक्शन खुलता है और फिर रुक जाता है, क्योंकि क्लाइंट ऐसे अभिवादन के उत्तर की प्रतीक्षा करता है जिसे दूसरा छोर कभी पार्स नहीं करता। बाहर से यह ठहराव बिल्कुल फ़िल्टर किए गए पोर्ट जैसा दिखता है, इसीलिए संस्करण का सवाल किसी भी फ़ायरवॉल नियम से पहले आता है। SOCKS-सजग फ़ेच इसे एक ही कमांड में तय कर देता है।

curl --socks5-hostname 127.0.0.1:9050 gw.lab.example

पूरा हुआ अनुरोध एक साथ दो बातें साबित करता है: प्रॉक्सी ने SOCKS अनुरोध स्वीकार किया और उसने नाम विश्लेषित किया। किसी URL स्कीम की ज़रूरत नहीं, क्योंकि curl नंगे होस्ट को HTTP मानता है, और यह इस परीक्षण के लिए पर्याप्त है।

यह फ़ेच उस विफलता को भी बाहर करता है जिसे क्लाइंट लॉग छिपाता है। प्रॉक्सी ब्राउज़र को अनुमति देकर भी VPN गंतव्य को अस्वीकार कर सकती है, और तब अस्वीकृति CONNECT पर होती है, किसी भी VPN प्रमाणीकरण से पहले। OpenVPN केवल टाइमआउट बताता है, इसलिए प्रॉक्सी का अपना उत्तर वह प्रमाण है जिसकी आपको ज़रूरत है।

ट्रांसपोर्ट दोनों ओर TCP होना चाहिए

SOCKS5 यहाँ TCP स्ट्रीम ले जाता है, इसलिए सुरंग को ही proto tcp-client चाहिए। जो प्रोफ़ाइल अब भी UDP पर सेट है वह इस पथ से काम नहीं करेगी, क्योंकि क्लाइंट प्रोटोकॉल के UDP एसोसिएशन मोड का उपयोग नहीं करता। प्रोफ़ाइल पलटना असली बदलाव है, औपचारिकता नहीं: दूर के छोर को उसी पोर्ट पर TCP पर सुनना होगा। फिर पेलोड TCP के भीतर TCP बन जाता है, जहाँ खोया सेगमेंट दो बार फिर भेजा जाता है और गति गिरती है, जिसे इंटरैक्टिव सत्र बड़े स्थानांतरणों से कहीं अधिक महसूस करते हैं।

proto tcp-client
remote gw.lab.example 8443
socks-proxy 127.0.0.1 9050

यह निर्देश प्रॉक्सी होस्ट, वैकल्पिक पोर्ट और वैकल्पिक क्रेडेंशियल फ़ाइल लेता है। उन्हें प्रोफ़ाइल में ही रखें ताकि कहीं और रखी प्रति वैसा ही व्यवहार करे।

पूरी श्रृंखला को एक कंटेनर में सीमित करें

श्रृंखला को होस्ट पर करने का अर्थ है उसका डिफ़ॉल्ट रूट ले लेना और resolver को ऐसी स्थिति में छोड़ देना जिसे बाद में कोई समझा न सके। नेमस्पेस या कंटेनर इसे सीमित करता है, इसलिए होस्ट अपना पथ रखता है जबकि SOCKS हॉप और सुरंग साथ रहते हैं। उसके भीतर कुछ भी सुरंग डिवाइस, उस डिवाइस को कॉन्फ़िगर करने के अधिकार और पहुँच योग्य प्रॉक्सी के बिना नहीं उठता। Compose सेवा यह cap_add: NET_ADMIN और bind-माउंट किए गए /dev/net/tun से पाती है।

cap_add:
  - NET_ADMIN
devices:
  - /dev/net/tun:/dev/net/tun

यह जोड़ी कंटेनर को privileged चलाने से अधिक संकरी है, और डिवाइस पहुँच का पूरा आवश्यक हिस्सा यही है। Tor क्लाइंट या अलग प्रॉक्सी कंटेनर श्रोता दे सकता है। दोनों स्थितियों में इसे loopback पर बाँधें, और प्रॉक्सी को नेटवर्क पर उजागर करने के बजाय नेमस्पेस से होस्ट के रास्ते इस तक पहुँचें।

नाम विश्लेषण वह जगह है जहाँ अलगाव विफल होता है

जो सुरंग पैकेट ले जाती है पर होस्ट के resolver से पूछती है उसने कुछ भी अलग नहीं किया। दो बातें अलगाव को असली बनाती हैं: नेमस्पेस का अपना resolver होना, और उसकी क्वेरीज़ का प्रॉक्सी या सुरंग से जाना, कभी भौतिक इंटरफ़ेस से नहीं। परीक्षण के लिए दो नाम लें: एक जो केवल सुरंग के पीछे मौजूद हो, और एक सार्वजनिक जिसे वही पथ लेना चाहिए।

docker compose exec vpn cat /etc/resolv.conf
docker compose exec vpn getent hosts internal.lab.example

यदि दूर का नाम विश्लेषित होता है और सार्वजनिक नहीं, तो श्रृंखला चयनात्मक है, टूटी नहीं, और अंतर बताता है कि हर क्वेरी ने कौन सा पथ लिया। यदि दोनों होस्ट से विश्लेषित होते हैं पर कंटेनर के भीतर कोई नहीं, तो कंटेनर अब भी होस्ट का resolver उधार ले रहा है। जो resolver फ़ाइल मिली उसे दर्ज करें, क्योंकि वही सेटिंग है जिसे बदलना है।

हर हॉप को क्रम में साबित करें

सूची छोटी है। एक SOCKS5 अनुरोध को उत्तर मिलता है, सुरंग प्रॉक्सी के रास्ते अपने श्रोता तक पहुँचती है, और नेमस्पेस से निकलने वाले पैकेट वह पता ले जाते हैं जिसकी दूर का छोर अपेक्षा करता है। अधिक कॉन्फ़िगरेशन जोड़ने के बजाय हर एक को अलग-अलग पुष्टि करें। जब क्लाइंट कहे कि जुड़ा हुआ है और कुछ नहीं हिलता, तो टूटन लगभग हमेशा दूसरे या तीसरे तथ्य में होती है।

curl --socks5-hostname 127.0.0.1:9050 gw.lab.example
docker compose exec vpn ip route get 203.0.113.10
docker compose exec vpn getent hosts internal.lab.example

जो संयोजन काम कर गया उसे लिख लें: SOCKS संस्करण, ट्रांसपोर्ट, resolver और नेमस्पेस सेटिंग्स। इस श्रृंखला को दूसरी बार याद से हल करना नोट से अधिक महँगा है। वे चार तथ्य टिकट में रखें, चैट थ्रेड में नहीं।

जो श्रृंखला जुड़ा हुआ बताती है और कुछ नहीं गुज़ारती, वह आमतौर पर उसी हॉप पर विफल हुई है जिसे आपने अभी साबित नहीं किया। अगली परत जोड़ने से पहले उस हॉप को जाँचें।

संबंधित लेख