Dodirnete red VPN u Postavkama, vidite profil koji je instalirao neko drugi i počnete tražiti poziv koji ga dodaje. Takav poziv ne postoji. Aplikacija može otvoriti vlastiti tunel preko VpnService, ali unosi na tom popisu pripadaju platformi i onom klijentu koji ih je stvorio. Točno znanje gdje leži granica štedi vam tjedan lova na skrivene klase.

Počnite od onoga što prikazuje zaslon Postavki

Popis VPN je registar profila koje je instalirao sustav ili klijent dobavljača: PPTP, L2TP/IPsec, IKEv2 i svi redovi koje je gurnuo OEM program ili MDM. Svaki red nosi adresu poslužitelja, akreditive i implementaciju protokola koja živi izvan vašeg procesa. Kada korisnik tamo dodirne Poveži, tunel podiže klijent platforme, a ne vaš kod. Zato red preživi restart i zato ga deinstalacija vaše aplikacije nikada ne uklanja.

S korisnikove strane popis izgleda kao API površina, mjesto gdje dodavanje VPN-a treba biti na udaljenosti jednog intenta. Nije. Jedine javne ulazne točke koje ga dotiču su navigacijski intenti, a sve što u njega piše pripada platformi ili privilegiranoj komponenti.

Praktična posljedica: ako tekst podrške kaže korisnicima da dodaju profil u Postavkama, vaša aplikacija uopće nije dio tog toka.

Što vam VpnService zapravo daje

VpnService i VpnService.Builder opisuju jedan tunel koji posjeduje vaša aplikacija. Dodajete adrese, rute, DNS poslužitelje i MTU, ograničavate promet pomoću addAllowedApplication() ili addDisallowedApplication(), a zatim establish() vraća ParcelFileDescriptor za TUN sučelje. Od tog trenutka aplikacija čita IP pakete i piše odgovore, što znači da je protokol vaš da ga implementirate ili ugradite: OpenVPN, WireGuard, prilagođeni transport.

Ništa u tom slijedu ne govori PPTP, L2TP/IPsec ili IKEv2. Builder nema prekidač koji kaže koristi sistemski L2TP klijent, i nema povratnog poziva koji vam dopušta da upravljate profilom koji platforma već posjeduje. To je prava granica, i to je granica dizajna, a ne praznina u dozvolama.

Dakle aplikacija sasvim može biti VPN klijent na Androidu. Samo ne može biti upravitelj za klijente koji dolaze s telefonom.

Dijalog pristanka nije ukras

Budući da vaš tunel može zahvatiti promet drugih aplikacija, sustav traži da ga korisnik izričito odobri. prepare() vraća Intent koji morate pokrenuti, odobrenje je vezano za vaš paket, a dok je tunel aktivan statusna traka pokazuje stalni indikator. Drugi VPN koji se podigne deaktivira prvi, jer Android drži jedan aktivan VPN u jednom trenutku.

To pravilo jednog aktivnog zbunjuje ljude u testiranju. Podignete svoj tunel dok je korporativni klijent povezan i zaključite da je vaš kod pokvaren, a platforma se jednostavno prebacila s drugog klijenta. Odobrenja se mogu kasnije povući, a prepare() može vratiti null na uređajima gdje nema aktivnosti za pristanak, pa establish() i dalje mora obrađivati neuspjeh.

Skriveni API-ji i intenti postavki

Stariji odgovori upućuju na com.android.internal klase i AIDL sučelja koje koristi ugrađeni klijent. Nisu u SDK-u, mijenjaju se između izdanja bez najave, a trgovine aplikacija tretiraju taj pristup kao rizik. Rootanje uređaja ih također ne čini stabilnim, jer root i pristup skrivenim API-jima su nepovezani problemi.

Podržana navigacijska pomoć je Settings.ACTION_VPN_SETTINGS, čija je vrijednost android.net.vpn.SETTINGS. Razriješite ga prije pokretanja, jer neke OEM gradnje ne isporučuju tu aktivnost; prijeđite na pisane korake kada razrješavanje ne uspije. On vodi korisnika na zaslon i ništa ne konfigurira.

Putevi vlasnika uređaja i MDM-a su izuzetak koji ljudi obično misle. DevicePolicyManager može odrediti paket stalno uključenog VPN-a, a upravljane konfiguracije mogu prethodno učitati postavke za klijent koji ih podržava, ali to još uvijek nije javni SDK koji piše PPTP profil.

Prođite odluku s korisnikove strane

Ako vaš proizvod mora prenositi promet, planirajte VpnService plus pravi protokolni stog i predvidite vrijeme za tok pristanka i pravilo jednog VPN-a. Ako je cilj povezati se na postojeći korporativni profil, vaš je posao navođenje: duboka veza do zaslona postavki, dokumentiranje polja i pustite klijent platforme da radi tuneliranje. Ako aplikacija samo treba dosegnuti privatnu krajnju točku, nije joj uopće potreban vlastiti tunel.

Zapišite tu odluku prije nego što napišete kod, jer tri puta nakon prvog sprinta gotovo da nemaju ništa zajedničko.

Posljednja provjera prije početka: kaže li zahtjev da se naša aplikacija povezuje ili da se uređaj povezuje? Prvo je VpnService, drugo je profil koji ne možete stvoriti. Ispraviti tu rečenicu jeftinije je od bilo kojeg refaktora.

Povezani članci