„Android“ VPN be root: kam priklauso sutikimas, maršrutai ir blokavimas
Sutikimas, TUN sąsaja ir sistemos blokavimo politika yra trys skirtingi leidimai. Nustatykite, kuris komponentas valdo kiekvieną iš jų, prieš vertindami „Android“ VPN programą.
Root nėra tai, kas leidžia „Android“ VPN programai perduoti srautą, blokuoti nutekėjimus ar išgyventi perkrovimą. Žmonės visa tai apibendrina kaip „programa turi VPN leidimą“, o tai paslepia tris atskirus mechanizmus: vartotojo duotą sutikimą, sistemos sukuriamą paketų sąsają ir platformos blokavimo politiką, kurios programa neapibrėžia. Vertinti „Android“ VPN dizainą reiškia klausti, kuo iš šių trijų teiginys iš tikrųjų remiasi, nes kiekvienas turi skirtingą savininką ir skirtingą gedimo būdą.
Sutikimas ateina per sistemos veiklą
VpnService.prepare() nieko nesuteikia. Kai sutikimo nėra, jis grąžina intent į sistemos sutikimo veiklą, o programa atveria tą dialogą, kad vartotojas patvirtintų paslaugą. Pačios programos proceso paleidimas, leidimo įtraukimas į manifestą ar pasirinktinio ekrano „įjungti VPN“ rodymas nesukuria leidimo.
Leidimas taip pat ribojamas. Jis priklauso paketui vartotojo profilyje, todėl asmeninė kopija ir darbo kopija yra atskiri sprendimai, o įrenginio savininkas gali valdomą profilį paruošti kitaip nei asmeninį. Jei dialogas niekada nepasirodo ir prepare() grąžina null, sutikimas tam paketui tame profilyje jau egzistuoja; tai neįrodo, kad programa patikima, tik kad leidimas yra.
Sąsaja yra užklausa, kurią sistema įvykdo
Po sutikimo programa aprašo, ko nori, naudodama VpnService.Builder: adresus, maršrutus, DNS serverius, MTU ir, kur palaikoma, programas, kurias reikia įtraukti arba išskirti. establish() prašo sistemos sukurti tunelio sąsają ir nukreipti į ją atitinkamą srautą. Maršrutizavimo sprendimas priklauso sistemai; programa gauna failo deskriptorių ir tada turi padaryti ką nors naudingo su paketais.
| What you observe | Who actually owns it |
|---|---|
| VPN consent dialog | The system, triggered by prepare() |
| Routes, DNS and app lists | The app requests them; the system applies them |
| One active VPN per profile | The platform; a new service replaces the old one |
| Always-on and block-without-VPN | Device policy enforced by the platform |
Ta lentelė yra architektūra vienoje vietoje. Programa dalyvauja apdorojant paketus; jai nepriklauso sąsaja, maršrutizavimo lentelė ar leidžiamų tarnybų skaičius.
Tunelio socket turi ištrūkti iš savo tunelio
Ryšys, kuriuo keliauja šifruotas srautas, pats yra socket. Jei jis nukreipiamas atgal į sąsają, kurią programa ką tik sukūrė, tunelis priklauso nuo tunelio ir sustoja. VpnService.protect() susieja tą socket su pagrindiniu tinklu, kad jis apeitų užfiksavimą, todėl teisingas klientas apsaugo savo išorinį socket prieš pirmąjį rankos paspaudimą.
adb shell dumpsys connectivity | grep -i -A5 vpn
adb shell settings get global always_on_vpn_app
adb shell settings get global always_on_vpn_lockdown
Šios komandos rodo įdiegtą VPN tinklą, visada įjungtą paketą ir ar nustatytas užraktas. Tai tik skaitymo stebėjimai: jei reikšmės neatitinka to, ką teigia dizainas, teiginys yra apie programos sąsają, o ne apie sistemos būseną.
Blokavimas gali priklausyti platformai
„Android“ dokumentuoja politiką, kuri blokuoja ryšius, nenaudojančius VPN. Tas vykdymas yra platformos sutartis, o ne programa, kuri cikle kartoja ryšio bandymus. Jungiklis yra įrenginio VPN nustatymuose kaip Blokuoti ryšius be VPN, o valdomame įrenginyje savininkas gali jį įjungti visam profiliui. Šis skirtumas svarbus vertinant rinkodaros teiginį: klientas gali rodyti spynos piktogramą ir agresyviai jungtis iš naujo, kol tiesioginis srautas dar įmanomas, arba aprėptos programos gali likti neprisijungusios, nes sistema vykdo užraktą.
Spynos piktogramą piešia programa, todėl ji įrodo tik tai, kad programa mano esanti prisijungusi. Ar kita programa praras tinklo prieigą, sprendžia platforma, todėl naudinga patikra yra stebėti, kaip ta programa nepavyksta, kol tunelis įjungtas.
„Visada įjungta“ žymė iš programų parduotuvės taip pat nepakeičia šios sutarties. Visada įjungta ir užraktas yra įrenginio nustatymai, kuriuos dažnai taiko savininkas, o jų elgesį išskirtoms programoms apibrėžia platforma. Skaitykite nustatymą, ne ženklą.
Keturi klausimai dizaino apžvalgai
Pirma, kas sutiko: kuris paketas, kuris profilis ir ar tai buvo vartotojas, ar valdomo įrenginio politika? Antra, ko programa paprašė: kokių maršrutų, kokių adresų šeimų, kokių programų įtraukta ar išskirta? Trečia, kas nutinka, kai tunelis neprieinamas: sistema blokuoja ar srautas grįžta į pagrindinį tinklą? Ketvirta, ką programa daro su gautais paketais?
Ketvirtas klausimas yra tas, į kurį leidimų modelis negali atsakyti. Sutikimas ir TUN sąsaja įrodo, kad programa gali gauti srautą, o ne kad ji jį šifruoja, autentifikuoja partnerį ar švariai atsistato. Tai įgyvendinimo savybės, ir būtent čia sąžininga apžvalga praleidžia laiką.
Nereikalinga root užklausa netampa teisėta vien todėl, kad rezultatas pavadinamas išjungikliu, o sutikimo dialogas nėra saugumo auditas. Laikykite tris leidimus atskirai ir kiekvienas teiginys tampa patikrinamas.