Telefonen starter på nytt, always-on er på, «blokker tilkoblinger uten VPN» er på, og tunnelen kommer aldri opp. Ingenting er feilkonfigurert: blokkeringen gjør jobben sin, og klientens eget forsøk på å nå endepunktet sitt er også underlagt den. Endepunktnavnet må løses før tunnelen finnes, av en klient som har lov til å snakke med nettverket mens alle andre apper ikke har det. Å forstå hvilken komponent som gjør dette, og i hvilken rekkefølge, er det som gjør dette fra et mysterium til et konfigurasjonsspørsmål.

Hva VPN-byggeren faktisk ber om

En Android VPN-app gir ikke plattformen en serveradresse. Den bygger et lokalt grensesnitt: adresser og ruter for tunnelen, oppløserne appene skal bruke inne i den, og deretter returnerer establish() en fildeskriptor som appen leser og skriver som rå IP-pakker. Det eksterne endepunktet forekommer ikke i den byggeren i det hele tatt.

Det er det sentrale strukturelle faktumet. Plattformen lager et tun-grensesnitt og håndhever policy på det; appen implementerer transporten i brukerrommet, noe som betyr at appen selv løser endepunktnavnet sitt og åpner den krypterte tilkoblingen. Et endepunkt som vertsnavn er derfor mulig — ikke fordi plattformen støtter navn, men fordi plattformen aldri ser endepunktet.

Ett felt i byggeren tar likevel adresser: DNS-serverne. De må være numeriske oppløseradresser, vanligvis de operatøren vil skal spørres gjennom tunnelen. Det feltet beskriver hvor appene sender spørringer etter at tunnelen er oppe. Det sier ingenting om hvordan klienten finner endepunktet, og å behandle de to som samme innstilling er der forvirringen begynner.

To DNS-spørsmål, ikke ett

Det første spørsmålet er: hvor sender appene spørringer når tunnelen er oppe? Svaret er en oppløseradresse inne i tunnelen, nåbar gjennom tun-grensesnittet, og numerisk av konstruksjon.

Det andre spørsmålet er: hvordan finner klienten sitt eget endepunkt før den tunnelen finnes? Det oppslaget skjer utenfor tunnelen, på det underliggende nettverket, i klientens prosess. Det kan bruke et navn, og det må bruke en oppløser enheten kan nå uten VPN.

StageWho resolvesPathFailure looks like
Endpoint lookupThe VPN appUnderlying network, protected socketNever connects; no tunnel interface traffic
Peer authenticationClient and serverTunnel transportConnects then drops; certificate or key error
Private name lookupApps via the tunnelResolver inside the tunTunnel up, internal sites do not resolve

Tre stadier, tre ulike symptomer. Én feilmelding som sier «kan ikke koble til» slår dem sammen, og det er derfor folk begynner å redigere DNS-serverfeltet for å fikse et problem som oppstår før feltet i det hele tatt blir lest.

Hvorfor oppstarten kan låse seg

Always-on med blokkeringen på betyr at trafikk som ikke er inne i VPN-en, blir droppet, også trafikk fra appen som eier VPN-en. Utveien er eksplisitt: appen kaller protect() på en socket, som binder den til det underliggende nettverket slik at den går utenom tunnelen og får slippe ut. Hver VPN-klient må gjøre dette for sin egen transport, ellers ville den aldri nå en server.

Tenk nå på en utrulling der den eneste oppløseren som kjenner endepunktnavnet, selv ligger inne i tunnelen. Klienten trenger tunnelen for å løse navnet, og navnet for å bygge tunnelen. Det er en ekte sirkulær avhengighet, og ingen klientkonfigurasjon løser den. Det er en designfeil, ikke en programfeil.

Timing avdekker den samme avhengigheten i mildere former. Ved oppstart før første opplåsing kan enheten ennå ikke ha et brukbart nettverk; på en captive portal finnes nettverket, men blokkerer alt unntatt portalen; ved overgang fra Wi-Fi til mobilnett endres det underliggende nettverket til den beskyttede socketen, og klienten må merke det og løse på nytt. Hver av disse er en oppstartshendelse, og hver er verdt å teste med vilje i stedet for å oppdage klokken 3 om natten.

Hvorfor det ikke hjelper å låse svaret

Den fristende omveien er å løse navnet én gang og lime den resulterende adressen inn i et numerisk felt, eller hardkode den i et eget bygg. Det ser ut til å virke, og det gjør et navn om til et stillbilde. Når operatøren flytter endepunktet — en migrering, en anycast-endring, en ny regional adresse — fortsetter klienten å ringe det gamle, og ingenting i grensesnittet forklarer hvorfor.

DNS-poster har en levetid nettopp for at svarene skal kunne endre seg; hurtiglagring er definert ut fra den levetiden, ikke for alltid. Å låse et svar kaster bort mekanismen som gjør et navn bedre enn en adresse, samtidig som driftskostnaden ved å ha brukt et navn beholdes.

Låsing pleier også å følge med en andre dårlig vane: å lempe på identitetskontrollen fordi tilkoblingen nå feiler annerledes. Verifisering av serveridentitet er ikke en del av oppstartsproblemet, og å svekke den bytter en DNS-ulempe mot en risiko for avlytting.

Design som overlever en omstart

Den varige ordningen er lite glamorøs. Bruk en klient som implementerer beskyttede socketer riktig og løser endepunktet sitt på det underliggende nettverket, og gi den et endepunktnavn som løses offentlig, eller gjennom en oppløser som er nåbar før tunnelen. La blokkeringen stå på; å slå den helt av for å få DNS til å virke fjerner egenskapen utrullingen finnes for.

Der endepunktet må forbli privat, legg til en eksplisitt oppstartsvei plattformen kan bruke — en oppløser som er nåbar uten tunnelen, eller en administrasjonsforbindelse operatøren vedlikeholder — og hold det unntaket smalt og eid av policy, ikke av en brukerbryter. Android VpnService-dokumentasjonen er referansen for hva plattformen garanterer om beskyttelse og livssyklus, og VpnService.Builder-referansen bekrefter at DNS-feltet tar numeriske adresser.

Deretter verifiser de tre stadiene, i rekkefølge, på en ny tilkobling etter omstart: endepunktnavnet løses, tunnelen etableres og motparten autentiseres, og et privat navn løses gjennom tunnelens oppløser. Hvis første stadium feiler, kan ingenting senere virke, og rettelsen hører hjemme i oppstartsveien — aldri i oppløserfeltet.

  • Oppløsning av endepunktet skjer i appen, utenfor tunnelen, på en beskyttet socket.
  • DNS-feltet i byggeren er for apper inne i tunnelen, ikke for klientens eget endepunkt.
  • En oppløser som bare er nåbar gjennom tunnelen, er en låsning, ikke en treg start.
  • Test endepunkt, autentisering og privat oppslag hver for seg etter en omstart.

Relaterte artikler