VpnService protect() ali izvzetje aplikacije: kaj dejansko popravi usmerjanje
Zaščitite vtičnico, ki nosi tunel, ali izvzemite celotno aplikacijo: trije pogoji, ki določajo, kakšen obseg potrebuje vaš Android VPN.
Tunelove lastne pakete lahko obdržite zunaj tunela na dva načina: zaščitite prenosno vtičnico ali odstranite celotno aplikacijo iz VPN-a. Rešujeta različna problema, izbira širše možnosti samo zato, ker jo je lažje povezati, pa je natanko tisto, zaradi česar aplikacije neopazno izgubijo dostop do lokalnega omrežja in razdeljeni DNS. Začnite s tem, kar mora ostati zunaj tunela, nato izberite najmanjši obseg, ki to doseže.
Kaj protect() odstrani iz tunela
VpnService.protect() je klic za posamezno vtičnico. Predate mu vtičnico ali deskriptor, ki nosi tunel, in Android to vtičnico označi, da njen promet uporablja osnovno omrežje namesto vmesnika VPN. Vse ostalo, kar aplikacija pošlje, še vedno sledi običajni poti VPN.
Prav ta ozek obseg je bistvo. Zaščitena vtičnica ne spremeni, kako vaš odjemalec HTTP razrešuje imena, kateri vmesnik uporabljajo vaši analitični klici, ali kaj se zgodi z drugo povezavo, odprto pozneje.
Trije pogoji, ki določijo obseg
Prvi pogoj je, ali mora ubežati le prenos tunela. Če naj bi šel preostali promet aplikacije še vedno skozi VPN, je zaščita vtičnice pravi obseg. Drugi pogoj je, ali nadzorujete ustvarjanje vtičnic. Knjižnica, ki vtičnico odpre globoko v sebi, vam ne pusti mesta za klic protect(), razen če ponuja kavelj ali sprejema že zgrajeno vtičnico. Tretji pogoj je, ali mora aplikacija neposredno doseči lokalno omrežje ali prijavno past, kar je druga zahteva kot ohranjanje tunela pri življenju.
Izvzetje aplikacije z addDisallowedApplication() je grob pripomoček. Iz VPN-a odstrani vsako povezavo, ki jo aplikacija vzpostavi, vključno s tistimi, ki ste jih hoteli pregledati, na nekaterih napravah pa spremeni tudi vedenje lokalnega odkrivanja.
Tretja možnost je, da prenos privežete na izbrano omrežje z bindProcessToNetwork() ali z omrežnim ročajem na ravni vtičnice. To je uporabno, ko ima naprava hkrati Wi-Fi in mobilno omrežje in želite, da tunel potuje po določeni povezavi navzgor.
Pokličite ga med ustvarjanjem prenosa
Pokličite protect() v istem bloku, ki ustvari prenos, pred connect() ali send(). Če klic vrne false, zaprite vtičnico in nastavitev naj spodleti; nadaljevanje vam pusti prenos, katerega paketi lahko znova vstopijo v vaš lastni vmesnik.
Oblika je dovolj majhna, da ostane na enem mestu:
DatagramSocket transport = new DatagramSocket();
if (!protect(transport)) {
transport.close();
throw new IOException("transport not protected");
}
transport.connect(serverAddress);Tu ugriznejo tri podrobnosti. Prvič, logična vrednost je edini signal, ki ga dobite, zato neuspeh zabeležite s toliko konteksta, da ločite preklicano soglasje od zavrnjenega klica. Drugič, protect() pokriva vtičnico, ne številke deskriptorja: če vtičnico zaprete in pozneje isto celo število uporabite za drugo vtičnico, nova vtičnica ni zaščitena. Tretjič, ko prenos odpre izvorna knjižnica, zaščitite deskriptor, preden se izvorna koda poveže, sicer je pot morda že izbrana. Referenca VpnService je kraj, kjer potrdite, katere preobremenitve vaša ciljna raven API v resnici ponuja.
Preizkusite blokirano pot, ne le srečne
Preverjajte z dvignjenim tunelom, ker je to edino stanje, v katerem se poti lahko razlikujeta. Pošljite eno zahtevo skozi zaščiteni prenos in eno iz kode, ki nikoli ni poklicala protect(), nato primerjajte, kaj vidi oddaljeni konec: zaščitena povezava naj bi prispela z osnovnim omrežjem kot virom, medtem ko nezaščitena kaže naslov samega tunela in premika njegove števce bajtov. Na napravi ss ali netstat pokaže isto razdelitev, še preden karkoli zapusti radijski vmesnik.
Preklic preizkusite ločeno, ker sprememba soglasja podre vmesnik, ne da bi se dotaknila vaše kode vtičnice. Prekličite soglasje VPN ali ustavite storitev, znova zgradite prenos in potrdite, da protect() še vedno vrne true in da se prenos znova poveže, ko je soglasje spet podeljeno.
Če zaščitena zahteva kljub temu sledi tunelu, se zaščitni klic verjetno zgodi potem, ko je bila vtičnica že usmerjena. Premaknite ga prej in znova preizkusite.
Odločitev obdržite zapisano poleg nastavitve prenosa: katere vtičnice so zaščitene, kateri promet aplikacije je izvzet in kaj aplikacija naredi, ko zaščita spodleti. Prav ta vrstica prepreči, da bi poznejše prestrukturiranje razširilo izvzetje na celotno aplikacijo, ker je en sam test spodletel. Naslednji osebi tudi da način, da preveri namen, ne da bi razstavljala manifest.