VpnService protect() või rakenduse välistamine: mis marsruutimise korda teeb
Kaitske tunnelit kandvat socketit või välistage kogu rakendus: kolm tingimust, mis määravad, millist ulatust teie Androidi VPN vajab.
Tunneli enda pakette saab tunnelist väljas hoida kahel viisil: kaitsta transport-socketit või võtta kogu rakendus VPN-ist välja. Need lahendavad erinevaid probleeme, ja laiema valimine, sest seda on lihtsam ühendada, on täpselt see tee, kuidas rakendused kaotavad juurdepääsu kohalikule võrgule ja jagatud DNS-ile seda märkamata. Alustage sellest, mis peab tunnelist välja jääma, seejärel valige väikseim ulatus, mis selle saavutab.
Mida protect() tunnelist eemaldab
VpnService.protect() on socketipõhine kutse. Annate sellele socketi või deskriptori, mis tunnelit kannab, ja Android märgistab selle socketi nii, et selle liiklus kasutab VPN-liidese asemel alusvõrku. Kõik muu, mida rakendus saadab, järgib endiselt tavalist VPN-marsruuti.
Just see kitsas ulatus ongi mõte. Kaitstud socket ei muuda seda, kuidas teie HTTP-klient nimesid lahendab, millist liidest teie analüütikakutsed kasutavad ega seda, mis juhtub hiljem avatud teise ühendusega.
Kolm tingimust, mis ulatuse määravad
Esimene tingimus on, kas välja peab pääsema ainult tunneli transport. Kui rakenduse ülejäänud liiklus peab endiselt VPN-i kaudu minema, on socketi kaitse õige ulatus. Teine tingimus on, kas kontrollite socketi loomist. Teek, mis avab oma socketi sügaval sees, ei jäta teile kohta, kus kutsuda protect(), kui see ei paku konksu või ei võta vastu valmis socketit. Kolmas tingimus on, kas rakendus peab otse jõudma kohalikku võrku või captive portal'i, mis on teine nõue kui tunneli elus hoidmine.
Rakenduse välistamine addDisallowedApplication()-ga on tööriist jämeda pintsliga. See eemaldab VPN-ist iga ühenduse, mille rakendus loob, sealhulgas need, mida tahtsite kontrollida, ja mõnel seadmel muudab ka kohaliku avastamise käitumist.
Kolmas võimalus on siduda transport valitud võrgu külge bindProcessToNetwork() või socketi tasemel võrgukäepideme abil. See on kasulik, kui seadmel on korraga Wi-Fi ja mobiilside ning soovite, et tunnel läheks kindlat üleslinki pidi.
Kutsuge seda transporti loomise ajal
Kutsuge protect() samas plokis, mis transporti loob, enne connect() või send(). Kui kutse tagastab false, sulgege socket ja laske seadistusel nurjuda; jätkamine jätab teile transpordi, mille paketid võivad uuesti teie enda liidesesse siseneda.
Kuju on piisavalt väike, et hoida seda ühes kohas:
DatagramSocket transport = new DatagramSocket();
if (!protect(transport)) {
transport.close();
throw new IOException("transport not protected");
}
transport.connect(serverAddress);Siin hammustavad kolm detaili. Esiteks,boolean on ainus signaal, mille saate, seega logige nurjumine piisava kontekstiga, et eristada tühistatud nõusolekut tagasilükatud kutsest. Teiseks,protect() katab socketi, mitte deskriptori numbrit: kui sulgete socketi ja kasutate hiljem sama täisarvu teise socketi jaoks, ei ole uus socket kaitstud. Kolmandaks, kui natiivne teek avab transpordi, kaitske deskriptor enne, kui natiivne kood ühendub, muidu võib marsruut olla juba valitud.VpnService'i viide on koht, kus kinnitada, milliseid ülekoormusi teie siht-API tase tegelikult pakub.
Testige blokeeritud teed, mitte ainult õnnelikku
Kontrollige tunneliga üleval, sest see on ainus olek, milles kaks teed saavad erineda. Saatke üks päring kaitstud transpordi kaudu ja üks kooditeelt, mis ei kutsunud kunagi protect(), seejärel võrrelge, mida näeb kaugem ots: kaitstud ühendus peaks saabuma alusvõrgu kui allikaga, samal ajal kui kaitsmata ühendus näitab tunneli enda aadressi ja liigutab tunneli baidiloendureid. Seadmes näitab ss või netstat sama jaotust enne, kui midagi raadiost väljub.
Testige tühistamist eraldi, sest nõusoleku muutus lammutab liidese teie socketikoodi puutumata. Tühistage VPN-i nõusolek või peatage teenus, ehitage transport uuesti üles ja kinnitage, et protect() tagastab endiselt true ja transport ühendub uuesti, kui nõusolek uuesti antakse.
Kui kaitstud päring järgib ikkagi tunnelit, toimub kaitsekutse tõenäoliselt pärast seda, kui socket on juba marsruuditud. Liigutage seda varemaks ja testige uuesti.
Hoidke otsus kirjas transpordi seadistuse kõrval: millised socketid on kaitstud, milline rakenduse liiklus on välistatud ja mida rakendus teeb, kui kaitse ebaõnnestub. Just see rida takistab hilisemal ümberkorraldusel laiendada välistust kogu rakendusele, sest üks test ebaõnnestus. See annab ka järgmisele inimesele viisi kavatsuse kontrollimiseks ilma manifesti tagurpidi konstrueerimiseta.