Android-emulator og VPN på værten: DNS-snapshot og forklaring af NAT
Gæsten sidder bag emulatorens NAT og beholder den DNS-liste, der blev kopieret ved opstart. Sæt tunnelen op før opstart, og test derefter opløsningen inde fra gæsten.
Når emulatoren ikke kan nå en buildserver, som værtens browser åbner uden problemer, er det nyttige spørgsmål ikke, om VPN virker. Det er, hvilken af to mekanismer gæsten mangler. Den virtuelle enhed kører sin egen netværksstak bag emulatorens NAT, og dens resolverliste er en kopi taget ved opstart, så en tunnel, der kom op bagefter, ændrer værtens vej uden at ændre, hvad gæsten spørger om. Forståelse af de to lag forklarer næsten hver variant af dette problem.
Gæsten er en separat stak bag en fast NAT
QEMU-netværk i brugertilstand placerer gæsten på 10.0.2.15, gateway på 10.0.2.2 og DNS-tjenesten på 10.0.2.3 til 10.0.2.6. Udgående trafik fra gæsten videresendes ikke af værtens kerne; den oversættes til sockets på værtssiden, én per gæsteforbindelse, og de sockets forlader værtens adresserum. Derfor arver en gæsteforbindelse værtens rutningsbeslutning i det øjeblik, den oprettes, og derfor har gæsten ingen rutingtabelpost, der navngiver din tunnel.
Samme mekanisme giver gæsten en nyttig udvej. 10.0.2.2 er et alias for værtens loopback-interface, så en tjeneste, der lytter på 127.0.0.1 på laptoppen, kan nås fra gæsten på den adresse. Alt, hvad klienten kun udstiller på loopback, kan nås den vej, og det er grundlaget for den proxyopsætning, der beskrives nedenfor.
Det, gæsten ikke kan, er at betragte værtens netværk, som om det var et navnerum på den. Der er ingen bro, ingen delt rutingtabel og ingen nedarvet resolver, kun NAT-tjenesten, der tager imod dens pakker, og det snapshot, starteren tog, da den virtuelle enhed startede.
DNS er et snapshot, ikke en levende visning
Ved start læser emulatoren værtens resolverliste og giver gæsten op til fire servere, udstillet på adresserne 10.0.2.3 til 10.0.2.6. Hvis tunnelen var nede på det tidspunkt, indeholder snapshottet enhver offentlig resolver, laptoppen brugte, og gæsten bliver ved med at spørge den resten af livet. Offentlige navne opløses, interne navne fejler, og hvert symptom peger på VPN, mens den faktiske forældede værdi er en resolverliste fanget minutter før, tunnelen kom op.
Så ordensrettelsen er ikke folketro. Forbind tunnelen først, genstart derefter emulatoren, og foretræk en kold opstart frem for gendannelse af et snapshot, fordi et hurtigopstartsbillede kan vende tilbage med den resolver- og rutingtilstand, det gemte tidligere. Hvis du vil se, hvad gæsten bruger nu, så spørg enheden i stedet for værten:
adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.exampleEmulatoren accepterer også en eksplicit resolver ved start, hvilket er nyttigt, når du ved præcis, hvilken server gæsten skal bruge, og farligt, når den server er offentlig:
emulator -avd Pixel_API_34 -dns-server 203.0.113.53En offentlig resolver har ingen kopi af en intern zone, så fastlåsning af én gør et ordensproblem til en permanent fejl. Hvis profilen skubber privat DNS, så lad tunnelen levere det, og koldstart gæsten i stedet for at hardcode en adresse.
Rutning følger værten på forbindelsestidspunktet
Fordi gæsteforbindelser bliver værtssockets, træffes rutningsbeslutningen, når socketen oprettes. Tunnel oppe før anmodningen betyder, at anmodningen forlader gennem tunnelen i henhold til profilens ruter. En split-tunnel-profil, der kun bærer udvalgte præfikser, vil med glæde lade dit private subnet blive udenfor, så værtens tilgængelighed er en hypotese om gæsten, ikke et resultat. Eksisterende gæsteforbindelser beholder den vej, de blev oprettet med, og derfor løser en klient, der genopretter forbindelse, ikke altid en fastlåst download inde i emulatoren.
Verifikationen hører på værtens interface, ikke i gæstens statistik:
sudo tcpdump -ni tun0 'host 203.0.113.10'Hvis gæstens anmodning vises på tunnelinterfacet, virker rutningen, og problemet er oven over. Hvis den vises på det fysiske interface, dækker profilen ikke det præfiks, og ingen mængde omkonfigurering på gæstesiden ændrer det.
Når klienten kun tilbyder en loopback-proxy
Nogle kommercielle klienter opretter slet ikke en systemtunnel. De udstiller en HTTP- eller SOCKS-lytter på 127.0.0.1 og forventer, at applikationer bruger den. Gæsten kan ikke se den socket direkte, men emulatoren kan få besked om at bruge den, enten via de udvidede kontroller (Indstillinger, derefter Proxy, manuel tilstand, vært 127.0.0.1 og den port, klienten udskriver) eller ved start:
emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080Kopiér porten fra klientvinduet; en gættet port fejler lydløst og ligner en brudt tunnel. Husk, hvad dette dækker: en HTTP-proxyindstilling respekteres af proxybevidste applikationer, og rå sockets ignorerer den helt. Hvis arbejdsbyrden er en native binær, der åbner sine egne forbindelser, er proxyvejen ikke ækvivalent med en tunnel, og sammenligningen skal gøres eksplicit.
Bevis resultatet inde fra gæsten
Adskil opløsning fra rutning med to tests i samme session. Et navn, der fejler, mens den numeriske adresse svarer, er et DNS-snapshotproblem, og rettelsen er orden eller en eksplicit resolver. Fejler begge, peger det på rutning eller politik, og den næste kontrol er, om appen kører i en arbejdsprofil med sine egne netværksbegrænsninger.
Endelig, vid, hvilken gæst du tester på. Meget gamle emulatorbilleder blev leveret uden den tun-understøttelse, som en VPN-klient på gæstesiden har brug for, så ingen profil kunne nogensinde virke der; nuværende billeder inkluderer den. En klient, der fejler på et nuværende billede, er et klient- eller profilproblem, og genopbygning af værtens tunnel ændrer ikke resultatet.