VPN क्लाइन्ट जोडिन्छ, ब्राउजर चल्छ, र तपाईंलाई साँच्चै चाहिएको त्यो एउटा आदेश अझै तपाईंको घरको जडानबाटै बाहिर जान्छ। वा उल्टो हुन्छ: टनेलले पूर्वनिर्धारित मार्ग समात्छ र स्थानीय फाइल सर्भर डेस्कटपबाट हराउँछ। मलाई यो एउटा बिल्ड एजेन्टसँग भयो, त्यसले आन्तरिक आर्टिफ्याक्ट मिररसम्म पुग्नुपर्थ्यो जबकि होस्टको बाँकी भाग कार्यालयको LAN मै रह्यो, र क्लाइन्टले ठ्याक्कै दुईवटा विकल्प दियो, सबै ट्राफिक वा केही पनि होइन। दुवैतर्फको अनुरोध एउटै हो, यो कार्यक्रम र पूरै मेसिन होइन, र धेरैजसो क्लाइन्टसँग यसका लागि जाँच बाकस छैन, किनकि मार्ग तालिकाले कार्यक्रम भनेको के हो भनेर कहिल्यै जान्दैन।

मार्ग तालिकाले तपाईंको कार्यक्रम किन देख्न सक्दैन

प्रक्रियाले प्याकेट पठाउँदा स्ट्याकले मार्ग तालिकामा गन्तव्य ठेगाना खोज्छ। निष्पादनयोग्यको नाम वा पोर्ट त्यो खोजीमा पस्दैन। डोमेन नामहरू पनि त्यही कारणले असफल हुन्छन्: टनेलले ट्राफिकलाई ठेगानासम्म लग्छ, र नाम ठेगानामा परिणत हुँदासम्म कर्नेलसँग बाँकी रहेको एक मात्र हतियार मार्गनिर्देशन हो। यसैले “यो साइटका लागि मात्र VPN” भन्नाले प्रोक्सी र “यो कार्यक्रमका लागि मात्र VPN” भन्नाले थोरै संख्याका संयन्त्रमध्ये एउटा भन्ने बुझिन्छ।

MechanismWhat selectsCoversOn tunnel drop
Socket bindsource addressa client you controlconnections fail
UID rule (Linux)owning userevery process of one accountconnections fail
Firewall profile (Windows)adapter profileone programfails closed
Network namespacenamespace membershipeverything started insideconnections fail
SOCKS hopapp proxy settingone app or one browser profileconnections fail

यीमध्ये कुनै पनि प्रति-प्रक्रिया मार्ग होइन। प्रत्येकले निर्णयलाई कार्यक्रम, प्रयोगकर्ता वा एपको आफ्नै कन्फिगरेसन देख्न सक्ने तहमा सार्छ।

एउटै गन्तव्य अझै मार्ग हो, कार्यक्रम नियम होइन। macOS मा सामान्य विधि “सबै ट्राफिक VPN माथि पठाउनुहोस्” को चिन्ह हटाएर होस्ट मार्ग थप्नु हो: sudo route add -host internal-tuner.example -interface ppp0, फेरि sudo route delete -host internal-tuner.example -interface ppp0 प्रयोग गरेर हटाइन्छ। पहिले ifconfig बाट इन्टरफेसको नाम पढ्नुहोस्, किनकि ppp0 एउटा उदाहरण मात्र हो। होस्ट मार्गमा वाइल्डकार्ड चल्दैन, त्यसैले धेरै नामसँग कुरा गर्ने सेवालाई प्रत्येक नामका लागि एउटा प्रविष्टि चाहिन्छ, र यो नियम मेसिनका सबै प्रक्रियामा लागू हुन्छ, तपाईंले सोचेको एउटामा मात्र होइन।

सकेटलाई टनेल ठेगानामा बाइन्ड गर्नुहोस्

तपाईंले क्लाइन्ट नियन्त्रण गर्दा बाइन्डिङ सबैभन्दा सस्तो छनोटकर्ता हो। टनेलको स्थानीय ठेगानामा बाइन्ड गरिएको सकेट त्यहाँ गन्तव्यको मार्ग भएसम्म त्यही इन्टरफेसबाट बाहिर जान्छ, र मेसिनमा बाँकी सबैले आफ्नो सामान्य बाटो राख्छ। सूक्ष्म कुरा के हो भने बाइन्डले स्रोत ठेगाना छान्छ तर मार्ग तालिकाले अझै निकास छान्छ। बाइन्ड मात्रले टनेलमा मार्ग नभएको ट्राफिक सार्दैन, र यही “मैले बाइन्ड गरें तर अझै गलत बाटो जान्छ” भन्ने धेरै रिपोर्टको पछाडिको गल्ती हो।

