Android VPN रूटिंग: main तालिका से पहले नीति-नियम
Android किसी भी गंतव्य खोज से पहले uid और मार्क नियमों से रूटिंग तालिका चुनता है, इसलिए main में जोड़ा गया रूट कभी जाँचा ही न जाए।
Android पर main तालिका में जोड़ा गया रूट हर सूची में सही दिखता है और फिर भी ट्रैफ़िक नहीं ढोता। कारण यह है कि main तालिका कई विकल्पों में से एक है, और उससे पहले नहीं पूछा जाता। Android की नेटवर्किंग सेवा ऐसे नीति-नियम बनाती है जो रूटिंग तालिका को उस जानकारी से चुनते हैं जो गंतव्य पते में नहीं होती — ऐप का uid, पैकेट पर लगा मार्क, जिस इंटरफ़ेस से वह आया — और गंतव्य की खोज बाद में होती है, उसी तालिका के भीतर जिसे उन नियमों ने चुना।
स्थिर क्रम में तीन निर्णय
बाहर जाता पैकेट तीन अलग निर्णय लेता है। पहला, एक नीति-नियम तय करता है कि कौन-सी रूटिंग तालिका लागू होती है। दूसरा, उस तालिका के भीतर का रूट अगला हॉप और आउटगोइंग इंटरफ़ेस तय करता है। तीसरा, netfilter हुक तय करते हैं कि पैकेट बचेगा, बदला जाएगा या रीडायरेक्ट होगा।
क्रम मायने रखता है क्योंकि हर चरण केवल अपने ही प्रश्न का उत्तर दे सकता है। पैकेट स्वीकार करने वाला फ़ायरवॉल नियम तालिका नहीं चुनता, और जिस तालिका को कोई नियम नहीं चुनता उसमें जोड़ा गया रूट निष्क्रिय रहता है। Android VPN के आसपास की अधिकांश उलझन तीन में से एक को ठीक करके कोई बदलाव न दिखने से आती है, क्योंकि खराबी किसी दूसरे में थी।
| Stage | Selector | What it cannot decide |
|---|---|---|
| Policy rule | uid range, mark, incoming interface | Which route exists inside the table |
| Route lookup | Destination prefix, longest match | Whether the packet is allowed out |
| Netfilter hook | Chain position, match conditions | Which table was selected |
मार्क एक पैक किया हुआ फ़ील्ड हैं, आपका अपना लेबल नहीं
Android कई तथ्यों को एक ही मार्क मान में पैक करता है: कौन-सा नेटवर्क चुना गया, क्या किसी ऐप ने स्पष्ट रूप से नेटवर्क चुना, क्या सॉकेट VPN से सुरक्षित है, और अनुमति से जुड़े बिट। AOSP का fwmark हेडर वर्तमान ट्री के लिए वह लेआउट परिभाषित करता है, और लेआउट प्लेटफ़ॉर्म का आंतरिक विवरण है जो रिलीज़ के बीच बदलता है।
इसलिए Android पर iptables -j MARK --set-mark से पूरा मार्क मान लिखना खतरनाक है। यह टैग नहीं जोड़ता; यह उस नेटवर्क चयन को बदल देता है जो सिस्टम पहले ही कर चुका है। फिर पैकेट अन्य नियमों से मेल खाता है, जो इस पर निर्भर करता है कि कौन-से बिट फिर से लिखे गए, यह दिख सकता है कि VPN काम करने लगा, या किसी असंबंधित ऐप ने कनेक्टिविटी खो दी।
अगर मार्क को छूना ही पड़े, तो पहले वर्तमान मान पढ़ें और मास्क का उपयोग करें ताकि केवल वे बिट बदलें जिन्हें आप समझते हैं:
ip rule show
ip route show table all | head -40
ip route get 10.20.4.11कनेक्शन मार्क पैकेट मार्क से अलग ऑब्जेक्ट है, और इनमें से कोई भी रूट नहीं है। उत्तर पैकेटों पर मार्क बहाल करना बाहर जाते समय तालिका चुनने से अलग चरण है, इसीलिए एकदिशीय सुधार ऐसे कनेक्शन बनाते हैं जो खुलते हैं और फिर अटक जाते हैं।
नियमों और तालिकाओं का मालिक कौन है
Android की नेटवर्क सेवा, netd, नियम और प्रति-नेटवर्क तालिकाएँ बनाती है। AOSP RouteController वह स्थान है जहाँ VPN, भौतिक नेटवर्क और uid श्रेणियों के लिए वे नियम जोड़े जाते हैं, और इसका जीवनचक्र कॉन्फ़िग फ़ाइल के बजाय नेटवर्क घटनाओं से जुड़ा है।
इससे दो परिणाम निकलते हैं। पहला, एक हैंडसेट पर मिलने वाली प्राथमिकताएँ और तालिका संख्याएँ बिल्ड के आंतरिक विवरण हैं, इंटरफ़ेस नहीं: किसी दूसरे Android संस्करण पर एक जैसी दिखने वाली संख्याएँ कुछ और ही अर्थ रख सकती हैं। दूसरा, नेटवर्क बदलने पर स्थिति फिर से बनती है, इसलिए आज root शेल से डाला गया नियम अगले Wi-Fi बदलाव के बाद गायब हो सकता है।
इस गायब होने को अक्सर यह कहकर सूचित किया जाता है कि सिस्टम रूट को नज़रअंदाज़ कर रहा है। वास्तव में हुआ यह है कि जिस नियम ने तालिका चुनी थी वह अब मौजूद नहीं है, और तालिका के भीतर का रूट अब पैकेट की दृष्टि से अगम्य है। जब कोई काम करता कॉन्फ़िगरेशन फिर से कनेक्ट होने के बाद काम करना बंद कर दे, तो रूट सूची नहीं, नियम सूची देखें।
हुक क्रम के प्रश्नों का सार्वभौमिक उत्तर नहीं है
क्या iptables VPN रूटिंग से पहले चलता है, इस प्रश्न का उत्तर पैकेट का पथ बताए बिना नहीं दिया जा सकता। स्थानीय रूप से बना पैकेट output हुक से गुज़रता है, जहाँ मार्क बदलने पर पुनःरूटिंग जाँच शुरू होती है — दूसरी खोज, पहली की पूर्वव्यापी संपादन नहीं। tether किए गए क्लाइंट से आने वाला पैकेट prerouting पथ से गुज़रता है और इसके बजाय आगे भेजा जाता है, और उसे देखने वाली चेन अलग होती हैं।
इसलिए वही नियम किसी ऐप के ट्रैफ़िक के लिए प्रभावी और tether ट्रैफ़िक के लिए अदृश्य हो सकता है, और शून्य पर रुका काउंटर आपको बताता है कि पैकेट ने कौन-सा पथ लिया, यह नहीं कि नियम गलत है। कोई भी मेल शर्त बदलने से पहले काउंटरों से पथ स्थापित करें।
यह वही चरण है जहाँ नीति-रूटिंग की गलती देखना कठिन हो जाता है। ऐसी तालिका में रूट करना जो मौजूद है पर गंतव्य नहीं रखती, नेटवर्क अगम्य उत्पन्न करता है जो फ़ायरवॉल ड्रॉप जैसा लगता है, जबकि फ़ायरवॉल ड्रॉप ऐसा टाइमआउट उत्पन्न करता है जो रूटिंग ब्लैक होल जैसा लगता है।
सिस्टम के भीतर निदान करें, या उसे छोड़ दें
अधिकृत समीक्षा के लिए कुछ भी छूने से पहले चार तथ्य स्थापित करें: ऐप का uid और प्रोफ़ाइल, Android ने उसके लिए कौन-सा नेटवर्क चुना, क्या VPN उस ऐप को शामिल करता है, और क्या समस्या दोनों पता परिवारों में है। प्रति-ऐप बहिष्करण बिना किसी रूटिंग खराबी के बहुत सी VPN काम नहीं कर रहा रिपोर्टें समझा देता है।
फिर वे नियम, मास्क और तालिकाएँ पढ़ें जो वास्तव में लागू हैं, और अवलोकन विंडो के भीतर एक नेटवर्क बदलाव रखें। अगर फिर से कनेक्ट होने पर व्यवहार बदलता है, तो आप प्रबंधित जीवनचक्र देख रहे हैं, गायब रूट नहीं।
सामान्य आवश्यकताओं के लिए समर्थित नियंत्रण उपयोग करें: प्रति-ऐप समावेशन और बहिष्करण VPN ऐप्लिकेशन में, और किसी विशिष्ट पथ की ज़रूरत वाली हर चीज़ के लिए प्लेटफ़ॉर्म का अपना नेटवर्क चयन। अगर किसी विशेषाधिकार प्राप्त एकीकरण को सचमुच रूटिंग मशीनरी के साथ सहयोग करना है, तो उसी Android संस्करण के कार्यान्वयन को लक्षित करें जिसका आप समर्थन करते हैं और उसका जीवनचक्र उस घटक के माध्यम से बनाए रखें जो उसका मालिक है। प्लेटफ़ॉर्म चेन फ्लश करना या उच्च प्राथमिकता वाला नियम डालना निदान को दूसरा नेटवर्क प्रबंधक बना देता है, और फ़ोन उसी के अनुसार व्यवहार करेगा।