Android aplikazio gehienek VPN bat detektatzeko erabiltzen duten egiaztapena interfaze-izen bat da, eta inoiz ez zen VPN egiaztapena izan. Garatzaileak espero zuen kate bat duen interfaze bat existitzen dela adierazten du, eta horrek gailu batean OpenVPN esan nahi du eta beste batean erabateko zerikusirik ez duen zerbait. Ping-ek frogabide mota bera da: helmuga batek erantzun zuela frogatzen du, ez tunel batek paketea eraman zuela. Plataformak benetan erakusten duena sare multzo bat eta bakoitzak deklaratzen dituen transportak dira, eta hori beste galdera bat da, beste erantzun batekin.

Mitoa: tun0 badago, VPN bat martxan dago

Android VPN aplikazioak VpnService inplementazioak dira, eta sistemari tun fitxategi-deskriptore bat ematen diote. Interfaze-izena sortu zuenarengandik dator: OpenVPN-k normalean tun0 sortzen du, PPTP-k eta L2TP-k ppp0 sortzen dute, WireGuard-ek tunelaren izena ematen dio interfazeari, eta IPsec tunel batek agian ez du inolako izen konbentzionalik aurkeztuko. Beraz, /proc/net/dev irakurtzeak edo NetworkInterface objektuak zerrendatzeak konbentzio bat bilatzen du, ez gertaera bat.

Errorearen bi norabideak bizirik daude. Gailu batek tun0 izan dezake erabiltzailearen VPN-arekin zerikusirik ez duen tokiko tunel baterako, eta WireGuard tunel erabat osasuntsu bat ikusezina izan daiteke tun0 katea bakarrik ezagutzen duen egiaztapen batentzat. Funtzio berean faltsuki positiboek eta faltsuki negatiboek erabilgaitz egiten dute diagnostiko gisa, izan ere, «VPN-rik ez da detektatu» dioen laguntza-txartel batek ez du norabide batean ere fidagarritasunik.

Sarbidea ere estutu da. Android bertsio berriagoek murriztu egiten dute aplikazio arrunt batek /proc-etik zer irakur dezakeen, beraz Android 8-n funtzionatzen zuen izen-egiaztapen batek zerrenda huts bat itzul dezake geroagoko gailu batean, koderik aldatu gabe. Egiaztapenak isilki huts egiten duenean alde irekira, aplikazioak VPN-rik ez dagoela ondorioztatzen du tunela ondo dagoen hardwarean.

Mitoa: ping arrakastatsu batek tunelak trafikoa daramala esan nahi du

Barneko host baterako ping-ek arrakasta du host horretarako bide bat dagoen bakoitzean. Tunel zatituarekin, host-a Wi-Fi bidez irisgarria izan daiteke tunela martxan dagoen bitartean eta erabat beste zerbait egiten ari dela. Aplikazioko VPN batekin, ping egiten ari den aplikazioa tunelaren kanpoan gera daiteke, beraz ICMP oihartzuna kanpora ateratzen da eta itzuli egiten da, eta horrek egiaztapenak suposatzen duenaren kontrakoa frogatzen du.

ICMP eta TCP ere bereiz filtratzen dira. Oihartzun-eskaerak onartzen dituen baina zerbitzu batek behar duen TCP ataka uzten duen tunel batek ping proba gaindituko du eta aplikazioan huts egingo du, eta hori beste aldeko suebaki araua da, ez gailuaren propietatea. Ping arrakastatsu baten irakurketa zintzo bakarra da helmuga horrek protokolo horri une honetan erantzun ziola.

Plataformak benetan zer adierazten duen

API 21etik aurrera, ConnectivityManager.getAllNetworks()-ek sistemak ezagutzen duen sare bakoitza itzultzen du, eta getNetworkCapabilities(network)-ek sare horrek zer deklaratzen duen adierazten du. VPN sare batek TRANSPORT_VPN darama. Sare guztietan zehar egiteak galdera bati erantzuten dio: VPN-rik martxan al dago gailu honetan oraintxe?

