Når emulatoren ikkje når ein byggjeserver som nettlesaren på vertsmaskina opnar heilt fint, er det nyttige spørsmålet ikkje om VPN-en verkar. Spørsmålet er kva av to mekanismar gjesten manglar. Den virtuelle eininga køyrer sin eigen nettverksstack bak NAT-en til emulatoren, og resolverlista hennar er ein kopi teken ved oppstart, så ein tunnel som kjem opp etterpå endrar ruta til verten utan å endre det gjesten spør om. Å forstå desse to laga forklarer nesten alle variantar av problemet.

Gjesten er ein eigen stack bak ein fast NAT

Brukarmodusnettverket til QEMU plasserer gjesten på 10.0.2.15 med gateway på 10.0.2.2, og DNS-tenesta på 10.0.2.3 til 10.0.2.6. Utgåande trafikk frå gjesten blir ikkje vidaresend av kjerna på verten; han blir omsett til sockets på vertssida, éin per tilkopling frå gjesten, og desse socketa går ut frå adresserommet til verten. Difor arvar ei gjestetilkopling rutingsavgjerda til verten i det augneblinken ho blir laga, og difor har gjesten inga oppføring i rutetabellen som nemner tunnelen din.

Den same mekanismen gjev gjesten ein nyttig naudutgang. 10.0.2.2 er eit alias for loopback-grensesnittet til verten, så ei teneste som lyttar på 127.0.0.1 på laptoppen er tilgjengeleg frå gjesten på den adressa. Alt klienten berre syner på loopback kan ein nå den vegen, og det er grunnlaget for proxyoppsettet som er skildra lenger ned.

Det gjesten ikkje kan, er å sjå på nettverket til verten som om det var hans eigen namespace. Det finst inga bru, ingen delt rutetabell og ingen arva resolver, berre NAT-tenesta som tek imot pakkane hans og snapshottet som oppstartaren tok då den virtuelle eininga starta.

DNS er eit snapshot, ikkje eit levande bilete

Ved oppstart les emulatoren resolverlista til verten og gjev gjesten opptil fire tenarar, synte på adressene 10.0.2.3 til 10.0.2.6. Var tunnelen nede i det augneblinken, inneheld snapshottet den offentlege resolvaren laptoppen brukte, og gjesten held fram med å spørje han heile livet. Offentlege namn blir løyste, interne namn feilar, og alle symptom peikar på VPN-en medan den eigentlege utdaterte verdien er ei resolverliste fanga nokre minutt før tunnelen kom opp.

Rekkjefølgjerettinga er difor ikkje folketru. Kopla til tunnelen først, start så emulatoren på nytt, og føretrekk kald oppstart framfor gjenoppretting av eit snapshot, fordi eit hurtigoppstartsbilete kan kome tilbake med resolver- og rutetilstanden det lagra tidlegare. Vil du sjå kva gjesten brukar no, spør eininga og ikkje verten:

adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.example

Emulatoren godtek òg ein eksplisitt resolver ved oppstart, noko som er nyttig når du veit nøyaktig kva tenar gjesten skal bruke, og farleg når den tenaren er offentleg:

emulator -avd Pixel_API_34 -dns-server 203.0.113.53

Ein offentleg resolver har ingen kopi av ei intern sone, så å låse éin gjer eit rekkjefølgjeproblem om til ein varig feil. Viss profilen skyv privat DNS, lat tunnelen levere han og kaldstart gjesten i staden for å hardkode ei adresse.

Ruting følgjer verten ved tilkoplingstidspunktet

Fordi gjestetilkoplingar blir sockets på verten, blir rutingsavgjerda teken når socketen blir laga. Tunnel oppe før førespurnaden tyder at førespurnaden går ut gjennom tunnelen, underlagd rutene til profilen. Ein splitt-tunnel-profil som berre ber utvalde prefiks lèt det private subnettet ditt bli ståande utanfor, så nåbarheit frå verten er ein hypotese om gjesten, ikkje eit resultat. Eksisterande gjestetilkoplingar held på ruta dei vart laga med, og difor rettar ikkje ein klient som koplar til på nytt alltid opp ei nedlasting som heng i emulatoren.

Stadfestinga høyrer heime på grensesnittet til verten, ikkje i statistikken til gjesten:

sudo tcpdump -ni tun0 'host 203.0.113.10'

Viss førespurnaden frå gjesten dukkar opp på tunellgrensesnittet, verkar rutinga og problemet ligg over henne. Viss han dukkar opp på det fysiske grensesnittet, dekkjer ikkje profilen det prefikset, og inga omkonfigurering på gjestesida vil endre det.

Når klienten berre tilbyr ein loopback-proxy

Nokre kommersielle klientar lagar ingen systemtunnel i det heile. Dei syner ein HTTP- eller SOCKS-lyttar på 127.0.0.1 og ventar at applikasjonane brukar han. Gjesten kan ikkje sjå den socketen direkte, men emulatoren kan bli beden om å bruke han, anten gjennom dei utvida kontrollane (Settings, så Proxy, manuell modus, vert 127.0.0.1 og porten klienten skriv ut) eller ved oppstart:

emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080

Kopier porten frå klientvindauget; ein gissa port feilar lydlaust og ser ut som ein øydelagd tunnel. Hugs kva dette dekkjer: ei HTTP-proxyinnstilling blir respektert av applikasjonar som kjenner proxy, og rå sockets ignorerer henne heilt. Viss arbeidslasta er ei native binærfil som opnar sine eigne tilkoplingar, er proxyvegen ikkje jamgod med ein tunnel, og samanlikninga må gjerast eksplisitt.

Prov resultatet frå innsida av gjesten

Skil oppslag frå ruting med to testar i same økta. Eit namn som feilar medan den numeriske adressa svarar, er eit DNS-snapshot-problem, og løysinga er rekkjefølgje eller ein eksplisitt resolver. Feilar begge, peikar det på ruting eller policy, og neste sjekk er om appen køyrer i ein arbeidsprofil med eigne nettverksavgrensingar.

Til slutt, vit kva gjest du testar på. Særs gamle emulatorbilete vart leverte utan tun-støtta ein VPN-klient på gjestesida treng, så ingen profil kunne nokon gong verke der; dagens bilete har henne. Ein klient som feilar på eit dagsaktuelt bilete, er eit klient- eller profilproblem, og å byggje vertstunnelen på nytt endrar ikkje resultatet.

Relaterte artiklar