Nustatymuose paliečiate VPN eilutę, matote profilį, kurį įdiegė kas nors kitas, ir pradedate ieškoti iškvietimo, kuris jį pridėtų. Tokio iškvietimo nėra. Programėlė gali atidaryti savo tunelį per VpnService, bet to sąrašo įrašai priklauso platformai ir tam klientui, kuris juos sukūrė. Tiksliai žinant, kur yra riba, sutaupoma savaitė vijantis paslėptas klases.

Pradėkite nuo to, ką rodo Nustatymų ekranas

VPN sąrašas yra profilių, kuriuos įdiegė sistema arba gamintojo klientas, registras: PPTP, L2TP/IPsec, IKEv2 ir visos eilutės, kurias įstūmė OEM programėlė arba MDM. Kiekviena eilutė neša serverio adresą, prisijungimo duomenis ir protokolo įgyvendinimą, kuris gyvena už jūsų proceso ribų. Kai vartotojas ten paliečia Prisijungti, tunelį pakelia platformos klientas, o ne jūsų kodas. Todėl eilutė išlieka po perkrovimo ir todėl jūsų programėlės pašalinimas jos niekada nepašalina.

Vartotojo pusėje sąrašas atrodo kaip API paviršius, vieta, kurioje VPN pridėjimas turėtų būti vieno ketinimo atstumu. Taip nėra. Vieninteliai vieši įėjimo taškai, kurie jį liečia, yra navigacijos ketinimai, o viskas, kas į jį rašo, priklauso platformai arba privilegijuotam komponentui.

Praktinė pasekmė: jei palaikymo tekstas nurodo vartotojams pridėti profilį Nustatymuose, jūsų programėlė visai nėra to srauto dalis.

Ką VpnService iš tikrųjų duoda

VpnService ir VpnService.Builder aprašo vieną tunelį, kuris priklauso jūsų programėlei. Jūs pridedate adresus, maršrutus, DNS serverius ir MTU, apribojate srautą su addAllowedApplication() arba addDisallowedApplication(), o tada establish() grąžina ParcelFileDescriptor TUN sąsajai. Nuo tos akimirkos programėlė skaito IP paketus ir rašo atsakymus, vadinasi, protokolas yra jūsų – jį įgyvendinti arba įterpti: OpenVPN, WireGuard, savas transportas.

Niekas toje sekoje nekalba PPTP, L2TP/IPsec ar IKEv2. Builder neturi jungiklio, kuris sakytų naudok sistemos L2TP klientą, ir nėra jokio atgalinio iškvietimo, leidžiančio valdyti profilį, kurį platforma jau turi. Tai tikroji riba, ir tai dizaino riba, o ne leidimų spraga.

Taigi programėlė tikrai gali būti VPN klientas Android sistemoje. Ji tik negali būti klientų, kurie ateina su telefonu, tvarkyklė.

Sutikimo dialogas nėra puošmena

Kadangi jūsų tunelis gali perimti kitų programėlių srautą, sistema reikalauja, kad vartotojas jį aiškiai patvirtintų. prepare() grąžina Intent, kurį privalote paleisti, patvirtinimas susietas su jūsų paketu, o kol tunelis veikia, būsenos juostoje rodomas nuolatinis indikatorius. Antras VPN jį pakėlus išjungia pirmąjį, nes Android vienu metu veikia tik vienas aktyvus VPN.

Ši vieno aktyvaus taisyklė kliudo žmonėms testuojant. Jūs pakeliate savo tunelį, kai įmonės klientas prijungtas, ir darote išvadą, kad jūsų kodas sulaužytas, o platforma tiesiog persijungė nuo kito kliento. Patvirtinimai gali būti vėliau atšaukti, o prepare() gali grąžinti null įrenginiuose, kuriuose nėra sutikimo veiklos, todėl establish() vis tiek turi apdoroti nesėkmę.

Paslėpti API ir nustatymų ketinimai

Senesni atsakymai nurodo com.android.internal klases ir AIDL sąsajas, kurias naudoja įtaisytasis klientas. Jų nėra SDK, jos keičiasi tarp leidimų be įspėjimo, o programėlių parduotuvės tą prieigą laiko rizika. Įrenginio root'inimas taip pat nepadaro jų stabilių, nes root ir prieiga prie paslėptų API yra nesusijusios problemos.

Palaikoma navigacijos pagalba yra Settings.ACTION_VPN_SETTINGS, kurios reikšmė android.net.vpn.SETTINGS. Išspręskite ją prieš paleisdami, nes kai kurie OEM rinkiniai netiekia šios veiklos, o kai sprendimas nepavyksta, pereikite prie rašytinių žingsnių. Ji nuveda vartotoją į ekraną ir nieko nesukonfigūruoja.

Įrenginio savininko ir MDM keliai yra ta išimtis, kurią žmonės paprastai turi omenyje. DevicePolicyManager gali paskirti visada įjungto VPN paketą, o valdomos konfigūracijos gali iš anksto įkelti nustatymus klientui, kuris juos palaiko, bet tai vis dar ne viešasis SDK, rašantis PPTP profilį.

Pereikite sprendimą iš vartotojo pusės

Jei jūsų produktas turi pernešti srautą, planuokite VpnService ir tikrą protokolų dėklą, ir numatykite laiką sutikimo srautui bei vieno VPN taisyklei. Jei tikslas yra prisijungti prie esamo įmonės profilio, jūsų darbas yra gairės: gili nuoroda į nustatymų ekraną, laukų dokumentavimas, ir leiskite platformos klientui daryti tunelį. Jei programėlei reikia tik pasiekti privatų galinį tašką, jai visai nereikia savo tunelio.

Užrašykite tą sprendimą prieš rašydami kodą, nes trys keliai po pirmojo sprinto beveik neturi nieko bendra.

Paskutinė patikra prieš pradedant: ar reikalavimas sako, kad jungiasi mūsų programėlė, ar kad jungiasi įrenginys? Pirmasis yra VpnService, antrasis yra profilis, kurio negalite sukurti. Teisingai suformuluoti tą sakinį pigiau nei bet koks pertvarkymas.

Susiję straipsniai