VpnService ॲपमधील स्प्लिट टनलिंग काही ठराविक ठिकाणी तुटते आणि प्रत्येकासाठी दुरुस्ती वेगळी आहे. क्लायंट फक्त एक अपयशी गंतव्य दाखवतो, म्हणून पहिले काम म्हणजे तुम्ही कोणत्या सीमेवर आदळत आहात हे शोधणे: builder ला मिळालेले मार्ग, ज्या प्रॉक्सीचे प्रमाणीकरण करता येत नाही, जो resolver फक्त जाहीर केला, किंवा प्लॅटफॉर्म प्रत्येक वापरकर्त्यासाठी लागू करतो ती ॲप यादी. म्हणूनच मी चार पायऱ्यांची तपासणी ठेवतो. ती खालील क्रमाने चालते आणि पहिल्या अपयशावर थांबते.

builder ने प्लॅटफॉर्मला काय दिले याची खात्री करा

VpnService.Builder ही घोषणांची यादी आहे. establish() व्हर्च्युअल इंटरफेससाठी ParcelFileDescriptor परत करते आणि प्लॅटफॉर्म त्या डिस्क्रिप्टरमध्ये फक्त addAddress व addRoute च्या प्रीफिक्सशी जुळणारा रहदारी पाठवतो; addDnsServer क्लायंटना कोणत्या resolver ला विचारायचे ते सांगते. तुम्ही जोडलेल्या कोणत्याही प्रीफिक्सच्या बाहेरचे गंतव्य इंटरफेस काहीही वचन देत असले तरी तुमच्या ॲपपर्यंत कधीच पोहोचत नाही. हीच एक गोष्ट कोड बदलण्यापूर्वीच तुटलेल्या स्प्लिट टनलिंगच्या बहुतेक तक्रारी समजावून सांगते.

builder ने जमवलेल्या पत्ता, मार्ग व DNS याद्या लॉग करा, नंतर त्यांची अपयशी गंतव्यांशी तुलना करा. व्यवस्थापन होस्टसाठी गहाळ /32 हे तुटलेल्या टनेलपेक्षा खूप सामान्य आहे. यादी बरोबर असेल तर पुढे जा; चुकीची असेल तर उर्वरित तपासणी सूची व्यर्थ श्रम आहे.

excludeRoute फक्त API 33 पासून आहे

गंतव्य-आधारित वगळणे ही सर्वाधिक वेळा सपोर्ट थ्रेड बनणारी विनंती आहे. builder.excludeRoute(IpPrefix) API 33 मध्ये आले; त्यापूर्वी एकमेव समर्थित पर्याय म्हणजे वगळलेल्या प्रीफिक्सशिवाय सर्वांसाठी मार्ग जोडणे, म्हणजे पूरक प्रीफिक्स तुम्हालाच मोजावे लागतात. दोन्ही कॉल आरशातील प्रतिबिंब नाहीत: एक इंटरफेसच्या मार्ग-संचातून वजा करते, दुसरे संच शून्यातून उभारते, आणि जुने उपकरण न ओळखणारा कॉल फेकून देते किंवा गुपचूप दुर्लक्ष करते. Build.VERSION.SDK_INT वर शाखा करा आणि दोन्ही मार्ग प्रत्यक्ष हार्डवेअरवर तपासा.

पूरक मोजताना प्रीफिक्स संरेखनाकडे लक्ष द्या. /16 मार्गातील /24 वगळण्यासाठी उर्वरित भाग खरोखर वर्णन करणारे आच्छादक प्रीफिक्स लागतात, एक विकृत /8 नाही. अंतिम यादी लॉग करा आणि वगळलेला होस्ट अजूनही टनेलबाहेरच्या मार्गाने सोडवला जातो याची खात्री करा.

प्रॉक्सी क्रेडेन्शियल्स व्यक्त करता येत नाहीत

setHttpProxy(ProxyInfo) इंटरफेसला HTTP किंवा SOCKS प्रॉक्सीकडे वळवते आणि PAC URL प्रत्येक गंतव्यासाठी दोन्हींपैकी निवडू शकतो. ProxyInfo किंवा PAC स्वरूप दोन्ही वापरकर्तानाव व पासवर्ड ठेवत नाहीत, म्हणून प्रमाणीकरण आवश्यक असलेली प्रॉक्सी प्लॅटफॉर्म API बाहेर राहते. ती आवश्यक असलेली ॲप्स सहसा userspace स्टॅक, tun2socks किंवा तत्सम इंजिन वापरतात आणि 407 आव्हानाला स्वतः उत्तर देतात.

