फोन रीबूट होतो, always-on सुरू आहे, «VPN शिवाय कनेक्शन अडवा» सुरू आहे, आणि टनेल मात्र कधीच येत नाही. काहीही चुकीचे कॉन्फिगर केलेले नाही: अडवणूक आपले काम करत आहे, आणि क्लायंटचा स्वतःचा त्याच्या एंडपॉइंटपर्यंत पोहोचण्याचा प्रयत्नही तिला अधीन आहे. एंडपॉइंटचे नाव टनेल अस्तित्वात येण्यापूर्वी सोडवावे लागते, अशा क्लायंटद्वारे ज्याला नेटवर्कशी बोलण्याची परवानगी आहे, तर इतर सर्व ॲप्सना नाही. कोणता घटक हे करतो आणि कोणत्या क्रमाने, हे समजल्यावर हे कोडे कॉन्फिगरेशनचा प्रश्न बनते.

VPN बिल्डर प्रत्यक्षात काय मागतो

Android VPN ॲप प्लॅटफॉर्मला सर्व्हरचा पत्ता देत नाही. ते स्थानिक इंटरफेस तयार करते: टनेलसाठी पत्ते आणि मार्ग, त्याच्या आत ॲप्सनी वापरावेत असे रिझोल्व्हर, आणि नंतर establish() फाइल डिस्क्रिप्टर परत करते, जे ॲप कच्च्या IP पॅकेट्स म्हणून वाचते आणि लिहिते. दूरचा एंडपॉइंट त्या बिल्डरमध्ये अजिबात दिसत नाही.

हीच मुख्य रचनात्मक गोष्ट आहे. प्लॅटफॉर्म tun इंटरफेस तयार करते आणि त्यावर धोरण लागू करते; ॲप वापरकर्ता जागेत वाहतूक अंमलात आणते, म्हणजे एंडपॉइंटचे नाव सोडवणे आणि कूटबद्ध कनेक्शन उघडणे हे ॲप स्वतः करते. म्हणून होस्टनावाचा एंडपॉइंट शक्य आहे — प्लॅटफॉर्म नावांना आधार देतो म्हणून नाही, तर प्लॅटफॉर्म एंडपॉइंट कधीच पाहत नाही म्हणून.

बिल्डरमधील एकच फील्ड पत्ते घेते: DNS सर्व्हर. ते अंकीय रिझोल्व्हर पत्ते असावेत, सामान्यतः जे ऑपरेटरला टनेलमधून विचारायचे असतात. ते फील्ड टनेल आल्यानंतर ॲप्स क्वेरी कुठे पाठवतात हे सांगते. क्लायंट एंडपॉइंट कसा शोधतो याबद्दल ते काहीही सांगत नाही, आणि हे दोन्ही एकच सेटिंग मानण्यापासूनच गोंधळ सुरू होतो.

एक नाही, दोन DNS प्रश्न

पहिला प्रश्न: टनेल आल्यानंतर ॲप्स क्वेरी कुठे पाठवतात? उत्तर टनेलच्या आतला रिझोल्व्हर पत्ता आहे, tun इंटरफेसद्वारे पोहोचण्यायोग्य, आणि रचनेनेच अंकीय.

दुसरा प्रश्न: तो टनेल अस्तित्वात येण्यापूर्वी क्लायंट आपला स्वतःचा एंडपॉइंट कसा शोधतो? तो शोध टनेलबाहेर, मूळ नेटवर्कवर, क्लायंटच्या प्रोसेसमध्ये होतो. तो नाव वापरू शकतो, आणि VPN शिवाय डिव्हाइस पोहोचू शकेल असा रिझोल्व्हर वापरावाच लागतो.

StageWho resolvesPathFailure looks like
Endpoint lookupThe VPN appUnderlying network, protected socketNever connects; no tunnel interface traffic
Peer authenticationClient and serverTunnel transportConnects then drops; certificate or key error
Private name lookupApps via the tunnelResolver inside the tunTunnel up, internal sites do not resolve

तीन टप्पे, तीन वेगळी लक्षणे. «कनेक्ट होऊ शकत नाही» असे एकच त्रुटी संदेश त्यांना एकत्र करतो, आणि म्हणूनच लोक ते फील्ड वाचले जाण्यापूर्वीच घडणाऱ्या समस्येची दुरुस्ती करण्यासाठी DNS सर्व्हर फील्ड संपादित करू लागतात.

bootstrap का अडकू शकतो

always-on मध्ये अडवणूक सुरू असल्याचा अर्थ VPN च्या आत नसलेली रहदारी टाकली जाते, VPN असलेल्या ॲपची रहदारीसुद्धा. सुटकेचा मार्ग स्पष्ट आहे: ॲप सॉकेटवर protect() बोलावते, जे ते मूळ नेटवर्कला बांधते, त्यामुळे ते टनेलला बगल देऊन बाहेर पडू शकते. प्रत्येक VPN क्लायंटने आपल्या वाहतुकीसाठी हे केलेच पाहिजे, अन्यथा तो सर्व्हरपर्यंत कधीच पोहोचणार नाही.

