VpnService protect() alebo vylúčenie aplikácie: čo vlastne opraví smerovanie
Chráňte vtičnicu, ktorou prechádza tunel, alebo vylúčte celú aplikáciu: tri podmienky, ktoré rozhodujú o tom, aký rozsah vaša Android VPN potrebuje.
Tunelové pakety sa dajú držať mimo tunela dvoma spôsobmi: chrániť prenosovú vtičnicu, alebo vytiahnuť celú aplikáciu z VPN. Riešia odlišné problémy a výber širšej možnosti len preto, že sa ľahšie zapája, je presne ten spôsob, akým aplikácie bez povšimnutia stratia prístup k lokálnej sieti a rozdelia DNS. Začnite tým, čo musí zostať mimo tunela, a potom zvoľte najmenší rozsah, ktorý to zabezpečí.
Čo protect() odoberá z tunela
VpnService.protect() je volanie pre jednotlivú vtičnicu. Odovzdáte mu vtičnicu alebo deskriptor, ktorým prechádza tunel, a Android tú vtičnicu označí tak, aby jej prevádzka používala podkladovú sieť namiesto rozhrania VPN. Všetko ostatné, čo aplikácia odošle, ide ďalej normálnou cestou VPN.
Práve ten úzky rozsah je zmyslom. Chránená vtičnica nemení spôsob, akým váš klient HTTP prekladá názvy, rozhranie, ktoré používajú analytické volania, ani to, čo sa stane s druhým pripojením otvoreným neskôr.
Tri podmienky, ktoré určujú rozsah
Prvá podmienka je, či musí uniknúť iba prenos tunela. Ak má ostatná prevádzka aplikácie stále prechádzať cez VPN, ochrana vtičnice je správny rozsah. Druhá podmienka je, či vytváranie vtičnic riadite vy. Knižnica, ktorá si vtičnicu otvára hlboko v sebe, vám nedáva miesto na volanie protect(), pokiaľ neponúka háčik alebo neprijíma vopred vytvorenú vtičnicu. Tretia podmienka je, či aplikácia potrebuje dosiahnuť lokálnu sieť alebo prihlasovaciu bránu priamo, čo je iná požiadavka než udržať tunel nažive.
Vylúčenie aplikácie pomocou addDisallowedApplication() je tupý nástroj. Odoberie z VPN každé pripojenie, ktoré aplikácia vytvorí, vrátane tých, ktoré ste chceli kontrolovať, a na niektorých zariadeniach mení aj správanie lokálneho objavovania.
Treťou možnosťou je pripútať prenos k zvolenej sieti pomocou bindProcessToNetwork() alebo sieťového popisovača na úrovni vtičnice. To je užitočné vtedy, keď má zariadenie súčasne Wi-Fi aj mobilnú sieť a chcete, aby tunel išiel konkrétnym smerom nahor.
Volajte ho počas vytvárania prenosu
protect() volajte v tom istom bloku, ktorý vytvára prenos, pred connect() alebo send(). Ak volanie vráti false, zatvorte vtičnicu a zlyhajte nastavenie; pokračovanie vám nechá prenos, ktorého pakety môžu znova vstúpiť do vášho vlastného rozhrania.
Tvar je dosť malý na to, aby zostal na jednom mieste:
DatagramSocket transport = new DatagramSocket();
if (!protect(transport)) {
transport.close();
throw new IOException("transport not protected");
}
transport.connect(serverAddress);Tri detaily tu hryzú. Po prvé, logická hodnota je jediný signál, ktorý dostanete, preto zlyhanie zalogujte s kontextom, podľa ktorého rozlíšite odvolaný súhlas od odmietnutého volania. Po druhé, protect() pokrýva vtičnicu, nie číslo deskriptora: ak vtičnicu zatvoríte a to isté celé číslo neskôr použijete pre inú vtičnicu, nová vtičnica chránená nie je. Po tretie, keď prenos otvára natívna knižnica, chráňte deskriptor skôr, než sa natívny kód pripojí, inak už môže byť trasa zvolená. Referencia VpnService je miesto, kde potvrdíte, ktoré preťaženia vaša cieľová úroveň API skutočne ponúka.
Testujte zablokovanú cestu, nielen tú šťastnú
Overujte so zapnutým tunelom, pretože to je jediný stav, v ktorom sa obe cesty môžu líšiť. Pošlite jednu požiadavku cez chránený prenos a jednu z kódu, ktorý nikdy nezavolal protect(), a porovnajte, čo vidí vzdialený koniec: chránené pripojenie má prísť s podkladovou sieťou ako zdrojom, kým nechránené ukazuje vlastnú adresu tunela a hýbe jeho počítadlami bajtov. Na zariadení ss alebo netstat ukáže rovnaké rozdelenie skôr, než čokoľvek opustí rádio.
Odvolanie testujte samostatne, pretože zmena súhlasu zbúra rozhranie bez toho, aby sa dotkla vášho kódu vtičnice. Odvolajte súhlas s VPN alebo zastavte službu, znova vytvorte prenos a overte, že protect() stále vracia true a že sa prenos po obnovení súhlasu znova pripojí.
Ak chránená požiadavka napriek tomu ide cez tunel, volanie ochrany sa pravdepodobne deje až po tom, čo bola vtičnica už smerovaná. Presuňte ho skôr a testujte znova.
Rozhodnutie si nechajte zapísané pri nastavení prenosu: ktoré vtičnice sú chránené, ktorá prevádzka aplikácie je vylúčená a čo aplikácia robí, keď ochrana zlyhá. Práve ten riadok bráni neskoršiemu refaktoru rozšíriť vylúčenie na celú aplikáciu len preto, že jeden test zlyhával. Zároveň dáva ďalšiemu človeku možnosť skontrolovať zámer bez spätného inžinierstva manifestu.