Bigarren galdera estuago batek beste dei bat behar du. getActiveNetwork()-ek aplikazioaren trafikoak oraintxe erabiliko lukeen sarea itzultzen du, eta gaitasun bera hartan egiaztatzeak erantzuten du: nire trafikoak VPN batetik pasako luke? Biak desados egon daitezke, eta desadostasun hori informatiboa da. Martxan dagoen baina aktiboa ez den VPN batek aplikazioko bideratze batera edo tunel zatitu baten konfiguraziora seinalatzen du, ez falta den tunel batera.

Network active = cm.getActiveNetwork();
NetworkCapabilities caps = cm.getNetworkCapabilities(active);
boolean viaVpn = caps != null
    && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);

Babestu bi deiak. Gaitasunak null izan daitezke zerrendatzearen eta kontsultaren artean desagertu den sare baterako, eta sare aktiboa null izan daiteke eskualdatze batean. NET_CAPABILITY_NOT_VPN beste norabidean da erabilgarria, sare bat inolaz ere ez dela tunel bat baieztatzeko, eta ez soilik VPN garraioaren bandera falta zaiola.

NetworkInfo mito bera zen API batekin

ConnectivityManager.TYPE_VPN NetworkInfo-rekin egiaztapen honen bigarren belaunaldia da, eta arrazoi batengatik zaharkituta dago. Bertsio modernoetan VPN baterako itzulitako objektua null izan daiteke tunela konektatuta dagoen bitartean, beraz null «VPN-rik ez» gisa tratatzen duen kodeak isilki negatibo faltsu bat ematen du erantzunak gehien axola duen gailuetan.

Normalean laguntzen dion emisioa ere ez da hobea. CONNECTIVITY_CHANGE-k VPN trantsizioak galtzeko historia dokumentatua du, VPN bat konektatu edo deskonektatu zenean soilik pizten zen bertsioak barne, sare-aldaketa bakoitzean beharrean. Horren gainean eraikitako entzule batek plataformaren ikuspegitik urruntzen den egoera-aldagai bat sortzen du, hurrengo konexio osoa arte.

Erreakzionatu dei-itzulerei, ez galdetze periodikoari

Erregistratu TRANSPORT_VPN eskatzen duen eta NET_CAPABILITY_NOT_VPN kentzen duen NetworkRequest bat, eta gero deitu registerNetworkCallback eskaera horrekin. Orduan onAvailable eta onLost-ek deklarazioa noiz aldatzen den esaten dizute, eta hori da benetan axola zaizun gertaera. Utzi dei-itzuleren erregistroa osagaia gelditzen denean, bestela aplikazioak pantaila hildako baten erreferentzia gordeko du eta dei-itzulera pizten jarraituko du.

NetworkRequest req = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
    .build();
cm.registerNetworkCallback(req, callback);

Horrek ACCESS_NETWORK_STATE behar du, baimen arrunta dena: root-ik gabe, erabiltzailearen onespen-elkarrizketarik gabe, VPN baimenik gabe. Tenporizadorearekin galdetzea da jendeak atzera egiten duen alternatiba, eta bateria erretzen du, bitartean tarteak baino laburragoa den trantsizio bat galtzen duela, eta horixe da erabiltzaile batek salatzen duen trantsizioa.

Erantzunak oraindik esan ezin dizuna

API horietako batek ere ez du adierazten tunela osasuntsu dagoen, zein zerbitzarian amaitzen den edo aplikazio jakin baten trafikoa haren barruan dagoen. VPN sare bat bide erabilgarririk gabe egon daiteke, eta aplikazioko tunel batek galdera egiten duen aplikazioa kanpoan utz dezake.

Beraz, erregistratu egiaztapenak ikusi zuena, ez bakarrik boolearra. Erregistratu sarearen identifikatzailea, deklaratutako transportak eta sare hura aktiboa zen. «VPN-rik ez da detektatu» dioen txosten bat erabilgaitza da, baina sare batek TRANSPORT_VPN deklaratu zuela baina getActiveNetwork()-ek Wi-Fi itzuli zuela dioen txostenak zuzenean bideratzera edo kanporatze-zerrenda batera seinalatzen du, eta hori norbaitek landu dezakeen konponketa da.

Erlazionatutako artikuluak