fwmark प्रयोग गरी एउटै Linux होस्टमा दुई OpenVPN क्लाइन्ट जोड्नुहोस्
दुवै क्लाइन्टलाई डिफल्ट रुट चाहिन्छ। भित्री सर्भरलाई होस्ट रुटले पिन गर्नुहोस्, दोस्रो क्लाइन्टलाई तालिका पुनः लेख्नबाट रोक्नुहोस्, अनि fwmark ले प्रवाह मोड्नुहोस्।
एउटै Linux होस्टमा दोस्रो OpenVPN क्लाइन्ट जोड्दा दुईमध्ये एउटा ठाउँमा असफल हुन्छ। या त भित्री क्लाइन्ट आफ्नै सर्भरसम्म पुग्न सक्दैन किनकि बाहिरी सुरुङले त्यो यातायात कब्जा गरेको छ, या दोस्रो क्लाइन्टले रुट तालिका पुनः लेख्छ र पहिलो सुरुङ काम गर्न छोड्छ। दुवै समस्या राउटिङमा छन्, इन्क्रिप्शनमा होइन, र दुवै नयाँ सुरुङले कुनै पनि अनुप्रयोग ट्राफिक बोक्नुअघि समाधान हुन्छन्। यहाँका ठेगानाहरू उदाहरणका लागि हुन्: tun0 बाहिरी सुरुङ हो, 203.0.113.9 भित्री सर्भर हो, र TCP 9999 त्यो प्रवाह हो जसले भित्री बाटो प्रयोग गर्नुपर्छ।
दुई असफलता मोड, एउटै रुट तालिका
भित्री क्लाइन्टले आफ्नो सर्भरतर्फ UDP सकेट खोल्छ, र त्यो सकेट अरू जस्तै हालको रुट तालिका पछ्याउँछ। यदि बाहिरी सुरुङसँग पहिले नै डिफल्ट छ भने, ह्यान्डशेक प्याकेट बाहिरी सुरुङमा जान्छन्। त्यो तब मात्र काम गर्छ जब बाहिरी सर्भर भित्री सर्भरसम्म पुग्न सक्छ र अर्को पक्ष प्रवाह बोक्न सहमत हुन्छ; अन्यथा ह्यान्डशेक रोकिन्छ र क्लाइन्ट फेरि प्रयास गर्छ।
दोस्रो असफलता सर्भरको push बाट आउँछ। सामान्य push redirect-gateway def1 हो, जसले डिफल्ट रुट प्रतिस्थापन गर्नुको सट्टा 0.0.0.0/1 र 128.0.0.0/1 स्थापना गर्छ। त्यसैले आफ्नै /1 जोडी स्थापना गर्ने दुई क्लाइन्ट ठोक्किन्छन्, र लगभग हरेक गन्तव्यका लागि नयाँ जोडी जित्छ। दोस्रो जोडिएपछि सुरुङ मर्दा तालिकामा ती दुई प्रिफिक्स खोज्नुहोस्, किनकि डिफल्ट रुट आफैं कहिल्यै नबदलिएको हुन सक्छ।
प्रवाहलाई चिन्ह लगाउनुहोस् र त्यसलाई तालिका दिनुहोस्
छानिएको ट्राफिकलाई mangle तालिकामा चिन्ह लगाएर र नीति नियममा त्यो चिन्ह मिलाएर मोड्नुहोस्। नियमले डिफल्ट रुट भित्री यन्त्र भएको समर्पित तालिकातर्फ संकेत गर्छ, त्यसैले चिन्ह लगाइएका प्याकेट मात्र भित्री बाटो लिन्छन्।
iptables -t mangle -A PREROUTING -p tcp -m multiport --dport 9999 -j MARK --set-mark 0x9999
ip rule add fwmark 0x9999 table 200 pref 1000
ip route add default dev tun1 table 200यो नियम समूहका अधिकांश असफलता दुई गल्तीबाट आउँछन्। फायरवालले सेट गर्ने चिन्ह मान र नियमले मिलाउने मान एकै हुनुपर्छ, किनकि फरकले त्रुटि वा प्रभाव दिँदैन। र PREROUTING ले बाहिरबाट आउने प्याकेट मात्र देख्छ, त्यसैले यो होस्टमा सुरु भएको जडानलाई चिन्ह लाग्नुअघि नै त्यही मिलान भएको OUTPUT नियम चाहिन्छ।
दोस्रो क्लाइन्टबाट रुटको स्वामित्व खोस्नुहोस्
दुई विकल्पले दोस्रो क्लाइन्टलाई तालिका सम्पादन गर्नबाट रोक्छन्, र ती फरक बिन्दुमा काम गर्छन्। route-nopull ले push गरिएका रुट विकल्प बेवास्ता गर्छ, त्यसैले केही पनि स्थापना हुँदैन। route-noexec ले push गरिएका विकल्प क्लाइन्टको वातावरणमा स्वीकार्छ तर तालिका परिवर्तन hook मा छोड्छ, र सर्भरले के प्रस्ताव गर्यो हेर्नुपर्दा तपाईंलाई यही चाहिन्छ।
Hook ले push गरिएका मानहरूसँग आफ्नै वातावरणमा चल्छ, र यसले तपाईंले स्वीकृत गरेका प्रविष्टि मात्र थप्नुपर्छ। यसलाई idempotent बनाउनुहोस्: पुनः निर्माण गर्नुअघि यसको स्वामित्वको तालिका खाली गर्नुहोस्, र अघिल्लो पटकले सफा अवस्था छोड्यो भनी नमान्नुहोस्। पुनः जडानले hook फेरि बोलाउँछ, र सफा नगरी थप्ने hook ले दोहोरिएका रुट जम्मा गर्छ।
एउटा मालिक छान्नुहोस् र त्यो लेख्नुहोस्। दुवै विकल्प सेट गर्ने प्रोफाइल, वा हातले लेखिएको स्क्रिप्टसँग प्रतिस्पर्धा गर्ने hook ले पछि कसैले पनि व्याख्या गर्न नसक्ने तालिका बनाउँछ।
दुवै सर्भर ठेगाना पिन गर्नुहोस्
भित्री क्लाइन्ट जोडिनुअघि भित्री सर्भरलाई बाहिरी यन्त्रबाट होस्ट रुट चाहिन्छ। त्यही प्रविष्टिले भित्री यातायातलाई डिफल्ट पछ्याउन नदिई बाहिरी सुरुङभित्र राख्छ।
ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9मुख्य तालिकामा बाहिरी सर्भरका लागि पनि मिल्दो होस्ट रुट थप्नुहोस्, अन्यथा पुनः जडानले बाहिरी क्लाइन्टको आफ्नै यातायात त्यसकै सुरुङमा रुट गर्न सक्छ। क्रम वैकल्पिक होइन: सम्बन्धित इन्टरफेस अस्तित्वमा आएपछि यी प्रविष्टि थप्नुहोस्, अर्थात् जडानपछि चल्ने hook वा स्क्रिप्ट। बन्द यन्त्रतर्फ संकेत गर्ने रुट हटाइन्छ वा बेवास्ता गरिन्छ, त्यसैले बुटको समयमा लेखिएको प्रविष्टि तपाईंले मानेको क्रममा टिक्दैन।
पूरै तालिका पढ्नुको सट्टा खोज जाँच्नुहोस्। रुट खोजको आउटपुटले kernel प्रयोग गर्ने यन्त्र र स्रोत ठेगाना बताउँछ, र क्लाइन्टले सकेट खोल्दा ठ्याक्कै त्यही पाउँछ।
शृंखला परीक्षण गर्नुहोस् र असफलता देखिने बनाउनुहोस्
भित्री क्लाइन्ट जोडिँदै गर्दा बाहिरी इन्टरफेसमा क्याप्चर गर्नुहोस्। भित्री ह्यान्डशेक बाहिरी सुरुङभित्र इन्क्रिप्टेड पेलोडका रूपमा देखिनुपर्छ; यदि त्यो 203.0.113.9 तर्फ साधारण UDP देखियो भने, होस्ट रुट छैन र शृंखला कहिल्यै बनिएको थिएन।
भौतिक अपलिङ्कमा चुपचाप फर्कने शृंखला सबैभन्दा नराम्रो परिणाम हो, किनकि इन्टरफेसको अवस्थाले केही घोषणा गर्दैन र भित्री ट्राफिक गलत स्रोत ठेगानाबाट बाहिरिन्छ। बाहिरी सुरुङ खस्दा दोस्रो क्लाइन्ट सिधै पुनः जोडिन सक्छ भने, त्यो बाटो बन्द गर्नुहोस् वा असफलता देखियोस् भनी त्यसलाई बाहिरी इन्टरफेसमा बाँध्नुहोस्।
दुई प्रवाह र एउटा नियम डम्पसँग टुङ्ग्याउनुहोस्: चिन्ह लगाइएको र नलगाइएको जडान फरक बाटो लिनुपर्छ, र ip rule show ले तपाईंले चाहेको प्राथमिकता सूचीबद्ध गर्नुपर्छ। दुवै प्रवाह एउटै बाटो गए भने, चिन्ह तपाईंले सोचेको ठाउँमा लागू भइरहेको छैन।