Telefonul repornește, always-on este activ, «blochează conexiunile fără VPN» este pornit, iar tunelul nu apare niciodată. Nimic nu este configurat greșit: blocarea își face treaba, iar încercarea clientului însuși de a-și atinge punctul final este și ea supusă blocării. Numele punctului final trebuie rezolvat înainte ca tunelul să existe, de către un client căruia i se permite să vorbească cu rețeaua în timp ce toate celelalte aplicații nu au voie. Înțelegerea componentului care face asta, și în ce ordine, este ceea ce transformă acest mister într-o întrebare de configurare.

Ce cere de fapt constructorul de VPN

O aplicație VPN Android nu dă platformei adresa unui server. Ea construiește o interfață locală: adrese și rute pentru tunel, resolverii pe care aplicațiile trebuie să îi folosească în interiorul lui, iar apoi establish() returnează un descriptor de fișier pe care aplicația îl citește și îl scrie ca pachete IP brute. Punctul final îndepărtat nu apare deloc în acel constructor.

Acesta este faptul structural cheie. Platforma creează o interfață tun și aplică politici pe ea; aplicația implementează transportul în spațiul utilizatorului, ceea ce înseamnă că aplicația însăși își rezolvă numele punctului final și deschide conexiunea criptată. Un punct final sub formă de nume de gazdă este așadar posibil — nu pentru că platforma acceptă nume, ci pentru că platforma nu vede niciodată punctul final.

Un singur câmp din constructor primește adrese: serverele DNS. Acestea trebuie să fie adrese numerice de resolver, de obicei cele pe care operatorul vrea să le interogheze prin tunel. Acel câmp descrie unde trimit aplicațiile interogări după ce tunelul este pornit. Nu spune nimic despre felul în care clientul găsește punctul final, iar tratarea celor două ca aceeași setare este locul unde începe confuzia.

Două întrebări DNS, nu una

Prima întrebare este: unde trimit aplicațiile interogări după ce tunelul este pornit? Răspunsul este o adresă de resolver în interiorul tunelului, accesibilă prin interfața tun, și numerică prin construcție.

A doua întrebare este: cum își găsește clientul propriul punct final înainte ca acel tunel să existe? Căutarea are loc în afara tunelului, pe rețeaua de dedesubt, în procesul clientului. Poate folosi un nume și trebuie să folosească un resolver pe care dispozitivul îl poate atinge fără 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

Trei etape, trei simptome diferite. Un singur mesaj de eroare care spune «nu se poate conecta» le topește la un loc, și de aceea oamenii ajung să editeze câmpul de server DNS pentru a repara o problemă care apare înainte ca acel câmp să fie vreodată consultat.

De ce bootstrap-ul poate intra în impas

Always-on cu blocarea activă înseamnă că traficul care nu este în interiorul VPN este eliminat, inclusiv traficul aplicației care deține VPN-ul. Ieșirea este explicită: aplicația apelează protect() pe un socket, ceea ce îl leagă de rețeaua de dedesubt, astfel încât ocolește tunelul și are voie să iasă. Fiecare client VPN trebuie să facă asta pentru transportul propriu, altfel nu ar ajunge niciodată la un server.

Să considerăm acum o instalare în care singurul resolver care cunoaște numele punctului final este el însuși în interiorul tunelului. Clientul are nevoie de tunel pentru a rezolva numele și de nume pentru a construi tunelul. Este o dependență circulară reală, iar nicio configurație de client nu o rezolvă. Este o eroare de proiectare, nu un bug.

Temporizarea expune aceeași dependență în forme mai blânde. La pornire, înainte de prima deblocare, dispozitivul poate să nu aibă încă o rețea utilizabilă; pe un captive portal rețeaua există, dar blochează tot, cu excepția portalului; la trecerea de la Wi-Fi la rețeaua mobilă, rețeaua de dedesubt a socketului protejat se schimbă, iar clientul trebuie să observe și să rezolve din nou. Fiecare dintre acestea este un eveniment de bootstrap, și fiecare merită testat intenționat în loc să fie descoperit la 3 noaptea.

De ce fixarea răspunsului nu este o soluție

Ocolul tentant este să rezolvi numele o dată și să lipești adresa rezultată într-un câmp numeric, sau să o codifici într-o compilare proprie. Pare să funcționeze și transformă un nume într-o fotografie. Când operatorul mută punctul final — o migrare, o schimbare anycast, o adresă regională nouă — clientul continuă să formeze numărul vechi și nimic din interfață nu explică de ce.

Înregistrările DNS au un timp de viață exact pentru ca răspunsurile să se poată schimba; cache-ul este definit în funcție de acea durată, nu pentru totdeauna. Fixarea unui răspuns aruncă mecanismul care face un nume mai bun decât o adresă, păstrând în schimb costul operațional al faptului că s-a folosit un nume.

Fixarea merge de obicei împreună cu un al doilea obicei prost: slăbirea verificărilor de identitate pentru că acum conexiunea eșuează altfel. Verificarea identității serverului nu face parte din problema de bootstrap, iar slăbirea ei schimbă un neajuns DNS pe un risc de interceptare.

Proiecte care supraviețuiesc unei reporniri

Aranjamentul durabil nu este spectaculos. Folosește un client care implementează corect socketurile protejate și își rezolvă punctul final pe rețeaua de dedesubt, și dă-i un nume de punct final care se rezolvă public, sau printr-un resolver accesibil înainte de tunel. Ține blocarea activă; dezactivarea ei completă ca să funcționeze DNS elimină proprietatea pentru care instalarea există.

Acolo unde punctul final trebuie să rămână privat, oferă o cale de bootstrap explicită pe care platforma o poate folosi — un resolver accesibil fără tunel, sau o conexiune de administrare întreținută de operator — și ține acea excepție îngustă și deținută de politică, nu de un comutator al utilizatorului. Documentația Android VpnService este referința pentru ce garantează platforma despre protecție și ciclul de viață, iar referința VpnService.Builder confirmă că câmpul DNS acceptă adrese numerice.

Apoi verifică cele trei etape, în ordine, pe o conexiune nouă după o repornire: numele punctului final se rezolvă, tunelul se stabilește și partenerul se autentifică, iar un nume privat se rezolvă prin resolverul tunelului. Dacă prima etapă eșuează, nimic de după nu poate funcționa, iar corectarea aparține căii de bootstrap — niciodată câmpului de resolver.

  • Rezolvarea punctului final are loc în aplicație, în afara tunelului, pe un socket protejat.
  • Câmpul DNS din constructor este pentru aplicațiile din interiorul tunelului, nu pentru punctul final al clientului.
  • Un resolver accesibil doar prin tunel este un impas, nu o pornire lentă.
  • Testează separat punctul final, autentificarea și căutarea privată după o repornire.

Articole similare