Hvers vegna Android VpnService-göngin þín hætta að beina umferð
Fjórar VpnService-tilgátur sem brotna í framleiðslu: eitt göng í einu, umfang slóða, listar eftir forritum og röð slökktar, með prófun fyrir hverja.
Fjórar forsendur um Android VpnService kostuðu mig einu sinni stóran hluta viku, og engin þeirra snerist um netþjónustulag. Forritið sagði tengt, lyklatáknið sat í stöðustikunni, og umferðin fór samt út um venjulegu slóðina. Ég hélt áfram að gera ráð fyrir að göngin væru mín þangað til ég stöðvaði þau, að slóðirnar sem ég bætti við væru slóðirnar sem ég fengi, og að kalla á stopSelf myndi taka viðmótið niður með sér. Þjónustan hagaði sér nákvæmlega eins og skjalfest er. Brotni hlutinn var hugmyndalíkan mitt.
Goðsögn 1: göngin standa þangað til þú stöðvar þau
Android heldur einu VPN-viðmóti í einu. Settu upp annað og kerfið setur það ekki í biðröð: það gerir þitt óvirkt og kallar á onRevoke() í þjónustunni þinni. Ef kóðinn þinn rekur allt niður aðeins við hnappapressu, skilur yfirtaka eftir lýsingu og lesþráð, og næsta ræsing erfir hvort tveggja.
VpnService-viðmiðin segja skýrt að prepare() skili null þegar forritið hefur þegar samþykki, og Intent þegar notandinn þarf enn að samþykkja. Það samþykki kemur aðeins ef þú sendir ætlunina í gegnum startActivityForResult(). Sleppaðu afhendingunni og establish() skilar null, sem er lesið sem hljóðlaust mistak, ekki vandamál með heimildir.
Always-on VPN bætir við eiganda sem þú stjórnar ekki. Kerfið getur sótt göngin aftur eftir ræsingu eða eftir hrun, og það ganga fram fyrir VPN-forrit sem notandinn ræsti handvirkt. Byggðu onRevoke() þannig að það loki sömu auðlindum og venjuleg slokknun þín, og meðhöndlaðu það sem aðalslokkningarleið frekar en jaðartilvik. Notendur skipta um VPN-forrit; kóðinn þinn verður að þola það.
Goðsögn 2: addRoute grípur nákvæmlega það sem þú listaðir
Slóðirnar ákvarða hvaða pakkar ná til lýsingarinnar þinnar, og umfangsvilla skapar það æðandi tilvik þar sem hluti umferðar fer í gegnum göngin og hluti ekki. addRoute("0.0.0.0", 0) tekur allt IPv4, sem þýðir að hver pakki kemur nú til þín og verður að senda hann áfram eða sleppa honum. /32 fyrir einn hýsil tekur næstum ekkert, og allt annað hagar sér eins og VPN-ið þitt hafi aldrei verið sett upp.
Fjölskyldurnar eru taldar sér. Slóð sem er aðeins IPv4 skilur IPv6 eftir á undirliggjandi netinu, svo hýsill með tvöfaldan staka getur enn leyst og tengst utan ganganana á meðan hann virðist fullkomlega tengdur inni í þeim.
DNS fylgir sömu rökfræði. Netþjónar sem bætt er við með addDnsServer() fara til forrita sem nota leysinn í göngunum, en forrit með eigin dulritaðan DNS-endapunkt eða Private DNS stillt á hýsilnafn hunsar þá algjörlega. Þegar nöfn mistakast fyrir eitt forrit og virka fyrir annað, athugaðu slóð leysisins áður en þú snertir eina einustu slóð.
Goðsögn 3: reglur eftir forritum eru rofi sem þú getur snúið í hvora áttina sem er
addDisallowedApplication() og addAllowedApplication() eru tveir hamir, ekki tveir síur. Byggirinn tekur eitt líkan fyrir hvert göng, þannig að forrit sem vill allt nema þrjá pakka notar bannlistann og lætur leyfða listann vera tóman. Þau tvö útiloka hvort annað, og fólk kemst að því á keyrslutíma eftir að stillingaskjárinn hefur þegar boðið báða rofana.
Sýnileiki pakka bítur líka. Á Android 11 og nýrri getur þú aðeins nefnt pakka sem þú sérð, svo útilokunarlisti byggður á fyrirspurn sem forritinu þínu er óheimilt að keyra mun hljóðlaust sleppa færslum. Berðu listann saman við það sem pakkastjórnandinn skilar í raun áður en þú treystir honum.
Vinnusnið skipta áhorfendum aftur. Göng sem ræst eru innan sniðsins ná yfir það snið og forrit þess, en persónulega hliðin heldur eigin tengingu. Það er umfangsákvörðun sem tekin er einu sinni, og hún á heima í viðmótinu, ekki í stuðningsmiða.
Goðsögn 4: stopSelf endar göngin
Nei. Viðmótið lifir í lýsingunni sem establish() skilar, og þjónustuhluturinn getur dáið á meðan lýsingin er áfram opin. Lokaðu ParcelFileDescriptor fyrst, slepptu tilvísuninni, sameinaðu eða truflaðu les- og skrifþræðina, og kallaðu svo á stopForeground(true) og stopSelf() í þeirri röð.
Gleymd lýsing er venjulega ástæðan fyrir því að þjónusta virðist lifa af eigin stöðvunarbeiðni, og hún útskýrir úrelta slóð sem lifir lengur en forritið sem bætti henni við.
Andstæða mistakið er jafn algengt: að loka lýsingunni á meðan lesþráður er mitt í lestri, og skilja svo þann þráð eftir að takast á við undantekningu sem enginn skrifaði meðferð fyrir. Haltu slokknunarröðinni á einum stað og láttu bæði aðgerð notandans og onRevoke() kalla þangað inn.
Hvað á að athuga þegar göngin virðast dauð
Verndaðu langlífar sambandsstikur með protect() áður en göngin rísa. Án þess er flutningur gangananna sjálfra beint aftur inn í göngin og tengingin stöðvast á þann hátt að hún lítur nákvæmlega út eins og netþjónsvilla. Prófaðu gegn vistfang sem er aðeins til bak við fjarnetið, ekki opinberri síðu sem svarar úr skyndiminni eða af undirliggjandi slóð.
Skráðu niðurstöðu establish(), slóðirnar, útilokuðu pakkana og ástæðu slokknunar. Þessar fjórar línur aðskilja samþykkisvandamál frá umfangsvandamáli og lífsferilsvandamáli án pakkaskoðunar.