Android always-on VPN: korleis endepunktnamnet vert løyst fyrst
Android blokkerer trafikk før tunnelen finst, men klienten må likevel løyse endepunktet sitt. Her er rekkjefølgja, og kvar ho låser seg.
Telefonen startar på nytt, always-on er på, «blokker tilkoplingar utan VPN» er på, og tunnelen kjem aldri opp. Ingenting er feilkonfigurert: blokkeringa gjer jobben sin, og klienten sitt eige forsøk på å nå endepunktet sitt er òg underlagt henne. Endepunktnamnet må løysast før tunnelen finst, av ein klient som har lov til å snakke med nettet medan alle andre appar ikkje har det. Å forstå kva komponent som gjer dette, og i kva rekkjefølgje, er det som gjer dette frå eit mysterium til eit konfigurasjonsspørsmål.
Kva VPN-byggjaren faktisk ber om
Ein Android VPN-app gjev ikkje plattformen ei serveradresse. Han byggjer eit lokalt grensesnitt: adresser og ruter for tunnelen, oppløysarane appane skal bruke inne i han, og deretter returnerer establish() ein fildeskriptor som appen les og skriv som rå IP-pakkar. Det eksterne endepunktet førekjem ikkje i den byggjaren i det heile.
Det er det sentrale strukturelle faktumet. Plattformen lagar eit tun-grensesnitt og handhevar policy på det; appen implementerer transporten i brukarrommet, noko som tyder at appen sjølv løyser endepunktnamnet sitt og opnar den krypterte tilkoplinga. Eit endepunkt som vertsnamn er difor mogleg — ikkje fordi plattformen støttar namn, men fordi plattformen aldri ser endepunktet.
Eitt felt i byggjaren tek likevel adresser: DNS-serverane. Dei må vere numeriske oppløysaradresser, vanlegvis dei operatøren vil skal spørjast gjennom tunnelen. Det feltet skildrar kvar appane sender spørjingar etter at tunnelen er oppe. Det seier ingenting om korleis klienten finn endepunktet, og å handsame dei to som same innstilling er der forvirringa byrjar.
To DNS-spørsmål, ikkje eitt
Det fyrste spørsmålet er: kvar sender appane spørjingar når tunnelen er oppe? Svaret er ei oppløysaradresse inne i tunnelen, nåbar gjennom tun-grensesnittet, og numerisk av konstruksjon.
Det andre spørsmålet er: korleis finn klienten sitt eige endepunkt før den tunnelen finst? Det oppslaget skjer utanfor tunnelen, på det underliggande nettet, i prosessen til klienten. Det kan bruke eit namn, og det må bruke ein oppløysar som eininga kan nå utan VPN.
| Stage | Who resolves | Path | Failure looks like |
|---|---|---|---|
| Endpoint lookup | The VPN app | Underlying network, protected socket | Never connects; no tunnel interface traffic |
| Peer authentication | Client and server | Tunnel transport | Connects then drops; certificate or key error |
| Private name lookup | Apps via the tunnel | Resolver inside the tun | Tunnel up, internal sites do not resolve |
Tre stadium, tre ulike symptom. Éi feilmelding som seier «kan ikkje kople til» slår dei saman, og det er difor folk byrjar å redigere DNS-serverfeltet for å fikse eit problem som oppstår før feltet i det heile vert lese.
Kvifor oppstarten kan låse seg
Always-on med blokkeringa på tyder at trafikk som ikkje er inne i VPN-en, vert droppa, òg trafikk frå appen som eig VPN-en. Utvegen er eksplisitt: appen kallar protect() på ein socket, som bind han til det underliggande nettet slik at han går utanom tunnelen og får sleppe ut. Kvar VPN-klient må gjere dette for sin eigen transport, elles ville han aldri nå ein server.
Tenk no på ein utrulling der den einaste oppløysaren som kjenner endepunktnamnet, sjølv ligg inne i tunnelen. Klienten treng tunnelen for å løyse namnet, og namnet for å byggje tunnelen. Det er ein ekte sirkulær avhengnad, og ingen klientkonfigurasjon løyser han. Det er ein designfeil, ikkje ein programfeil.
Timing avdekkjer den same avhengnaden i mildare former. Ved oppstart før fyrste opplåsing kan eininga enno ikkje ha eit brukbart nett; på ein captive portal finst nettet, men blokkerer alt utanom portalen; ved overgang frå Wi-Fi til mobilnett endrar det underliggande nettet til den verna socketen seg, og klienten må merke det og løyse på nytt. Kvar av desse er ei oppstartshending, og kvar er verd å teste med vilje i staden for å oppdage klokka 3 om natta.
Kvifor det ikkje hjelper å låse svaret
Den freistande omvegen er å løyse namnet éin gong og lime den resulterande adressa inn i eit numerisk felt, eller hardkode henne i eit eige bygg. Det ser ut til å verke, og det gjer eit namn om til eit stillbilete. Når operatøren flyttar endepunktet — ein migrering, ei anycast-endring, ei ny regional adresse — held klienten fram med å ringje det gamle, og ingenting i grensesnittet forklarer kvifor.
DNS-postar har ei levetid nettopp for at svara skal kunne endre seg; hurtiglagring er definert ut frå den levetida, ikkje for alltid. Å låse eit svar kastar bort mekanismen som gjer eit namn betre enn ei adresse, samstundes som driftskostnaden ved å ha brukt eit namn vert halden.
Låsing plar òg følgje med ein andre dårleg vane: å lempe på identitetskontrollen fordi tilkoplinga no feilar annleis. Verifisering av serveridentitet er ikkje ein del av oppstartsproblemet, og å svekke henne byter eit DNS-ubehag mot ein risiko for avlytting.
Design som overlever ein omstart
Den varige ordninga er lite glamorøs. Bruk ein klient som implementerer verna socketar rett og løyser endepunktet sitt på det underliggande nettet, og gjev han eit endepunktnamn som vert løyst offentleg, eller gjennom ein oppløysar som er nåbar før tunnelen. Lat blokkeringa stå på; å slå henne heilt av for å få DNS til å verke fjernar den eigenskapen utrullinga finst for.
Der endepunktet må halde fram med å vere privat, legg til ein eksplisitt oppstartsveg plattformen kan bruke — ein oppløysar som er nåbar utan tunnelen, eller ei administrasjonsforbindelse operatøren vedlikeheld — og hald det unntaket smalt og eigd av policy, ikkje av ein brukarbrytar. Android VpnService-dokumentasjonen er referansen for kva plattformen garanterer om vern og livssyklus, og VpnService.Builder-referansen stadfester at DNS-feltet tek numeriske adresser.
Deretter verifiser dei tre stadia, i rekkjefølgje, på ei ny tilkopling etter omstart: endepunktnamnet vert løyst, tunnelen vert etablert og motparten autentiserast, og eit privat namn vert løyst gjennom oppløysaren til tunnelen. Om fyrste stadium feilar, kan ingenting seinare verke, og rettinga høyrer heime i oppstartsvegen — aldri i oppløysarfeltet.
- Oppløysing av endepunktet skjer i appen, utanfor tunnelen, på ein verna socket.
- DNS-feltet i byggjaren er for appar inne i tunnelen, ikkje for klienten sitt eige endepunkt.
- Ein oppløysar som berre er nåbar gjennom tunnelen, er ei låsing, ikkje ein treg start.
- Test endepunkt, autentisering og privat oppslag kvar for seg etter ein omstart.