De kontrôle dy't de measte Android-apps brûke om in VPN te detektearjen is in ynterfacenamme, en it wie nea in VPN-kontrôle. It meldt dat der in ynterface bestiet mei in tekenrige dy't de ûntwikkelder ferwachte, wat op ien apparaat OpenVPN betsjut en op in oar eat folslein net-relatearre. In ping is itselde soart bewiis: it bewiist dat ien bestimming antwurde, net dat in tunnel it pakket droech. Wat it platfoarm eins bleatleit is in set netwurken en de transporten dy't elk dêrfan ferklearret, en dat is in oare fraach mei in oar antwurd.

Myte: as tun0 bestiet, is in VPN oan

Android-VPN-apps binne VpnService-ymplemintaasjes dy't it systeem in tun-bestânsdeskriptor jouwe. De ynterfacenamme komt fan wa't it makke hat: OpenVPN produsearret meastal tun0, PPTP en L2TP produsearje ppp0, WireGuard neamt syn ynterface nei de tunnel, en in IPsec-tunnel hat faaks hielendal gjin konvinsjonele namme. It lêzen fan /proc/net/dev of it opsomjen fan NetworkInterface-objekten siket dêrom nei in konvinsje, net nei in feit.

Beide flaterrjochtings binne libjend. In apparaat kin tun0 hawwe foar in lokale tunnel dy't neat mei de VPN fan de brûker te meitsjen hat, en in folslein sûne WireGuard-tunnel kin ûnsichtber wêze foar in kontrôle dy't allinnich de tekenrige tun0 ken. Ferkearde positives en ferkearde negatives yn deselde funksje meitsje it ûnbrûkber as diagnoaze, want in stipekaartje dat seit „gjin VPN fûn“ is yn gjin inkelde rjochting te fertrouwen.

Tagong is ek smeller wurden. Nijere Android-ferzjes beheine wat in gewoane app lêze kin út /proc, sadat in op namme basearre kontrôle dy't wurke op Android 8 in lege list weromjaan kin op in letter apparaat sûnder ienige koadeferoaring. As de kontrôle stilwei iepen mislearret, konkludearret de app dat der gjin VPN is op hardware dêr't de tunnel wol goed is.

Myte: in slagge ping betsjut dat de tunnel ferkear draacht

In ping nei in ynterne host slagget wannear't der in rûte nei dy host bestiet. Mei split tunnelling kin de host berikber wêze fia Wi-Fi wylst de tunnel oan is en hielendal eat oars docht. Mei in per-app-VPN kin de app dy't de ping docht fan de tunnel útsletten wêze, sadat de ICMP-eko der bûtenút giet en weromkomt, wat it tsjinoerstelde bewiist fan wat de kontrôle oannimt.

ICMP en TCP wurde ek apart filtere. In tunnel dy't eko-fersiken tastean lit mar de TCP-poarte dy't in tsjinst nedich hat weilizze, sil de ping-test trochjaan en yn de app mislearje, en dat is in firewallregel oan de oare kant, net in eigenskip fan it apparaat. De iennige earlike lêzing fan in slagge ping is dat dizze bestimming op dit stuit op dit protokol antwurde.

Wat it platfoarm eins meldt

Fan API 21 ôf jout ConnectivityManager.getAllNetworks() elk netwurk werom dat it systeem ken, en getNetworkCapabilities(network) meldt wat dat netwurk ferklearret. In VPN-netwurk draacht TRANSPORT_VPN. Troch alle netwurken hinne gean beantwurdet ien fraach: is der op dit stuit in VPN oan op dit apparaat?

In twadde, smellere fraach hat in oare oprop nedich. getActiveNetwork() jout it netwurk werom dat it ferkear fan de app no brûke soe, en it kontrolearjen fan deselde kapasiteit dêrop beantwurdet: soe myn ferkear troch in VPN gean? De twa kinne it net iens wêze, en it ferskil is ynformtyf. In VPN dy't oan is mar net aktyf wiist op per-app-routing of in split-tunnel-konfiguraasje, net op in ûntbrekkende tunnel.

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

Beskermje beide oproppen. Kapasiteiten kinne null wêze foar in netwurk dat ferdwûn tusken opsomming en fraach, en it aktive netwurk kin null wêze by in oerdracht. NET_CAPABILITY_NOT_VPN is nuttich yn 'e oare rjochting, om te befestigjen dat in netwurk perfoarst gjin tunnel is, ynstee fan allinnich it VPN-transportflagge te missen.

NetworkInfo wie deselde myte mei in API

ConnectivityManager.TYPE_VPN mei NetworkInfo is de twadde generaasje fan dizze kontrôle, en it is mei reden ferâldere. Op moderne ferzjes kin it objekt dat foar in VPN weromjûn wurdt null wêze wylst de tunnel ferbûn is, sadat koade dy't null as „gjin VPN“ behannelet stilwei in ferkeard negatyf meldt op de apparaten dêr't it antwurd it measte útmakket.

De útstjoering dy't it meastal begeliedt is ek net better. CONNECTIVITY_CHANGE hat in dokumintearre skiednis fan miste VPN-oergongen, ynklusyf builds dêr't it allinnich ôfgie as in VPN ferbûn of ferbrutsen waard, ynstee fan by elke netwurkferoaring. In lústerder boud op dat barren produsearret in steatferoarling dy't fan 'e werjefte fan it platfoarm ôfdriuwt oant de folgjende folsleine werferbining.

Reagearje op callbacks ynstee fan polling

Registrearje in NetworkRequest dy't TRANSPORT_VPN easket en NET_CAPABILITY_NOT_VPN fuorthellet, en rop dan registerNetworkCallback oan mei dy oanfraach. Dan fertelle onAvailable en onLost jo wannear't de ferklearring feroaret, en dat is it barren dêr't jo echt om jouwe. Untregistrearje de callback as de komponint stopt, oars hâldt de app in ferwizing nei in dea skerm en de callback bliuwt ôfgean.

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

Dit easket ACCESS_NETWORK_STATE, dat in normale tastimming is: gjin root, gjin dialooch foar brûkersynstimming, gjin VPN-tastimming. Polling op in timer is it alternatyf dêr't minsken op weromfalle, en it baarnt batterij wylst it noch altyd in oergong mist dy't koarter is as it ynterval, en dat is krekt de oergong dy't in brûker meldt.

Wat it antwurd jo noch altyd net sizze kin

Gjin fan dizze API's meldt oft de tunnel sûn is, op hokker server it einiget of oft it ferkear fan in beskate app der binnen is. In VPN-netwurk kin bestean sûnder brûkbere rûtes, en in per-app-tunnel kin de app dy't de fraach stelt útslute.

Registrearje dus wat de kontrôle seach, net allinnich de boolean. Log de netwurkidentifikaasje, de ferklearre transporten en oft dat netwurk aktyf wie. In rapport dat seit „gjin VPN fûn“ is ûnbrûkber, wylst ien dat seit dat in netwurk TRANSPORT_VPN ferklearre mar getActiveNetwork() Wi-Fi weromjoech, direkt wiist op routing of op in útslutingslist, en dat is in ferbettering dêr't immen mei oan 'e slach kin.

Relatearre artikelen