Emulátor Android a VPN na hostiteľovi: snapshot DNS a NAT
Hosť sedí za NAT emulátora a drží zoznam DNS skopírovaný pri boote. Zdvíhnite tunel pred bootom a potom otestujte prekladanie mien zvnútra hosťa.
Keď sa emulátor nedostane na build server, ktorý prehliadač na hostiteľovi otvára bez problémov, užitočná otázka nie je, či VPN funguje. Otázka je, ktorý z dvoch mechanizmov hosťovi chýba. Virtuálne zariadenie prevádzkuje vlastný sieťový zásobník za NAT emulátora, a jeho zoznam resolverov je kópia urobená pri boote, takže tunel, ktorý sa zdvihne neskôr, mení cestu hostiteľa, ale nemení to, na čo sa hosť pýta. Pochopenie týchto dvoch vrstiev vysvetľuje takmer každý variant tohto problému.
Hosť je samostatný zásobník za pevným NAT
Sieť QEMU v používateľskom režime umiestňuje hosťa na 10.0.2.15 s bránou na 10.0.2.2 a DNS službou na 10.0.2.3 až 10.0.2.6. Odchádzajúca prevádzka hosťa sa nepreposiela jadrom hostiteľa; prekladá sa na sockety na strane hostiteľa, jeden pre každé spojenie hosťa, a tieto sockety vychádzajú z adresného priestoru hostiteľa. Preto spojenie hosťa dedí rozhodnutie smerovania hostiteľa v momente vzniku, a preto hosť nemá v tabuľke trás záznam, ktorý by menoval váš tunel.
Ten istý mechanizmus dáva hosťovi užitočný východ. 10.0.2.2 je alias rozhrania loopback hostiteľa, takže služba počúvajúca na 127.0.0.1 na notebooku je z hosťa dostupná na tej adrese. Všetko, čo klient sprístupňuje iba na loopbacku, je takto dostupné, a to je základ nastavenia proxy opísaného nižšie.
Čo hosť nemôže, je pozorovať sieť hostiteľa, akoby bol jej namespace. Neexistuje most, zdieľaná tabuľka trás ani zdedený resolver; existuje iba NAT služba, ktorá prijíma jeho pakety, a snapshot, ktorý urobil spúšťač pri štarte virtuálneho zariadenia.
DNS je snapshot, nie živý pohľad
Pri štarte emulátor prečíta zoznam resolverov hostiteľa a dá hosťovi až štyri servery, sprístupnené na adresách 10.0.2.3 až 10.0.2.6. Ak bol tunel v tom momente dole, snapshot obsahuje ten verejný resolver, ktorý notebook používal, a hosť sa ho pýta celý život. Verejné mená sa prekladajú, interné mená zlyhávajú, a všetky príznaky ukazujú na VPN, kým skutočná zastaraná hodnota je zoznam resolverov zachytený niekoľko minút pred zdvihnutím tunela.
Oprava poradia preto nie je folklór. Najprv pripojte tunel, potom reštartujte emulátor, a uprednostnite studený štart pred obnovením snapshotu, pretože obraz quick-boot sa môže vrátiť s predtým uloženým stavom resolverov a trás. Ak potrebujete vidieť, čo hosť teraz používa, pýtajte sa zariadenia, nie hostiteľa:
adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.exampleEmulátor prijíma aj explicitný resolver pri štarte, čo je užitočné, keď presne viete, ktorý server má hosť používať, a nebezpečné, keď je ten server verejný:
emulator -avd Pixel_API_34 -dns-server 203.0.113.53Verejný resolver nemá kópiu internej zóny, takže pripnutie jedného mení problém poradia na trvalú poruchu. Ak profil tlačí súkromný DNS, nechajte tunel, aby ho dodal, a studeno naštartujte hosťa namiesto natvrdo zapísanej adresy.
Smerovanie nasleduje hostiteľa v čase spojenia
Keďže spojenia hosťa sa stávajú socketmi hostiteľa, rozhodnutie o smerovaní sa prijíma pri vytvorení socketu. Tunel hore pred požiadavkou znamená, že požiadavka vychádza cez tunel, podľa trás profilu. Profil split-tunnel, ktorý prenáša len vybrané prefixy, rád nechá vašu súkromnú podsietu vonku, takže dosiahnuteľnosť hostiteľa je hypotéza o hosťovi, nie výsledok. Existujúce spojenia hosťa si zachovajú cestu, s ktorou vznikli, a preto klient, ktorý sa znova pripojí, nie vždy opraví zaseknuté sťahovanie v emulátore.
Overenie patrí rozhraniu hostiteľa, nie štatistikám hosťa:
sudo tcpdump -ni tun0 'host 203.0.113.10'Ak sa požiadavka hosťa objaví na rozhraní tunela, smerovanie funguje a problém je nad ním. Ak sa objaví na fyzickom rozhraní, profil ten prefix nepokrýva, a žiadna rekonfigurácia na strane hosťa to nezmení.
Keď klient ponúka iba loopback proxy
Niektorí komerční klienti vôbec nevytvárajú systémový tunel. Sprístupňujú HTTP alebo SOCKS listener na 127.0.0.1 a očakávajú, že aplikácie ho použijú. Hosť ten socket priamo nevidí, ale emulátoru sa dá povedať, aby ho použil, buď cez rozšírené ovládanie (Settings, potom Proxy, manuálny režim, hostiteľ 127.0.0.1 a port, ktorý klient vypíše), alebo pri štarte:
emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080Skopírujte port z okna klienta; uhádnutý port zlyhá potichu a vyzerá ako pokazený tunel. Majte na pamäti, čo to pokrýva: nastavenie HTTP proxy rešpektujú aplikácie, ktoré proxy poznajú, a surové sockety ho úplne ignorujú. Ak je záťažou natívny binárnik, ktorý si otvára vlastné spojenia, cesta cez proxy nie je ekvivalentná tunelu a porovnanie treba urobiť explicitne.
Dokážte výsledok zvnútra hosťa
Oddeľte prekladanie mien od smerovania dvoma testami v tej istej relácii. Meno, ktoré zlyhá, kým číselná adresa odpovedá, je problém snapshotu DNS a riešením je poradie alebo explicitný resolver. Ak zlyhajú obidve, ukazuje to na smerovanie alebo politiku, a ďalšia kontrola je, či aplikácia beží v pracovnom profile s vlastnými sieťovými obmedzeniami.
Nakoniec vedzte, na ktorom hosťovi testujete. Veľmi staré obrazy emulátora sa dodávali bez podpory tun, ktorú potrebuje VPN klient na strane hosťa, takže tam žiadny profil nemohol fungovať; aktuálne obrazy ju majú. Klient, ktorý zlyhá na aktuálnom obraze, je problém klienta alebo profilu, a prestavba tunela hostiteľa výsledok nezmení.