आता अशी तैनाती विचारात घ्या जिथे एंडपॉइंटचे नाव जाणणारा एकमेव रिझोल्व्हर स्वतः टनेलच्या आत आहे. नाव सोडवण्यासाठी क्लायंटला टनेल लागतो, आणि टनेल बांधण्यासाठी नाव लागते. हे खरे चक्रीय अवलंबन आहे, आणि कोणतेही क्लायंट कॉन्फिगरेशन ते सोडवत नाही. ही रचना त्रुटी आहे, बग नाही.

वेळ हेच अवलंबन सौम्य स्वरूपात उघड करतो. बूटच्या वेळी, पहिल्या अनलॉकपूर्वी, डिव्हाइसकडे अजून वापरण्यायोग्य नेटवर्क नसू शकते; captive portal वर नेटवर्क आहे पण पोर्टलशिवाय सर्व अडवते; Wi-Fi वरून मोबाइलवर जाताना संरक्षित सॉकेटचे मूळ नेटवर्क बदलते आणि क्लायंटला ते लक्षात घेऊन पुन्हा सोडवावे लागते. यातील प्रत्येक bootstrap घटना आहे, आणि प्रत्येक रात्री 3 वाजता शोधण्यापेक्षा जाणीवपूर्वक चाचणी करण्यासारखी आहे.

उत्तर स्थिर करणे हा उपाय का नाही

मोहाचा मार्ग म्हणजे नाव एकदा सोडवून मिळालेला पत्ता अंकीय फील्डमध्ये पेस्ट करणे, किंवा सानुकूल बिल्डमध्ये हार्डकोड करणे. ते चालल्यासारखे वाटते, आणि नावाचे छायाचित्र बनवते. ऑपरेटर एंडपॉइंट हलवतो तेव्हा — स्थलांतर, anycast बदल, नवीन प्रादेशिक पत्ता — क्लायंट जुन्यालाच कॉल करत राहतो आणि UI मध्ये कुठेही कारण स्पष्ट होत नाही.

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

स्थिर करण्यासोबत सहसा दुसरी वाईट सवय येते: कनेक्शन आता वेगळ्या प्रकारे अयशस्वी होत असल्याने ओळख पडताळणी सैल करणे. सर्व्हरची ओळख पडताळणी bootstrap समस्येचा भाग नाही, आणि ती कमकुवत करणे म्हणजे DNS चा त्रास अडवणुकीच्या जोखमीशी बदलणे.

रीबूट टिकून राहणाऱ्या रचना

टिकाऊ मांडणी फारशी आकर्षक नाही. संरक्षित सॉकेट योग्यरीत्या अंमलात आणणारा आणि एंडपॉइंट मूळ नेटवर्कवर सोडवणारा क्लायंट वापरा, आणि त्याला सार्वजनिकरीत्या किंवा टनेलपूर्वी पोहोचण्यायोग्य रिझोल्व्हरद्वारे सोडवला जाणारा एंडपॉइंट नाव द्या. अडवणूक सुरू ठेवा; DNS चालावे म्हणून ती पूर्णपणे बंद करणे हे तैनाती ज्या गुणधर्मासाठी आहे तो काढून टाकते.

जिथे एंडपॉइंट खाजगी राहिला पाहिजे, तिथे प्लॅटफॉर्म वापरू शकेल असा स्पष्ट bootstrap मार्ग द्या — टनेलशिवाय पोहोचण्यायोग्य रिझोल्व्हर, किंवा ऑपरेटर ठेवत असलेले व्यवस्थापन कनेक्शन — आणि तो अपवाद अरुंद ठेवा, वापरकर्ता टॉगलऐवजी धोरणाच्या मालकीचा ठेवा. Android VpnService दस्तऐवज हे संरक्षण आणि जीवनचक्राबद्दल प्लॅटफॉर्म काय हमी देतो याचा संदर्भ आहे, आणि VpnService.Builder संदर्भ DNS फील्ड अंकीय पत्ते घेते याची पुष्टी करतो.

नंतर रीबूटनंतरच्या नवीन कनेक्शनवर तीन टप्पे क्रमाने तपासा: एंडपॉइंटचे नाव सोडवले जाते, टनेल स्थापित होते आणि सहभागी प्रमाणित होतो, आणि खाजगी नाव टनेलच्या रिझोल्व्हरद्वारे सोडवले जाते. पहिला टप्पा अयशस्वी झाला तर पुढील काहीही चालू शकत नाही, आणि दुरुस्ती bootstrap मार्गातली आहे — कधीही रिझोल्व्हर फील्डमधली नाही.

  • एंडपॉइंट सोडवणे ॲपमध्ये, टनेलबाहेर, संरक्षित सॉकेटवर होते.
  • बिल्डरमधील DNS फील्ड टनेलच्या आतल्या ॲप्ससाठी आहे, क्लायंटच्या स्वतःच्या एंडपॉइंटसाठी नाही.
  • केवळ टनेलमधून पोहोचणारा रिझोल्व्हर म्हणजे अडकणे, संथ सुरुवात नाही.
  • रीबूटनंतर एंडपॉइंट, प्रमाणीकरण आणि खाजगी शोध वेगवेगळे तपासा.

संबंधित लेख