Virheellinen oletus on, että VpnService-sovellus kääntää järjestelmän kytkintä ja siitä lähtien puhelin on suojattu. Mitä todella tapahtuu, on kapeampaa: sovellus pyytää suostumusta, rakentaa rajapinnan, lukee ja kirjoittaa paketteja tiedostokuvauksen kautta ja palauttaa rajapinnan lopettaessaan. Vain yksi tällainen tunneli voi olla elossa kerrallaan, ja järjestelmä voi ottaa sen pois kysymättä. Suurin osa siitä hämmentävästä käytöksestä, jonka ihmiset painavat protokollan syyksi, tulee juuri tästä omistusmallista.

Käsittele jokaista elinkaaren siirtymää osana suunnittelua, älä reunatapauksena.

Myytti: sovellus kytkee puhelimen VPN:n päälle

Virta alkaa VpnService.prepare():sta, joka palauttaa Intentin, jonka käyttäjän on hyväksyttävä, ja jatkuu establish():llä, joka voi silti myöhemmin epäonnistua syistä, joita sovellus ei hallitse. Toisen tunnelin luominen poistaa ensimmäisen rajapinnan käytöstä ja korvaa järjestelmäilmoituksen. Missään tuon sarjan kohdassa sovellus ei omista koko laitteen kytkintä; se omistaa kuvauksen, joka sille annettiin, ja paketit, jotka laskeutuvat siihen. Jopa pysyvä ilmoitus kuuluu järjestelmälle, ei sovelluksen suunnittelulle.

Koska rajapinta annetaan eikä kaapata, toinen asiakas voi ottaa paikan milloin tahansa. Sovellus saa sen tietoonsa takaisinkutsun kautta, ei paluuarvon kautta.

Sovelluksen pakkospysäytys näkyy ilmoituspaneelissa samasta syystä: järjestelmä raportoi, mitä se antoi, ei sitä, mitä sovellus päätti näyttää.

Myytti: suostumus annetaan kerran

Kun järjestelmä luovuttaa tunnelin toiselle asiakkaalle, se lähettää peruutustapahtuman sille binderille, jonka perusluokka palauttaa kohdasta onBind(). Sovelluksen, joka korvaa tuon binderin omallaan, on itse välitettävä peruutustapahtuma eteenpäin, muuten VpnService.onRevoke() ei laukea koskaan ja palvelu jatkaa kirjoittamista kuvaukseen, jota ei enää ole. Käyttäjä voi myös peruuttaa hyväksynnän, ja järjestelmä voi pysäyttää palvelun uudelleenkäynnistyksen tai aina päällä olevan uudelleenyhdistämisen aikana.

Sen käsitteleminen on konkreettista työtä, ei lokirivi: lopeta kuvauksen lukeminen, sulje se, tyhjennä yhdistetty-lippu ja kerro käyttäjälle, missä tilassa hän on. Päätä sitten, pitäisikö sovelluksen luoda yhteys uudelleen, kysyä uudelleen vai odottaa, koska aina päällä olevassa kokoonpanossa järjestelmä voi tuoda palvelun takaisin itsestään.

Sovellus, joka kohtelee peruutusta poikkeuksena eikä tilana, raportoi yhdistettynä, vaikka jokainen sen kirjoittama paketti hylätään, ja se on yksityisyystyökalulle pahin mahdollinen vikatila.

Myytti: rajapinta suodattaa liikennettä puolestasi

Saapuva on raakaa IP:tä. Kaappaaminen tai suodattaminen tarkoittaa IP-, TCP-, UDP- ja IPv6-otsikoiden jäsentämistä, virtausten seuraamista ja vastausten kirjoittamista takaisin kuvaukseen, mikä tekee kaappaussovelluksesta pienen verkkopinon eikä järjestelmän ominaisuuden. protect() on olemassa, jotta sovelluksen oma siirtoyhteys ohittaa tunnelinsa sen sijaan että kaappaisi itsensä, ja se palauttaa totuusarvon, joka ansaitsee tarkistuksen jokaisella pistokkeella, joka luodaan sen jälkeen kun tunneli on pystyssä.

Rakentajan sallittujen ja kiellettyjen sovellusten listat päättävät, kenen liikenne tulee rajapintaan. Ne eivät anna pääsyä hyötykuormaan rajapinnan kantamien IP-pakettien ulkopuolelle, eikä mikään API paljasta toisen asiakkaan tunnelia tai luettele järjestelmän VPN-profiileja. Verkon ominaisuudet voivat kertoa, että verkko on VPN-siirtoa, mutta eivät sitä, kenen tunneli se on.

Siksi tilakysymykset muista sovelluksista saavat ristiriitaisia vastauksia: tieto ei yksinkertaisesti ole prosessisi saatavilla.

Mitä elinkaari todella vaatii

Seuraa tiloja, joita hallitset: valmisteltu, luotu, peruutettu, pysäytetty. Uudelleenyhdistämisen pitäisi olla purkaminen ja sitten luominen, yhdellä omistajalla kuvaukselle ja siirtoyhteydelle, koska kaksi komponenttia, jotka kilpailevat luomisesta, tappelevat ainoasta vapaasta paikasta. Taustakäynnistykset on rajoitettu nykyaikaisessa Androidissa, joten käynnistyksen lähetys ei ole tae; käytä etualapalvelua ilmoituksineen siellä, missä API-taso sen sallii.

Kirjaa siirtymä, älä vain lopputilaa, ja pidä tilakone tarpeeksi pienenä, jotta voit testata jokaisen polun. Tila, johon et pääse testissä, on tila, jonka kohtaat kentällä ilman lokia.

Testaa elinkaari laitteella

Emulaattorit voivat huijata yhteyttä mutta eivät suostumuksen ja peruutuksen polkua vakuuttavasti, joten aja nämä oikealla laitteella, johon on asennettu toinen VPN-asiakas varastamaan paikka.

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

Käynnistä tunneli, vahvista ilmoitus ja rajapinta, yhdistä sitten toinen asiakas ja katso, ajetaanko peruutuksen takaisinkutsu ja tyhjeneekö tila. Pakkopysäytä sovellus ja tarkista, raportoiko mikään vielä elävää kuvausta.

Toista sarja aina päällä olevan uudelleenkäynnistyksen jälkeen, koska se polku eroaa käyttäjän aloittamasta yhteydestä. Et etsi vihreää kuvaketta vaan todistetta siitä, että sovellus lakkasi käyttämästä kuvausta, jota se ei enää omistanut.

Aiheeseen liittyvät artikkelit