Pam nad yw eich twnnel Android VpnService yn stopio llwybro traffig
Pedwar camgred am VpnService sy'n torri mewn cynhyrchu: un twnnel ar y tro, cwmpas llwybrau, rhestrau fesul ap a threfn cau, gyda gwiriad ar gyfer pob un.
Fe wnaeth pedwar rhagdybiaeth am Android VpnService gostio'r rhan fwyaf o wythnos i mi unwaith, ac nid oedd yr un ohonynt ynghylch y protocol weiren. Roedd yr ap yn dweud ei fod wedi cysylltu, roedd yr eicon allwedd yn eistedd yn y bar statws, ac roedd y traffig yn dal i fynd allan dros y llwybr arferol. Roeddwn i'n dal i dybio mai fy nhwnnel i oedd o nes i mi ei stopio, mai'r llwybrau a ychwanegais oedd y llwybrau a gefais, ac y byddai galw stopSelf yn cymryd y rhyngwyneb i lawr gyda fe. Roedd y gwasanaeth yn ymddwyn yn union fel y mae wedi'i ddogfennu. Fy model meddwl i oedd y rhan wedi torri.
Chwedl 1: mae'r twnnel yn aros i fyny nes i chi ei stopio
Mae Android yn dal un rhyngwyneb VPN ar y tro. Gosodwch un ail a does dim rhaid i'r platfform ei roi yn y ciw: mae'n dadactifadu eich un chi ac yn galw onRevoke() ar eich gwasanaeth. Os mai dim ond ar wasgiad botwm y mae eich côd yn chwalu popeth, mae cymryd drosodd yn gadael disgrifydd a llinyn darllen ar ôl, ac mae'r cychwyn nesaf yn etifeddu'r ddau.
Mae cyfeirlyfr VpnService yn dweud yn glir fod prepare() yn dychwelyd null pan fod gan yr ap ganiatâd yn barod, ac Intent pan fod rhaid i'r defnyddiwr ei gymeradwyo o hyd. Dim ond pan fyddwch yn danfon y bwriad trwy startActivityForResult() y daw'r cymeradwyaeth honno. Hepgorwch y danfoniad ac mae establish() yn dychwelyd null, sydd yn darllen fel methiant distaw yn hytrach na phroblem caniatâd.
Mae Always-on VPN yn ychwanegu perchennog nad ydych yn ei reoli. Gall y system ddod â'r twnnel yn ôl ar ôl cychwyn neu ar ôl chwalfa, ac mae'n rhagfynd â ap VPN a gychwynnwyd â llaw gan y defnyddiwr. Adeiladwch onRevoke() fel ei fod yn cau'r un adnoddau â'ch cau arferol, a'i drin fel prif lwybr stopio yn hytrach na chornel achos. Mae defnyddwyr yn newid apiau VPN; rhaid i'ch côd oroesi hynny.
Chwedl 2: mae addRoute yn dal yn union yr hyn a restrwyd gennych
Mae'r llwybrau'n penderfynu pa becynnau sy'n cyrraedd eich disgrifydd, ac mae gwall cwmpas yn cynhyrchu'r achos gwyllt lle mae peth traffig yn mynd trwy'r twnnel a pheth ddim. Mae addRoute("0.0.0.0", 0) yn cymryd yr IPv4 i gyd, sy'n golygu bod pob pecyn bellach yn cyrraedd atoch ac yn rhaid ei anfon ymlaen neu ei ollwng. Nid yw /32 ar gyfer un gwesteiwr yn cymryd fawr ddim, ac mae popeth arall yn ymddwyn fel pe na bai eich VPN erioed wedi'i osod.
Mae teuluoedd yn cael eu cyfrif ar wahân. Mae llwybr IPv4 yn unig yn gadael IPv6 ar y rhwydwaith sylfaenol, felly gall gwesteiwr deu-stac o hyd ddatrys a chysylltu y tu allan i'r twnnel tra'n edrych yn berffaith gysylltiedig y tu mewn iddo.
Mae DNS yn dilyn yr un rhesymeg. Mae gweinyddwyr a ychwanegwyd â addDnsServer() yn mynd i apiau sy'n defnyddio datryswr y twnnel, tra bod ap sydd â'i bwynt diwedd DNS amgryptiedig ei hun neu Private DNS wedi'i osod ar enw gwesteiwr yn eu hanwybyddu'n llwyr. Pan fydd enwau'n methu i un ap ac yn gweithio i un arall, gwiriwch lwybr y datryswr cyn i chi gyffwrdd ag un llwybr.
Chwedl 3: mae rheolau fesul ap yn switsh y gallwch ei droi y naill ffordd neu'r llall
Mae addDisallowedApplication() a addAllowedApplication() yn ddau fodd, nid yn ddau hidlydd. Mae'r adeiladwr yn derbyn un model fesul twnnel, felly mae ap sydd eisiau popeth ac eithrio tri phecyn yn defnyddio'r rhestr waharddedig ac yn gadael y rhestr a ganiateir yn wag. Mae'r ddau'n cau ei gilydd allan, ac mae pobl yn darganfod hyn yn ystod rhedeg ar ôl i'r sgrin gosodiadau gynnig y ddau dogl eisoes.
Mae gwelededd pecynnau yn brathu hefyd. Ar Android 11 ac yn ddiweddarach ni allwch enwi ond pecynnau y gallwch eu gweld, felly bydd rhestr eithrio a adeiladwyd o ymholiad nad oes gan eich ap hawl i'w redeg yn colli cofnodion yn dawel. Cymharwch y rhestr â'r hyn y mae'r rheolwr pecynnau yn ei ddychwelyd mewn gwirionedd cyn ymddiried ynddi.
Mae proffiliau gwaith yn rhannu'r gynulleidfa eto. Mae twnnel a gychwynnwyd o fewn y proffil yn cwmpasu'r proffil hwnnw a'i apiau, tra bod yr ochr bersonol yn cadw ei chysylltedd ei hun. Penderfyniad cwmpas a wneir unwaith yw hwnnw, ac mae'n perthyn i'r rhyngwyneb yn hytrach nag i docyn cymorth.
Chwedl 4: mae stopSelf yn gorffen y twnnel
Nac ydy. Mae'r rhyngwyneb yn byw yn y disgrifydd a ddychwelwyd gan establish(), a gall gwrthrych y gwasanaeth farw tra bod y disgrifydd hwnnw'n parhau ar agor. Caewch y ParcelFileDescriptor yn gyntaf, gollyngwch y cyfeiriad, ymunwch â'r llinynnau darllen ac ysgrifennu neu torrwch ar eu traws, yna galwch stopForeground(true) a stopSelf() yn y drefn honno.
Disgrifydd wedi'i anghofio yw'r rheswm arferol dros ymddangos bod gwasanaeth yn goroesi ei gais stopio ei hun, ac mae'n esbonio llwybr hen ffasiwn sy'n byw yn hirach na'r ap a'i hychwanegodd.
Mae'r camgymeriad gwrthdro yr un mor gyffredin: cau'r disgrifydd tra bod llinyn darllen yng nghanol darllen, ac yna gadael y llinyn hwnnw i drin eithriad na ysgrifennodd neb ei driniaeth. Cadwch y dilyniant cau mewn un man a gadewch i weithred y defnyddiwr a onRevoke() alw i mewn iddo.
Beth i'w wirio pan fydd y twnnel yn edrych yn farw
Diogelwch socedi hirhoedlog â protect() cyn i'r twnnel godi. Heb hynny, mae cludiant y twnnel ei hun yn cael ei lwybro'n ôl i'r twnnel ac mae'r cysylltiad yn sownd mewn ffordd sy'n edrych yn union fel nam gweinydd. Profwch yn erbyn cyfeiriad sy'n bodoli'n unig y tu ôl i'r rhwydwaith anghysbell, nid safle cyhoeddus sy'n ateb o'r storfa neu o'r llwybr sylfaenol.
Cofnodwch ganlyniad establish(), y llwybrau, y pecynnau a eithriwyd a'r rheswm dros gau. Mae'r pedair llinell hynny'n gwahanu problem caniatâd oddi wrth broblem cwmpas ac oddi wrth broblem cylch bywyd heb ddal pecyn.