Android एमुलेटर और होस्ट VPN: DNS स्नैपशॉट और NAT की व्याख्या
गेस्ट एमुलेटर के NAT के पीछे बैठता है और बूट के समय कॉपी की गई DNS सूची रखता है। बूट से पहले टनल जोड़ें, फिर गेस्ट के अंदर से रिज़ॉल्यूशन जाँचें।
जब एमुलेटर उस बिल्ड सर्वर तक नहीं पहुँच पाता जिसे होस्ट का ब्राउज़र बिना किसी परेशानी के खोलता है, तो उपयोगी सवाल यह नहीं है कि VPN काम करता है या नहीं। सवाल यह है कि गेस्ट को दो में से कौन-सी व्यवस्था नहीं मिली है। वर्चुअल डिवाइस एमुलेटर के NAT के पीछे अपना अलग नेटवर्क स्टैक चलाता है, और उसकी रिज़ॉल्वर सूची बूट के समय ली गई एक कॉपी है, इसलिए बाद में ऊपर आया टनल होस्ट का रास्ता बदल देता है पर गेस्ट जो पूछता है उसे नहीं बदलता। इन दो परतों को समझना इस समस्या के लगभग हर रूप की व्याख्या कर देता है।
गेस्ट स्थिर NAT के पीछे एक अलग स्टैक है
QEMU का यूज़र-मोड नेटवर्किंग गेस्ट को 10.0.2.15 पर, गेटवे को 10.0.2.2 पर और DNS सेवा को 10.0.2.3 से 10.0.2.6 तक रखता है। गेस्ट का बाहर जाने वाला ट्रैफ़िक होस्ट का कर्नेल आगे नहीं भेजता; वह होस्ट की तरफ़ के सॉकेट में बदल जाता है, गेस्ट के हर कनेक्शन के लिए एक, और वे सॉकेट होस्ट के पता-स्थान से बाहर निकलते हैं। इसीलिए गेस्ट का कनेक्शन बनते समय होस्ट का रूटिंग फ़ैसला विरासत में लेता है, और इसीलिए गेस्ट के रूट टेबल में कोई ऐसी प्रविष्टि नहीं है जो आपके टनल का नाम ले।
यही व्यवस्था गेस्ट को एक उपयोगी रास्ता देती है। 10.0.2.2 होस्ट के लूपबैक इंटरफ़ेस का उपनाम है, इसलिए लैपटॉप पर 127.0.0.1 पर सुनने वाली सेवा गेस्ट से उस पते पर पहुँची जा सकती है। क्लाइंट जो कुछ केवल लूपबैक पर खोलता है, वहाँ इस तरह पहुँचा जा सकता है, और यही नीचे बताई गई प्रॉक्सी व्यवस्था का आधार है।
गेस्ट जो नहीं कर सकता वह है होस्ट के नेटवर्क को ऐसे देखना जैसे वह उस पर कोई नेमस्पेस हो। कोई ब्रिज नहीं, कोई साझा रूट टेबल नहीं और कोई विरासत में मिला रिज़ॉल्वर नहीं, बस उसके पैकेट लेने वाली NAT सेवा और वह स्नैपशॉट जो वर्चुअल डिवाइस शुरू होते समय लॉन्चर ने लिया था।
DNS एक स्नैपशॉट है, जीवंत दृश्य नहीं
शुरुआत में एमुलेटर होस्ट की रिज़ॉल्वर सूची पढ़ता है और गेस्ट को चार तक सर्वर देता है, जो 10.0.2.3 से 10.0.2.6 पतों पर खुलते हैं। अगर उस समय टनल बंद था, तो स्नैपशॉट में वही सार्वजनिक रिज़ॉल्वर है जो लैपटॉप ने इस्तेमाल किया, और गेस्ट जीवन भर उसी से पूछता रहता है। सार्वजनिक नाम हल होते हैं, आंतरिक नाम विफल होते हैं, और हर लक्षण VPN की ओर इशारा करता है जबकि असली पुराना मान टनल ऊपर आने से कुछ मिनट पहले ली गई रिज़ॉल्वर सूची है।
इसलिए क्रम से सुधार कोई किस्सा नहीं है। पहले टनल जोड़ें, फिर एमुलेटर को फिर से शुरू करें, और स्नैपशॉट बहाल करने के बजाय कोल्ड बूट को प्राथमिकता दें, क्योंकि तेज़-बूट इमेज पहले सहेजे गए रिज़ॉल्वर और रूट की स्थिति के साथ लौट सकती है। अगर आप देखना चाहते हैं कि गेस्ट अभी क्या इस्तेमाल करता है, तो होस्ट से नहीं, डिवाइस से पूछें:
adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.exampleएमुलेटर शुरू होते समय स्पष्ट रिज़ॉल्वर भी स्वीकार करता है, जो तब उपयोगी है जब आप ठीक-ठीक जानते हैं कि गेस्ट को कौन-सा सर्वर इस्तेमाल करना चाहिए, और तब खतरनाक है जब वह सर्वर सार्वजनिक हो:
emulator -avd Pixel_API_34 -dns-server 203.0.113.53सार्वजनिक रिज़ॉल्वर के पास आंतरिक ज़ोन की कोई कॉपी नहीं होती, इसलिए एक को पिन करना क्रम की समस्या को स्थायी विफलता में बदल देता है। अगर प्रोफ़ाइल निजी DNS थोपती है, तो टनल को वह देने दें और पता हार्डकोड करने के बजाय गेस्ट को कोल्ड बूट करें।
रूटिंग कनेक्शन के समय होस्ट का अनुसरण करती है
चूँकि गेस्ट के कनेक्शन होस्ट के सॉकेट बन जाते हैं, रूटिंग का फ़ैसला सॉकेट बनते समय होता है। अनुरोध से पहले टनल ऊपर होने का मतलब है कि अनुरोध प्रोफ़ाइल के रास्तों के अनुसार टनल से बाहर जाता है। केवल चुने हुए प्रीफ़िक्स ले जाने वाली स्प्लिट-टनल प्रोफ़ाइल आपके निजी सबनेट को बड़े आराम से बाहर छोड़ देगी, इसलिए होस्ट की पहुँच गेस्ट के बारे में एक अनुमान है, परिणाम नहीं। मौजूदा गेस्ट कनेक्शन उसी रास्ते पर रहते हैं जिसके साथ बने थे, इसलिए फिर से जुड़ने वाला क्लाइंट एमुलेटर के अंदर अटका डाउनलोड हमेशा ठीक नहीं करता।
सत्यापन होस्ट के इंटरफ़ेस पर है, गेस्ट के आँकड़ों में नहीं:
sudo tcpdump -ni tun0 'host 203.0.113.10'अगर गेस्ट का अनुरोध टनल इंटरफ़ेस पर दिखता है, तो रूटिंग काम कर रही है और समस्या उसके ऊपर है। अगर वह भौतिक इंटरफ़ेस पर दिखता है, तो प्रोफ़ाइल उस प्रीफ़िक्स को नहीं ढकती, और गेस्ट की तरफ़ कितना भी पुनर्संरचना करें वह नहीं बदलेगा।
जब क्लाइंट केवल लूपबैक प्रॉक्सी देता है
कुछ व्यावसायिक क्लाइंट कोई सिस्टम टनल बनाते ही नहीं। वे 127.0.0.1 पर HTTP या SOCKS श्रोता खोलते हैं और उम्मीद करते हैं कि ऐप्लिकेशन उसका इस्तेमाल करेंगे। गेस्ट उस सॉकेट को सीधे नहीं देख सकता, पर एमुलेटर को उसे इस्तेमाल करने के लिए कहा जा सकता है, या तो विस्तारित नियंत्रणों से (सेटिंग्स, फिर प्रॉक्सी, मैन्युअल मोड, होस्ट 127.0.0.1 और वह पोर्ट जो क्लाइंट छापता है) या शुरू होते समय:
emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080क्लाइंट विंडो से पोर्ट कॉपी करें; अनुमानित पोर्ट चुपचाप विफल होता है और टूटे टनल जैसा दिखता है। याद रखें यह क्या ढकता है: HTTP प्रॉक्सी सेटिंग को प्रॉक्सी-सजग ऐप्लिकेशन मानते हैं, और कच्चे सॉकेट उसे पूरी तरह अनदेखा करते हैं। अगर काम का बोझ अपने कनेक्शन खोलने वाला नेटिव बाइनरी है, तो प्रॉक्सी का रास्ता टनल के बराबर नहीं है और तुलना स्पष्ट रूप से करनी होगी।
परिणाम गेस्ट के अंदर से सिद्ध करें
एक ही सत्र में दो परीक्षणों से रिज़ॉल्यूशन को रूटिंग से अलग करें। जो नाम विफल होता है जबकि संख्यात्मक पता उत्तर देता है, वह DNS स्नैपशॉट की समस्या है, और सुधार क्रम या स्पष्ट रिज़ॉल्वर है। दोनों विफल हों तो यह रूटिंग या नीति की ओर इशारा करता है, और अगली जाँच यह है कि ऐप अपने नेटवर्क प्रतिबंधों वाली कार्य प्रोफ़ाइल में चल रहा है या नहीं।
अंत में, जानें कि आप किस गेस्ट पर परीक्षण कर रहे हैं। बहुत पुरानी एमुलेटर इमेज बिना उस tun समर्थन के भेजी गई थीं जो गेस्ट-साइड VPN क्लाइंट को चाहिए, इसलिए वहाँ कोई प्रोफ़ाइल कभी काम नहीं कर सकती थी; मौजूदा इमेज में वह है। मौजूदा इमेज पर विफल होने वाला क्लाइंट क्लाइंट या प्रोफ़ाइल की समस्या है, और होस्ट का टनल फिर से बनाने से परिणाम नहीं बदलेगा।