Tunel zatitua Android VpnService-n: zer bideratu dezakezun benetan
VpnService-k builder-ak bere deskriptorera bidalitako paketeak soilik pasatzen ditu. Egiaztatu prefikoak, proxyaren autentifikazioa, DNSa eta aplikazioen zerrendak tunel zatitua erruduntzat jo aurretik.
VpnService aplikazio bateko tunel zatitua leku zehatz gutxitan hausten da, eta konponketa desberdina da bakoitzerako. Bezeroak huts egiten duen helmuga bakarra erakusten du, beraz lehen lana zein muga jotzen ari zaren argitzea da: builder-ak jaso zituen bideak, autentifikatu ezin duzun proxya, soilik iragarri zenuen resolverra edo plataformak erabiltzaileko aplikatzen duen aplikazio-zerrenda. Horregatik zehazki gordetzen dut lau urratseko egiaztapen bat. Beheko ordenan doa eta lehen hutsegitean gelditzen da.
Egiaztatu builder-ak plataformari zer eman zion
VpnService.Builder deklarazio-zerrenda bat da. establish()-ek ParcelFileDescriptor bat itzultzen du interfaze birtual baterako, eta plataformak deskriptore horretara addAddress eta addRoute prefiksoekin bat datozen trafiko bakarrik bidaltzen du; addDnsServer-ek bezeroei zein resolver galdetu esaten die. Gehitu dituzun prefiko guztietatik kanpoko helmuga ez da inoiz zure aplikaziora iristen, interfazeak zer agindu ere. Gertaera bakar horrek azaltzen ditu tunel zatitu hautsiaren inguruko txosten gehienak kodea aldatu aurretik.
Erregistratu zure builder-ak osatu zituen helbide, bide eta DNS zerrendak, eta alderatu huts egiten duten helmugekin. Kudeaketa-host baterako falta den /32 bat tunel hautsia baino askoz ohikoagoa da. Zerrenda zuzena bada, jarraitu; okerra bada, gainerako zerrenda ahalegin alferra da.
excludeRoute API 33tik aurrera soilik dago
Helmugan oinarritutako bazterketa laguntza-hari bihurtzen den eskaerarik ohikoena da. builder.excludeRoute(IpPrefix) API 33an iritsi zen; lehenago onartutako hurbilpen bakarra baztertutako prefiksoa ez den guztiarentzako bideak gehitzea da, hau da, prefikso osagarriak zeuk kalkulatu behar dituzu. Bi deiek ez dute ispilu-irudiak: batek interfazearen bide-multzoari kentzen dio, besteak multzoa hutsetik eraikitzen du, eta gailu zahar batek ezagutzen ez duen dei bat bota edo isilean baztertuko du. Adarkatu Build.VERSION.SDK_INT arabera eta probatu bi bideak hardware errealean.
Osagarriak kalkulatzean, begiratu prefiksoen lerrokatzea. /16 bide baten barruko /24 bazterketak gainerakoa benetan deskribatzen duten estaldura-prefiksoak behar ditu, /8 gaizki eratua ez. Erregistratu azken zerrenda eta egiaztatu baztertutako hostak tunelaz kanpoko bide batetik oraindik ebatzi egiten dela.
Proxyaren kredentzialak ezin dira adierazi
setHttpProxy(ProxyInfo)-k interfazea HTTP edo SOCKS proxy batera zuzentzen du, eta PAC URL batek bien artean aukera dezake helmugako. Proxylnfo-k ez eta PAC formatuak ez dute erabiltzaile-izena eta pasahitza eramaten, beraz autentifikatutako proxy bat plataformaren APItik kanpo geratzen da. Behar duen aplikazioak erabiltzaile-espazioko pila bat, tun2socks edo antzeko motor bat txertatzen du, eta 407 erronkari berak erantzuten dio.
Aukera horrek ondorioak ditu. Erabiltzaile-espazioko pilak berarengana bideratzen duzun trafiko bakarrik ikusten du, beraz deskriptorearen muga berean bizi behar du, eta protect()-en baldintza bera heredatzen du bere uplink socketarentzat. Utzi protect() alde batera eta tunelak bere garraioa harrapatzen du, lehen paketearen ondoren trabatzen den eskuko keinu gisa agertzen dena. Probatu kredentzialak eskatzen dituen proxy baten aurka, proxy ireki batek plataformaren bidean pasatzen baitu eta ez du ezer frogatzen.
Aplikazio-zerrendak eta DNS ere deklarazioak dira
Builder-ek addAllowedApplication eta addDisallowedApplication ditu, eta elkar baztertzen dute: biak deitzeak salbuespena botatzen du. Nolanahi ere, zerrenda erabiltzaileko aplikatzen da interfazea konfiguratzean, beraz lan-profil bateko aplikazioa lan-profilaren tunelak gobernatzen du, ez zureak. Inongo APIk ez dizu beste aplikazio baten erabakia kontrolatzeko aukerarik ematen: ezin duzu pakete bat zure tunelera kanpotik bultzatu, eta ezin duzu jadanik aktibo dagoen VPN bat itxi edo birkonfiguratu.
DNSak eredu bera jarraitzen du. addDnsServer-ek resolver helbide bat iragartzen du; ez dio zure aplikazioari kontsultei erantzuten uzten. Izenak zeuk ebatzi nahi badituzu, exekutatu resolver bat eta bideratu haren helbidea tunelera. Host-izen finko batera DoT edo DoH erabiltzen duten aplikazioek iragarri zenuen helbidea saihestu dezakete, beraz hartu izenen ebazpena ahalegin onena gisa, kontsultaren bidea ere atzematen ez baduzu.
Manifesta, always-on eta lau urratseko proba
Egokitasuna manifestuan deklaratzen da: BIND_VPN_SERVICE, android.net.VpnService intent-iragazkia eta foreground zerbitzua tunelak atzeko planoan iraun behar badu. Always-on VPNak gainera onRevoke garbia eskatzen du, sistemak erabiltzaileak ezarpenak aldatzen dituenean edo beste aplikazio batek kontrola hartzen duenean deitzen baitu.
Exekutatu egiaztapenak ordenan eta gelditu lehen hutsegitean. Lehenik, atera builder-ari emandako helbide, bide eta DNS zerrendak. Bigarrenik, egiaztatu establish()-ek deskriptore bat itzuli zuela eta garraio-socketa babestuta dagoela. Hirugarrenik, eskatu helmuga bat barne hartutako prefiko baten barruan eta beste bat baztertutako prefiko baten barruan. Laugarrenik, egiaztatu zein resolverrek erantzun zuen benetan, zure resolverrak soilik ebatzi dezakeen host-izen bat galdetuz.
Amaitutako eskuko keinuak ez du ondorengo urratsetako bat ere frogatzen. Egiaztapen bakoitzak geruza bat isolatzen du, beraz bigarren urratseko arrakastak ez du ezer esaten laugarrenari buruz.
VpnService.Builder erreferentziak builder-aren gainazal osoa zerrendatzen du. Horretaz harago behar duzun guztia beste API bat, beste aplikazio bat edo zure erabiltzaile-espazioko pila da, eta hori diseinu-erabakia da, ez tunel zatituaren akatsa.