import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))

उच्च-स्तरका उपकरणहरूले यही विचार देखाउँछन्: curl --interface 10.8.0.2, PHP को CURLOPT_INTERFACE, र Python का HTTP क्लाइन्टमा source_address तर्क। ठेगाना टनेलको हुनुपर्छ, र यहाँको टाइपिङ गल्ती मार्गको गुनासो होइन, सामान्य जडान त्रुटिका रूपमा असफल हुन्छ। ठेगानाको सट्टा यन्त्रको नाममा बाइन्ड गर्नु Linux को विशेषाधिकार हो र Windows वा macOS मा सर्दैन, त्यसैले पोर्टेबल स्क्रिप्टहरूले ठेगाना पठाउँछन्।

Linux: कार्यक्रमको नाम होइन, मालिक मिलाउनुहोस्

कर्नेलले सकेटको मालिक प्रयोगकर्ता मिलाउन सक्छ, त्यसैले समर्पित खाता नै छनोटकर्ता बन्छ।

ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100

यो तब मात्र काम गर्छ जब टनेल पहिले नै पूर्वनिर्धारित मार्ग होइन। क्लाइन्टलाई --route-nopull सँग सुरु गर्नुहोस्, वा --pull-filter ignore "redirect-gateway" प्रयोग गरेर धकेलिएको रिडाइरेक्ट OpenVPN 2.4 र त्यसपछिका संस्करणमा फिल्टर गर्नुहोस्, अनि तालिका प्रविष्टि आफैं थप्नुहोस्। नत्र दुवै पूर्वनिर्धारित हुन्छन् र कम प्राथमिकताको जित्छ। यसको जानाजान गरिएको संस्करण पूर्वनिर्धारित मार्गलाई टनेल गेटवेतर्फ फर्काउनु वा डिस्कनेक्ट स्क्रिप्टबाट गर्नु हो: टनेल खस्दा यसले ट्राफिकलाई इन्टरनेटबाट टाढा राख्छ, तर त्यो किल स्विच हो, छनोटकर्ता होइन, र कसैले नहटाएसम्म रहन्छ।

अझ बलियो संस्करण नेटवर्क नेमस्पेस हो। यो बनाउनुहोस्, क्लाइन्ट भित्र चलाउनुहोस्, र एप्लिकेसनलाई ip netns exec सँग सुरु गर्नुहोस्। नेमस्पेस बाहिर कसैले टनेल इन्टरफेस देख्दैन, त्यसैले एप्लिकेसन दुर्घटनावश होस्ट मार्गमा फर्कन सक्दैन। लागत वास्तविक छ: नेमस्पेसलाई भौतिक नेटवर्कसम्म पुग्न veth जोडी र आफ्नै रिजोल्भर फाइल चाहिन्छ, किनकि माउन्ट नेमस्पेसले होस्टको रिजोल्युसन सेटिङ साझा गर्दैन।

दुई असफलता मोडले धेरैजसो चुहावट व्याख्या गर्छन्। नाम रिजोल्युसन अझै होस्टको रिजोल्भरमा हुन्छ, त्यसैले TCP जडान भित्र गए पनि क्वेरी टनेल बाहिर जान्छ। र IPv6 लाई आफ्नै ip -6 rule चाहिन्छ, किनकि v4 नियमले त्यसलाई समेट्दैन।

Windows र macOS: फायरवलको दायरा तोक्नुहोस् वा प्रोक्सी दिनुहोस्

Windows मा पनि प्रति-एप्लिकेसन मार्ग छनोटकर्ता छैन, तर त्यसका फायरवल नियम प्रोफाइलसम्म सीमित गर्न सकिन्छ, र VPN एडाप्टरलाई सार्वजनिकका रूपमा वर्गीकृत गर्न सकिन्छ जबकि घरको LAN निजी रहन्छ। निजी र डोमेन प्रोफाइलमा कार्यक्रमका लागि बाहिरी ब्लक नियम बनाउनुहोस्, सार्वजनिक खुला छोड्नुहोस्, अनि एप्लिकेसनले टनेलबाट मात्र नेटवर्कमा पुग्न सक्छ। पहिले जडानको नेटवर्क श्रेणी तोक्नुहोस्, अनि फायरवलको मोनिटर प्यानलमा नियम मिल्यो भनी पुष्टि गर्नुहोस्। यो मार्ग होइन, ब्लक हो: टनेल खस्दा यो बन्द भएर असफल हुन्छ, र फायरवललाई बेवास्ता गर्ने एप्लिकेसनलाई यसले रोक्न सक्दैन।

