Android эмуляторы және хосттағы VPN: DNS snapshot-ы және NAT
Guest эмулятор NAT-ының артында отырады және boot кезінде көшірілген DNS тізімін ұстайды. Туннельді boot-тан бұрын қосыңыз, содан кейін resolution-ды guest ішінен тексеріңіз.
Эмулятор хосттың браузерінде қалыпты ашылатын build-серверіне жете алмағанда, пайдалы сұрақ VPN жұмыс істеп тұр ма дегенде емес. Сұрақ guest-ке екі механизмнің қайсысы жетіспейді дегенде. Виртуалды құрылғы өз желілік stack-ін эмулятор NAT-ының артында ұстайды, ал оның resolver тізімі boot кезінде алынған көшірме, сондықтан кейінірек көтерілген туннель хост жолын өзгертеді, бірақ guest сұрайтын нәрсені өзгертпейді. Осы екі қабатты түсіну бұл мәселенің барлық дерлік нұсқасын түсіндіреді.
Guest — тіркелген NAT артындағы бөлек stack
QEMU-ның user-mode желісі guest-ті 10.0.2.15 мекенжайына, gateway-ді 10.0.2.2-ге және DNS қызметін 10.0.2.3-тен 10.0.2.6-ға дейін орналастырады. Guest-тің сыртқа шығатын трафигі хост kernel-імен forward жасалмайды; ол хост жағындағы socket-терге айналады, әр guest-қосылымына біреу, және бұл socket-тер хосттың мекенжай кеңістігінен шығады. Сондықтан guest-қосылымы жасалған сәттегі хосттың routing шешімін мұра етеді, сондықтан guest-тің route кестесінде сіздің туннельді атайтын жазба жоқ.
Сол механизм guest-ке пайдалы шығу жолын береді. 10.0.2.2 хосттың loopback интерфейсінің alias-ы, сондықтан ноутбуктегі 127.0.0.1-де тыңдайтын қызметке guest-тен сол мекенжай бойынша қол жеткізуге болады. Client тек loopback-те ашатын нәрсенің бәріне осылай жетуге болады, және бұл төменде сипатталған proxy конфигурациясының негізі.
Guest-тің жасай алмайтыны — хост желісін өзінің namespace-і сияқты бақылау. Bridge жоқ, ортақ route кестесі жоқ және мұрагерлік resolver жоқ; тек оның packet-терін қабылдайтын NAT қызметі және виртуалды құрылғы іске қосылғанда launcher алған snapshot бар.
DNS — snapshot, тірі көрініс емес
Іске қосылу кезінде эмулятор хосттың resolver тізімін оқып, guest-ке төртке дейін сервер береді, олар 10.0.2.3-тен 10.0.2.6 мекенжайларында ашылады. Егер сол сәтте туннель төмен болса, snapshot-та ноутбук қолданған public resolver болады, және guest өмірінің соңына дейін одан сұрайды. Public атаулар шешіледі, ішкі атаулар сәтсіз аяқталады, және барлық симптом VPN-ді нұсқайды, ал шын мәнінде ескірген мән — туннель көтерілмес бұрын бірнеше минут бұрын алынған resolver тізімі.
Сондықтан реттілікті түзету фольклор емес. Алдымен туннельді қосыңыз, содан кейін эмуляторды қайта іске қосыңыз, және snapshot-ты қалпына келтіруден гөрі cold boot-ты таңдаңыз, өйткені quick-boot бейнесі бұрын сақталған resolver мен route күйімен оралуы мүмкін. Guest қазір нені қолданып жатқанын көргіңіз келсе, хосттан емес, құрылғыдан сұраңыз:
adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.exampleЭмулятор іске қосылу кезінде айқын resolver-ды да қабылдайды, бұл guest қай серверді қолдануы керектігін нақты білгенде пайдалы, ал сол сервер public болса қауіпті:
emulator -avd Pixel_API_34 -dns-server 203.0.113.53Public resolver-да ішкі zone-ның көшірмесі жоқ, сондықтан біреуін бекіту реттілік мәселесін тұрақты ақауға айналдырады. Егер profile private DNS таратса, оны туннель берсін және мекенжайды қатты жазу орнына guest-ті cold boot жасаңыз.
Routing қосылым сәтінде хостқа ереді
Guest-қосылымдары хост socket-теріне айналатындықтан, routing шешімі socket жасалғанда қабылданады. Сұранысқа дейін көтерілген туннель сұраныстың profile route-тарына сәйкес туннельден шығатынын білдіреді. Тек таңдауды prefix-терді тасымалдайтын split-tunnel profile сіздің private subnet-ті сыртта қалдырады, сондықтан хостқа жетімділік guest туралы гипотеза, нәтиже емес. Бар guest-қосылымдары жасалған жолын сақтайды, сондықтан қайта қосылған client эмулятордағы кептелген жүктемені әрдайым түзетпейді.
Тексеру хост интерфейсінде, guest статистикасында емес:
sudo tcpdump -ni tun0 'host 203.0.113.10'Егер guest сұранысы туннель интерфейсінде көрінсе, routing жұмыс істейді және мәселе оның үстінде. Егер ол физикалық интерфейсте көрінсе, profile сол prefix-ті қамтымайды, және guest жағындағы ешқандай қайта конфигурациялау оны өзгертпейді.
Client тек loopback proxy ұсынғанда
Кейбір коммерциялық client-тер жүйелік туннельді мүлде жасамайды. Олар 127.0.0.1-де HTTP немесе SOCKS listener ашады және қолданбалар оны қолданады деп күтеді. Guest бұл socket-ті тікелей көре алмайды, бірақ эмуляторға оны қолдануға болады: не extended controls арқылы (Settings, содан кейін Proxy, manual mode, host 127.0.0.1 және client басып шығарған port), не іске қосу кезінде:
emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080Port-ты client терезесінен көшіріңіз; болжалған port үнсіз сәтсіз аяқталады және сынған туннельге ұқсайды. Бұл нені қамтитынын есте сақтаңыз: HTTP proxy параметрін proxy-ді танитын қолданбалар сақтайды, ал шикі socket-тер оны мүлде елемейді. Егер жүктеме өз қосылымдарын ашатын native binary болса, proxy жолы туннельге тең емес және салыстыруды айқын жасау керек.
Нәтижені guest ішінен дәлелдеңіз
Бір сессияда екі тестпен resolution-ды routing-нен бөліңіз. Сандық мекенжай жауап беріп, атау сәтсіз аяқталса — бұл DNS snapshot мәселесі, ал шешім реттілік немесе айқын resolver. Екеуі де сәтсіз болса, routing немесе policy мәселесі, және келесі тексеру — қолданба өз желілік шектеулері бар work profile ішінде жұмыс істеп жатпағаны.
Соңында, қай guest-те тексеріп жатқаныңызды біліңіз. Өте ескі эмулятор бейнелері guest жағындағы VPN client-ке қажет tun қолдауынсыз шығарылған, сондықтан онда ешбір profile жұмыс істей алмады; қазіргі бейнелерде ол бар. Қазіргі бейнеде сәтсіз аяқталған client — client немесе profile мәселесі, және хост туннелін қайта құру нәтижені өзгертпейді.