या निवडीचे परिणाम आहेत. userspace स्टॅक फक्त तुम्ही त्याच्याकडे वळवलेला रहदारी पाहतो, म्हणून त्याला त्याच डिस्क्रिप्टर सीमेत राहावे लागते आणि स्वतःच्या uplink सॉकेटसाठी तीच protect() अट वारसा मिळते. protect() वगळले तर टनेल स्वतःचे वाहन पकडते, जे पहिल्या पॅकेटनंतर अडकणारे हस्तांदोलन म्हणून दिसते. क्रेडेन्शियल्स मागणाऱ्या प्रॉक्सीविरुद्ध चाचणी करा, कारण खुली प्रॉक्सी प्लॅटफॉर्मच्या मार्गाने जाते आणि काहीही सिद्ध करत नाही.

प्रति-ॲप याद्या आणि DNS हेही घोषणा आहेत

Builder मध्ये addAllowedApplication आणि addDisallowedApplication दोन्ही आहेत आणि ते परस्परविरोधी आहेत: दोन्ही कॉल केल्यास अपवाद फेकला जातो. कोणत्याही स्थितीत यादी इंटरफेस सेटअपवेळी प्रत्येक वापरकर्त्यासाठी लागू होते, म्हणून कार्य प्रोफाइलमधील ॲप तुमच्या टनेलऐवजी कार्य प्रोफाइलच्या टनेलद्वारे नियंत्रित होते. कोणतेही API दुसऱ्या ॲपच्या निर्णयावर नियंत्रण देत नाही: बाहेरून पॅकेट तुमच्या टनेलमध्ये ढकलता येत नाही आणि आधीच सक्रिय VPN बंद किंवा पुन्हा संरचीत करता येत नाही.

DNS तोच नमुना अनुसरते. addDnsServer resolver चा पत्ता जाहीर करते; ते तुमच्या ॲपला प्रश्नांना उत्तर देऊ देत नाही. तुम्हाला नावे स्वतः सोडवायची असतील तर resolver चालवा आणि त्याचा पत्ता टनेलमध्ये वळवा. ठराविक होस्टनावासाठी DoT किंवा DoH वापरणारी ॲप्स तुम्ही जाहीर केलेला पत्ता टाळू शकतात, म्हणून प्रश्नाचा मार्गही अडवत नसाल तर नाव-निराकरण हे सर्वोत्तम प्रयत्न माना.

Manifest, always-on आणि चार पायऱ्यांची चाचणी

पात्रता manifest मध्ये घोषित होते: BIND_VPN_SERVICE, android.net.VpnService इंटेंट फिल्टर आणि टनेल पार्श्वभूमीत टिकायचे असेल तर foreground सेवा. Always-on VPN ला अधिक स्पष्ट onRevoke लागतो, कारण वापरकर्ता सेटिंग्ज बदलतो किंवा दुसरे ॲप नियंत्रण घेते तेव्हा सिस्टम तो कॉल करते.

तपासण्या क्रमाने करा आणि पहिल्या अपयशावर थांबा. पहिले, builder ला दिलेल्या पत्ता, मार्ग व DNS याद्या काढा. दुसरे, establish() ने डिस्क्रिप्टर परत दिला आणि वाहन सॉकेट संरक्षित आहे याची खात्री करा. तिसरे, समाविष्ट प्रीफिक्समध्ये एक आणि वगळलेल्या प्रीफिक्समध्ये एक गंतव्य मागा. चौथे, फक्त तुमचा resolver सोडवू शकेल असे होस्टनाव विचारून कोणत्या resolver ने प्रत्यक्षात उत्तर दिले ते तपासा.

पूर्ण झालेले हस्तांदोलन पुढील कोणत्याही पायरीची सिद्धी देत नाही. प्रत्येक तपासणी एक स्तर वेगळा करते, म्हणून दुसऱ्या पायरीतील यश चौथ्याबद्दल काहीही सांगत नाही.

VpnService.Builder संदर्भ builder ची संपूर्ण पृष्ठभाग सूचीबद्ध करतो. त्यापुढे जे लागते ते दुसरे API, दुसरे ॲप किंवा तुमचा स्वतःचा userspace स्टॅक आहे आणि तो स्प्लिट-टनेल बग नसून रचनेचा निर्णय आहे.

संबंधित लेख