नाही, VpnService अॅप फोनचे VPN सुरू करू शकत नाही
अॅप एका बोगद्याची आणि त्याच्या जीवनचक्राची मालक आहे, फोनच्या VPN स्विचची नाही। संमती मागे घेतली जाऊ शकते, एका वेळी फक्त एकच VPN चालतो, आणि पॅकेट पार्स करणे तुमचे काम आहे।
चुकीची धारणा अशी आहे की VpnService अॅप सिस्टमचा स्विच फिरवते आणि त्यानंतर फोन संरक्षित राहतो। प्रत्यक्षात घडणारे अधिक अरुंद आहे: अॅप संमती मागते, इंटरफेस बनवते, फाइल डिस्क्रिप्टरद्वारे पॅकेट वाचते आणि लिहिते, आणि थांबल्यावर इंटरफेस परत देते। एका वेळी अशा एकाच बोगद्याचा जिवंत राहू शकतो, आणि सिस्टम विचारल्याशिवाय तो काढून घेऊ शकते। लोक प्रोटोकॉलवर जे गोंधळाचे वर्तन ढकलतात त्याचा मोठा भाग या मालकीच्या मॉडेलमधून येतो।
प्रत्येक जीवनचक्र संक्रमणाला कडेचा प्रसंग न मानता रचनेचा भाग माना।
गैरसमज: अॅप फोनचे VPN सुरू करते
VpnService.prepare() ने प्रवाह सुरू होतो, जे वापरकर्त्याने स्वीकारावे लागणारे Intent परत करते, आणि establish() ने पुढे जातो, जे नंतरही अॅप नियंत्रित न करणाऱ्या कारणांमुळे अयशस्वी होऊ शकते। दुसरा बोगदा स्थापित केल्यास पहिला इंटरफेस निष्क्रिय होतो आणि सिस्टम सूचना बदलते। त्या क्रमात कुठेही अॅप संपूर्ण उपकरणाचा स्विच धारण करत नाही; त्याच्याकडे दिलेला डिस्क्रिप्टर आणि त्यावर येणारी पॅकेट असतात। कायमस्वरूपी सूचनाही अॅपच्या रचनेची नसून सिस्टमची आहे।
इंटरफेस हिसकावला जात नाही तर दिला जातो, म्हणून दुसरा क्लायंट कधीही जागा घेऊ शकतो। अॅप हे रिटर्न व्हॅल्यूने नाही तर कॉलबॅकने कळते।
अॅप जबरदस्तीने थांबवल्याचे सूचना पॅनेलमध्ये दिसण्याचेही तेच कारण आहे: सिस्टम काय दिले ते सांगते, अॅपने काय दाखवायचे निवडले ते नाही।
गैरसमज: संमती एकदाच दिली जाते
सिस्टम बोगदा दुसऱ्या क्लायंटला सोपवते तेव्हा, बेस क्लास onBind() मधून परत देणाऱ्या binder वर रद्दीकरण व्यवहार पाठवते। तो binder स्वतःच्या बदलणारे अॅपने रद्दीकरण व्यवहार स्वतः पुढे पाठवावा, अन्यथा VpnService.onRevoke() कधीही सक्रिय होत नाही आणि सेवा आता अस्तित्वात नसलेल्या डिस्क्रिप्टरमध्ये लिहीत राहते। वापरकर्ताही मंजुरी मागे घेऊ शकतो, आणि सिस्टम रीस्टार्ट किंवा नेहमी-चालू पुनर्जोडणीच्या वेळी सेवा थांबवू शकते।
हे हाताळणे म्हणजे लॉगची ओळ नाही तर ठोस काम: डिस्क्रिप्टर वाचणे थांबवा, तो बंद करा, जोडलेला फ्लॅग साफ करा आणि वापरकर्त्याला तो कोणत्या स्थितीत आहे ते सांगा। मग अॅपने पुन्हा स्थापित करावे, पुन्हा विचारावे की थांबावे हे ठरवा, कारण नेहमी-चालू संरचनेत सिस्टम सेवा स्वतःहून परत आणू शकते।
जे अॅप रद्दीकरणाला स्थिती न मानता अपवाद मानते ते जोडलेले असल्याचे सांगत राहील, तर ते लिहिणारे प्रत्येक पॅकेट टाकून दिले जाईल, आणि गोपनीयता साधनासाठी हा शक्य तितका सर्वात वाईट अपयशाचा प्रकार आहे।
गैरसमज: इंटरफेस तुमच्यासाठी रहदारी गाळते
जे येते ते कच्चे IP आहे। पकडणे किंवा गाळणे म्हणजे IP, TCP, UDP आणि IPv6 शीर्षके पार्स करणे, प्रवाह मागोवा घेणे आणि उत्तरे डिस्क्रिप्टरमध्ये परत लिहिणे, ज्यामुळे कॅप्चर अॅप सिस्टम सुविधा नसून लहान नेटवर्क स्टॅक बनते। protect() यासाठी आहे की अॅपचे स्वतःचे ट्रान्सपोर्ट सॉकेट स्वतःला पकडण्याऐवजी स्वतःचा बोगदा टाळावे, आणि ते बोगदा उभा राहिल्यानंतर तयार होणाऱ्या प्रत्येक सॉकेटवर तपासण्याजोगे बुलियन परत करते।
बिल्डरच्या परवानगी आणि प्रतिबंधित अॅप्लिकेशन याद्या कोणाची रहदारी इंटरफेसमध्ये प्रवेश करेल हे ठरवतात। त्या इंटरफेस वाहून नेणाऱ्या IP पॅकेटच्या पलीकडील पेलोडपर्यंत प्रवेश देत नाहीत, आणि कोणतेही API दुसऱ्या क्लायंटचा बोगदा उघड करत नाही किंवा सिस्टमच्या VPN प्रोफाइलची यादी करते। नेटवर्क क्षमता सांगू शकतात की नेटवर्क VPN वाहतूक आहे, पण बोगदा कोणाचा आहे ते नाही।
म्हणूनच इतर अॅप्सबद्दलच्या स्थितीच्या प्रश्नांना विरोधाभासी उत्तरे मिळतात: माहिती फक्त तुमच्या प्रक्रियेला उघड केलेली नाही।
जीवनचक्र प्रत्यक्षात काय मागते
तुम्ही नियंत्रित करता त्या स्थिती मागोवा घ्या: तयार, स्थापित, रद्द, थांबलेले। पुनर्जोडणी म्हणजे तोडणे आणि नंतर स्थापित करणे असावे, डिस्क्रिप्टर आणि ट्रान्सपोर्ट सॉकेटसाठी एकच मालक असावा, कारण स्थापित करण्यासाठी स्पर्धा करणारे दोन घटक एकमेव उपलब्ध जागेसाठी भांडतील। आधुनिक Android वर पार्श्वभूमी सुरुवाती मर्यादित आहेत, म्हणून बूट प्रसारण हमी नाही; API स्तर परवानगी देतो तिथे त्याच्या सूचनेसह फोरग्राउंड सेवा वापरा।
फक्त अंतिम स्थिती नाही तर संक्रमण लॉग करा, आणि प्रत्येक मार्ग तपासता येईल इतकी स्थिती यंत्रणा लहान ठेवा। तपासणीत जिथपर्यंत पोहोचू शकत नाही ती स्थिती लॉगशिवाय क्षेत्रात भेटणारी स्थिती आहे।
उपकरणावर जीवनचक्र तपासा
एम्युलेटर कनेक्टिव्हिटी बनावट करू शकतात, पण संमती आणि रद्दीकरणाचा मार्ग खात्रीलायकपणे नाही, म्हणून हे जागा चोरण्यासाठी दुसरा VPN क्लायंट स्थापित केलेल्या खऱ्या उपकरणावर चालवा।
adb shell dumpsys connectivity | grep -i -A3 vpn
adb shell dumpsys activity services | grep -i -A2 vpnservice
adb logcat -s VpnService:V AndroidRuntime:E
adb shell am force-stop com.example.vpnapp
बोगदा सुरू करा, सूचना आणि इंटरफेसची खात्री करा, मग दुसरा क्लायंट जोडा आणि रद्दीकरण कॉलबॅक चालतो का आणि स्थिती साफ होते का ते पाहा। अॅप जबरदस्तीने थांबवा आणि अजूनही जिवंत डिस्क्रिप्टरची तक्रार कुणी करतो का ते तपासा।
नेहमी-चालू रीस्टार्टनंतर क्रम पुन्हा करा, कारण तो मार्ग वापरकर्त्याने सुरू केलेल्या जोडणीपेक्षा वेगळा आहे। तुम्ही हिरवे चिन्ह नाही तर अॅपने आता त्याच्या मालकीचा नसलेला डिस्क्रिप्टर वापरणे थांबवले याचा पुरावा शोधत आहात।