macOS ले उही तर्क फरक उपकरणसँग पछ्याउँछ। SSH मार्फत पुग्ने SOCKS स्रोता सबैभन्दा कम हस्तक्षेपको विकल्प हो, किनकि ssh -D 1080 user@host एउटा स्थानीय पोर्ट बनाउँछ र त्यसलाई प्रयोग गर्न मिलाइएका एप्लिकेसनले मात्र त्यो बाटो लिन्छन्। pf नियमले प्रयोगकर्ता वा समूहअनुसार कार्यक्रम ब्लक गर्न सक्छ, तर त्यसले त्यो कार्यक्रमका लागि मात्र टनेल छान्न सक्दैन। Tunnelblick ले डोमेनअनुसार फिल्टर गर्न सक्दैन, किनकि मार्गहरू ठेगानामा चल्छन्; OpenConnect प्रयोगकर्ताहरूले सर्भरले धेरै फराकिलो प्रिफिक्स सूची धकेल्दा vpn-slice तिर जान्छन्।

प्लेटफर्म उपकरणले छुटाएको कुरा दुई उपायले समेट्छन्। डोमेनअनुसार प्रोक्सी फेर्ने ब्राउजर एक्सटेन्सन “यो साइट मात्र” का लागि व्यावहारिक उत्तर हो, किनकि तिनी नाम अझै रहेको एप्लिकेसन तहमा काम गर्छन्; तिनी एउटा ब्राउजर मात्र समेट्छन्, अरू केही होइन। ठूलो उपाय भनेको विक्रेताको क्लाइन्टलाई भर्चुअल मेसिनभित्र चलाउनु हो, ताकि पाहुना मार्ग परिवर्तनको मालिक बन्छ र होस्ट आफ्नो बाटो राख्छ, तर दुई नेटवर्क स्ट्याक सञ्चालन गर्ने लागत पर्छ।

बाइन्ड विकल्प नभएका उपकरणका लागि SOCKS हप

धेरैजसो एप्लिकेसनलाई HTTP वा SOCKS प्रोक्सीतिर फर्काउन सकिन्छ, तिनलाई इन्टरफेसबारे केही थाहा नभए पनि। SSH क्लाइन्टले सर्भरतर्फ कुनै परिवर्तन नगरी एउटा दिन्छ:

ssh -N -D 127.0.0.1:9999 [email protected]

त्यो पोर्ट प्रयोग गर्न मिलाइएको सबै बास्टियनबाट बाहिर जान्छ, जबकि बाँकी डेस्कटपले आफ्नो सामान्य जडान राख्छ। टनेल ठेगानामा बाइन्ड गरिएको स्थानीय 3proxy इन्स्टेन्सले SSH बिना एउटा पोर्टका लागि यही काम गर्छ, र stunnel ले TLS मा बेरिएको एउटै पोर्ट समेट्छ। सीमा व्यावहारिक छन्: प्रोक्सीले त्यसलाई प्रयोग गर्न जान्ने प्रोटोकल मात्र बोक्छ, UDP लाई SOCKS5 UDP सहयोग चाहिन्छ जुन धेरै क्लाइन्टको “SOCKS5” सेटिङले सक्रिय गर्दैन, र DNS प्रोक्सीले नै रिजोल्भ गर्नुपर्छ (curl मा socks5h) नत्र नाम स्थानीय रिजोल्भरमा चुहिन्छ।

अर्को मेसिनलाई आवश्यक नभएसम्म स्रोतालाई लूपब्याकमै राख्नुहोस्।

स्थिति सन्देशले होइन, क्याप्चरले बाटो पुष्टि गर्नुहोस्

एप्लिकेसन स्थिति विन्डोहरूले सेटिङ वर्णन गर्छन्, प्याकेट होइन। दुवै इन्टरफेसमा क्याप्चर गरेर तुलना गर्नुहोस्:

tcpdump -i any -n port 443
ss -tnp | grep 443

जडान भौतिक इन्टरफेसमा टनेलमा मिल्ने प्रविष्टि बिना देखिएमा, क्लाइन्टले के रिपोर्ट गरे पनि छनोटकर्ता लागू छैन। IPv6 र रिजोल्भर छुट्टाछुट्टै जाँच्नुहोस्, र सहायक प्रक्रिया वा वंशानुगत प्रणाली प्रोक्सीजस्तो दोस्रो बाटो पनि जाँच्नुहोस्।

अनि आवश्यकतासँग मिल्ने सीमा छान्नुहोस्: एउटा साइटका लागि प्रोक्सी पर्याप्त छ, एउटा खाताका लागि UID नियम पर्याप्त छ, जडान बन्द भएर असफल हुनुपर्ने भए फायरवल प्रोफाइल पर्याप्त छ, र बाहिरका सबैबाट टनेल लुकाउने एक मात्र विकल्प नेमस्पेस हो।

सम्बन्धित लेखहरू