Ne, aplikacija VpnService ne more vklopiti VPN-a telefona
Aplikacija ima v lasti en tunel in njegov življenjski cikel, ne stikala VPN na telefonu. Privolitev je mogoče preklicati, hkrati teče le en VPN, pakete pa razčlenjujete sami.
Napačna predpostavka je, da aplikacija VpnService obrne sistemsko stikalo in da je telefon od takrat zaščiten. Kar se v resnici zgodi, je ožje: aplikacija zaprosi za privolitev, zgradi vmesnik, bere in piše pakete prek deskriptorja datoteke ter vrne vmesnik, ko se ustavi. Hkrati je lahko živ le en tak tunel, sistem pa mu ga lahko odvzame, ne da bi vprašal. Večina zmedenega vedenja, ki ga ljudje pripisujejo protokolu, izhaja prav iz tega modela lastništva.
Vsak prehod življenjskega cikla obravnavajte kot del zasnove in ne kot robni primer.
Mit: aplikacija vklopi VPN telefona
Tok se začne s VpnService.prepare(), ki vrne Intent, ki ga mora uporabnik sprejeti, in nadaljuje s establish(), ki lahko pozneje še vedno spodleti iz razlogov, ki jih aplikacija ne nadzoruje. Vzpostavitev drugega tunela deaktivira prvi vmesnik in zamenja sistemsko obvestilo. Nikjer v tem zaporedju aplikacija nima stikala za celotno napravo; ima deskriptor, ki ji je bil dodeljen, in pakete, ki pristanejo na njem. Tudi trajno obvestilo pripada sistemu in ne zasnovi aplikacije.
Ker se vmesnik dodeli in ne zagrabi, lahko drug odjemalec mesto kadarkoli prevzame. Aplikacija to izve prek povratnega klica, ne prek vračilne vrednosti.
Prisilna ustavitev aplikacije je v plošči z obvestili vidna iz istega razloga: sistem poroča, kaj je dodelil, ne pa, kaj se je aplikacija odločila prikazati.
Mit: privolitev se da enkrat
Ko sistem preda tunel drugemu odjemalcu, pošlje transakcijo preklica po binderju, ki ga osnovni razred vrne iz onBind(). Aplikacija, ki ta binder zamenja s svojim, mora transakcijo preklica posredovati sama, sicer VpnService.onRevoke() nikoli ne sproži in storitev še naprej piše v deskriptor, ki ne obstaja več. Odobritev lahko prekliče tudi uporabnik, sistem pa lahko storitev ustavi med ponovnim zagonom ali ponovno povezavo v načinu vedno vklopljeno.
Ukvarjanje s tem je konkretno delo in ne vrstica dnevnika: prenehajte brati deskriptor, zaprite ga, počistite zastavico povezanosti in uporabniku povejte, v katerem stanju je. Nato odločite, ali naj aplikacija znova vzpostavi, znova vpraša ali počaka, ker lahko v konfiguraciji vedno vklopljeno sistem storitev vrne sam.
Aplikacija, ki preklic obravnava kot izjemo in ne kot stanje, bo poročala o povezanosti, medtem ko se vsak paket, ki ga zapiše, zavrže, kar je najslabši možni način odpovedi za orodje za zasebnost.
Mit: vmesnik filtrira promet namesto vas
Kar prispe, je surov IP. Zajemanje ali filtriranje pomeni razčlenjevanje glav IP, TCP, UDP in IPv6, sledenje tokovom in pisanje odgovorov nazaj v deskriptor, kar naredi iz aplikacije za zajemanje majhen omrežni sklad in ne sistemsko zmogljivost. protect() obstaja zato, da se lastna transportna vtičnica aplikacije izogne svojemu tunelu, namesto da bi zajela sebe, in vrne logično vrednost, ki si zasluži preverjanje pri vsaki vtičnici, ustvarjeni po dvigu tunela.
Seznami dovoljenih in prepovedanih aplikacij v graditelju odločajo, čigav promet vstopi v vmesnik. Ne dajejo dostopa do koristne obremenitve onkraj IP paketov, ki jih vmesnik nosi, in noben API ne razkrije tunela drugega odjemalca niti navaja sistemske profile VPN. Omrežne zmogljivosti lahko povedo, da je omrežje transport VPN, ne pa, čigav je tunel.
Zato vprašanja o stanju drugih aplikacij dobijo protislovne odgovore: informacija preprosto ni izpostavljena vašemu procesu.
Kaj življenjski cikel v resnici zahteva
Sledite stanjem, ki jih nadzorujete: pripravljeno, vzpostavljeno, preklicano, ustavljeno. Ponovna povezava mora biti razstavljanje in nato vzpostavljanje, z enim lastnikom deskriptorja in transportne vtičnice, ker se bosta dve komponenti, ki tekmujeta za vzpostavitev, borili za edino prosto mesto. Zagoni v ozadju so v sodobnem Androidu omejeni, zato oddajanje ob zagonu ni zagotovilo; uporabite storitev v ospredju z njenim obvestilom, kjer raven API to dovoljuje.
Beležite prehod in ne le končnega stanja, in držite stroj stanj dovolj majhen, da preizkusite vsako pot. Stanje, do katerega v preizkusu ne morete priti, je stanje, s katerim se boste na terenu srečali brez dnevnika.
Preizkusite življenjski cikel na napravi
Emulatorji lahko ponaredijo povezljivost, ne pa prepričljivo poti privolitve in preklica, zato jih zaženite na resnični napravi z nameščenim drugim odjemalcem VPN, ki bo ukradel mesto.
adb shell dumpsys connectivity | grep -i -A3 vpn
adb shell dumpsys activity services | grep -i -A2 vpnservice
adb logcat -s VpnService:V AndroidRuntime:E
adb shell am force-stop com.example.vpnapp
Zaženite tunel, potrdite obvestilo in vmesnik, nato povežite drugega odjemalca in opazujte, ali se povratni klic preklica izvede in ali se stanje počisti. Prisilno ustavite aplikacijo in preverite, ali kaj še vedno poroča o živem deskriptorju.
Ponovite zaporedje po ponovnem zagonu v načinu vedno vklopljeno, ker se ta pot razlikuje od povezave, ki jo začne uporabnik. Ne iščete zelene ikone, ampak dokaz, da je aplikacija prenehala uporabljati deskriptor, ki ga ni več imela v lasti.