स्थानीय ऐप, VPN नियम: आपकी FORWARD चेन कभी क्यों नहीं चलती
मशीन पर चलने वाली प्रक्रिया OUTPUT इस्तेमाल करती है, FORWARD नहीं। सही namespace में hook चुनें, फिर तय करें कि mark या साधारण route काफ़ी है या नहीं।
आप FORWARD चेन में VPN ट्रैफ़िक के लिए नियम जोड़ते हैं, वही Linux बॉक्स से अनुरोध चलाते हैं, और काउंटर शून्य पर ही टिका रहता है। नियम संभवतः सही है। पैकेट ने वह रास्ता कभी नहीं लिया, क्योंकि मशीन पर ही पैदा हुआ अनुरोध उसके द्वारा आगे नहीं भेजा जाता। पैकेट का जीवन सॉकेट से तार तक देखने पर समझ आता है कि ऐसा क्यों है और नियम असल में कहाँ होना चाहिए।
पता लगाएँ कि पैकेट कहाँ जन्मा
Netfilter का hook क्रम तीन स्थितियाँ अलग करता है, और उनमें से सिर्फ़ एक में FORWARD आता है:
| Origin | Path | Hook that sees it |
|---|---|---|
| Local process | OUTPUT then POSTROUTING | OUTPUT, POSTROUTING |
| Addressed to a local service | PREROUTING then INPUT | PREROUTING, INPUT |
| Received for another host | PREROUTING, FORWARD, POSTROUTING | FORWARD |
स्थानीय ऐप्लिकेशन OUTPUT पथ में शुरू होता है, क्योंकि कर्नेल पहले ही तय कर चुका है कि पैकेट यहीं पैदा होता है और कभी फ़ॉरवर्डिंग का उम्मीदवार नहीं है। टनल बनाना उस वर्गीकरण को नहीं बदलता; टनल एक उपकरण है जिससे पैकेट बाहर जा सकता है, ऐसा चरण नहीं जो स्थानीय आउटपुट को ट्रांज़िट बना दे।
दो पैकेट, एक कहानी
टनल चालू होने के बाद ऐप का भीतरी पैकेट और एन्क्रिप्टेड बाहरी पैकेट अलग-अलग वस्तुएँ हैं। भीतरी पैकेट वही गंतव्य और पेलोड ले जाता है जो ऐप ने चुना। बाहरी पैकेट सिफ़रटेक्स्ट को पीयर के पते और पोर्ट तक ले जाता है, और भौतिक इंटरफ़ेस वास्तव में वही पार करता है।
आपकी नीति इनमें से एक से जुड़ी है, और ग़लत वाला चुनना एक आम वजह है कि नियम कुछ करता हुआ नहीं दिखता। पीयर के बाहरी पते से मेल खाता नियम हर टनल पैकेट को एक जैसा देखता है, भीतर का ऐप कुछ भी कर रहा हो। भीतरी गंतव्य से मेल खाता नियम आपके लिए ज़रूरी ट्रैफ़िक देखता है, और वह तभी चलेगा जब वह पैकेट उस hook तक पहुँचेगा जिस पर आपने नियम लगाया है।
namespace सीमा को खिसकाते हैं
कंटेनर सिद्धांत बदले बिना इसे मुश्किल बना देता है। ऐप का अनुरोध कंटेनर के नेटवर्क namespace के भीतर स्थानीय आउटपुट है। होस्ट उस ट्रैफ़िक को वर्चुअल Ethernet इंटरफ़ेस पर प्राप्त करता है और उसे आगे भेज सकता है, इसलिए होस्ट पर FORWARD नियम अर्थपूर्ण हो सकता है, भले ही अनुरोध पैदा करने वाली प्रक्रिया ने होस्ट की OUTPUT चेन को कभी छुआ न हो।
hook चुनने से पहले तय करें कि नियम-समूह और टनल असल में कहाँ रहते हैं। कंटेनर के भीतर टनल, होस्ट पर टनल और कंटेनर का उससे होकर रूट होना, और अलग namespace में टनल — ये तीन अलग टोपोलॉजी और तीन अलग नियम-स्थान हैं। नियम उसी namespace के भीतर पढ़ें जो उपकरण का मालिक है, सिर्फ़ डिफ़ॉल्ट में नहीं।
पूछें कि क्या आपको mark की ज़रूरत है ही
अगर मक़सद एक गंतव्य प्रीफ़िक्स को टनल से भेजना है, तो उस प्रीफ़िक्स के लिए route काफ़ी हो सकता है। पहले प्रभावी routes देखें, सर्वर द्वारा धकेली गई हर चीज़ समेत: रीडायरेक्ट किया गया डिफ़ॉल्ट आपके मन की संकरी नीति से कहीं ज़्यादा ट्रैफ़िक VPN से भेजता है, और कितना भी mark करने से नतीजा मक़सद से मेल नहीं खाएगा।
वर्गीकरण तब ज़रूरी है जब फ़ैसला किसी ऐसी चीज़ पर निर्भर हो जिसे route व्यक्त नहीं कर सकता, जैसे स्रोत, उपयोगकर्ता या प्रक्रिया। प्राप्त ट्रैफ़िक के लिए PREROUTING में mark काम करता है। स्थानीय ट्रैफ़िक के लिए mark ऐसे आउटपुट चरण में होना चाहिए जो mark लगने के बाद नई route खोज शुरू कर सके। nftables में वह आउटपुट hook पर route प्रकार की चेन है; साधारण आउटपुट फ़िल्टर चेन मान लगाकर route को अपरिवर्तित छोड़ देगी।
iptables में बराबर की चीज़ mangle OUTPUT व्यवस्था में रहती है, और वही शर्त लागू है: mark मौजूद होने के बाद रूटिंग फ़ैसला दोबारा देखना होगा। फिर नीति-नियम को mark ख़र्च करना होगा और ऐसी तालिका की ओर इशारा करना होगा जिसमें काम का route हो। conntrack mark लगाना तीसरा, अलग ऑपरेशन है; वह फ़्लो पर मान रखता है और ख़ुद उस मान को मौजूदा पैकेट पर नहीं रखता कि रूटिंग उसे पढ़ सके।
खोज और काउंटर साथ जाँचें
nft list ruleset
ip route get 198.51.100.25
ip route get 198.51.100.25 mark 0x1
पता और mark उदाहरण हैं, और दोनों route प्रश्न अलग-अलग सवालों का जवाब देते हैं। दूसरा पूछता है कि अगर पैकेट पर वह mark होता तो कर्नेल क्या करता; यह नहीं दिखाता कि आपका नियम-समूह कोई mark देता है। इसे परिकल्पना-परीक्षण मानें, नीति के काम करने का प्रमाण नहीं।
फिर एक हानिरहित अनुरोध चलाएँ और एक साथ दो चीज़ें देखें: आपके चुने hook का काउंटर, और वह निकास जो पैकेट ने असल में लिया। अगर काउंटर बढ़े और पैकेट कहीं और से निकले, तो mark या तालिका ग़लत है। अगर कुछ भी न बढ़े, तो पैकेट उस hook तक पहुँचता ही नहीं, और अगला सवाल namespace या पथ है।
अंत में, परीक्षण को उतना ही सीमित रखें जितना तंत्र व्यक्त कर सकता है। एक पते के लिए एक route, ऐसी सेवा के लिए स्थायी नीति नहीं बन जाता जिसके पते बदलते रहते हैं। पहले पैकेट का दायरा तय करें, फिर जाँचें कि रूटिंग और mark डिज़ाइन दोबारा जुड़ने के बाद भी वह दायरा थाम सकता है।