Dalītais tunelējums VpnService lietotnē salūzt dažās konkrētās vietās, un katrai no tām labojums ir atšķirīgs. Klients parāda tikai vienu neizdevušos galamērķi, tāpēc pirmais darbs ir noskaidrot, kurā robežā jūs atduraties: builder saņemtie maršruti, proxy, kuru nevarat autentificēt, resolver, kuru tikai paziņojāt, vai lietotņu saraksts, ko platforma piemēro katram lietotājam. Tieši tāpēc man ir četru soļu pārbaude. Tā iet zemāk norādītajā secībā un apstājas pie pirmās kļūdas.

Pārliecinieties, ko builder nodeva platformai

VpnService.Builder ir deklarāciju saraksts. establish() atgriež ParcelFileDescriptor virtuālajai saskarnei, un platforma šajā deskriptorā sūta tikai to plūsmu, kas atbilst addAddress un addRoute prefiksiem; addDnsServer pasaka klientiem, kuru resolver jautāt. Galamērķis ārpus visiem jūsu pievienotajiem prefiksiem nekad nesasniedz jūsu lietotni, lai ko arī solītu saskarne. Šis viens fakts izskaidro lielāko daļu ziņojumu par salūzušu dalīto tunelējumu vēl pirms koda maiņas.

Ierakstiet žurnālā builder savāktos adrešu, maršrutu un DNS sarakstus, pēc tam salīdziniet tos ar neizdevušajiem galamērķiem. Trūkstošs /32 pārvaldības resursdatoram ir daudz biežāks nekā salūzis tunelis. Ja saraksts ir pareizs, ejiet tālāk; ja nepareizs, pārējais kontrolsaraksts ir veltīgs darbs.

excludeRoute pastāv tikai no API 33

Izslēgšana pēc galamērķa ir pieprasījums, kas visbiežāk pārvēršas atbalsta pavedienā. builder.excludeRoute(IpPrefix) parādījās API 33; pirms tam vienīgā atbalstītā tuvināšana ir maršrutu pievienošana visam, izņemot izslēgto prefiksu, kas nozīmē, ka papildprefiksi jāaprēķina pašiem. Abi izsaukumi nav spoguļattēli: viens atņem no saskarnes maršrutu kopas, otrs veido kopu no nulles, un vecāka ierīce izsauks izņēmumu vai klusējot ignorēs izsaukumu, ko nepazīst. Atzarojiet pēc Build.VERSION.SDK_INT un pārbaudiet abus ceļus reālā aparatūrā.

Aprēķinot papildinājumus, sekojiet prefiksu izlīdzinājumam. /24 izslēgšanai /16 maršrutā vajag pārklājošos prefiksus, kas tiešām apraksta atlikušo daļu, nevis vienu bojātu /8. Ierakstiet galīgo sarakstu un pārliecinieties, ka izslēgtais resursdators joprojām tiek atrisināts pa ceļu ārpus tuneļa.

Proxy akreditācijas datus nevar izteikt

setHttpProxy(ProxyInfo) novirza saskarni uz HTTP vai SOCKS proxy, un PAC URL var izvēlēties starp tiem katram galamērķim. Ne ProxyInfo, ne PAC formāts nepārnēsā lietotājvārdu un paroli, tāpēc proxy, kam vajadzīga autentifikācija, paliek ārpus platformas API. Lietotnes, kam tas nepieciešams, parasti iekļauj lietotāja telpas steku, tun2socks vai līdzīgu dzinēju un pašas atbild uz 407 izaicinājumu.

Šai izvēlei ir sekas. Lietotāja telpas steks redz tikai to plūsmu, ko tam novirzāt, tāpēc tam jādzīvo tajās pašās deskriptora robežās, un tas manto tās pašas protect() prasības savam uplink ligzdai. Izlaidiet protect() un tunelis pārtver savu transportu, kas izpaužas kā rokas sitiens, kas iestrēgst pēc pirmās paketes. Pārbaudiet pret proxy, kas pieprasa akreditācijas datus, jo atvērts proxy iziet platformas ceļā un neko nepierāda.

Lietotņu saraksti un DNS arī ir deklarācijas

Builder ir gan addAllowedApplication, gan addDisallowedApplication, un tie viens otru izslēdz: abu izsaukšana met izņēmumu. Jebkurā gadījumā saraksts tiek piemērots katram lietotājam, iestatot saskarni, tāpēc darba profila lietotni pārvalda darba profila tunelis, nevis jūsējais. Ko nedod neviena API, ir kontrole pār citas lietotnes lēmumu: jūs nevarat no ārpuses iebīdīt paketi savā tunelī un nevarat aizvērt vai pārkonfigurēt jau aktīvu VPN.

DNS seko tam pašam modelim. addDnsServer paziņo resolver adresi; tas neļauj jūsu lietotnei atbildēt uz vaicājumiem. Ja gribat paši atrisināt vārdus, palaidiet resolver un novirziet tā adresi tunelī. Lietotnes, kas izmanto DoT vai DoH uz fiksētu resursdatora nosaukumu, var apiet paziņoto adresi, tāpēc vārdu atrisināšanu uzskatiet par labāko pūliņu, ja vien nepārtverat arī vaicājuma ceļu.

Manifests, always-on un četru soļu tests

Atbilstība tiek deklarēta manifestā: BIND_VPN_SERVICE, android.net.VpnService intent filtrs un priekšplāna pakalpojums, ja tunelim jāizdzīvo fonā. Always-on VPN papildus prasa tīru onRevoke, jo sistēma to izsauc, kad lietotājs maina iestatījumus vai cita lietotne pārņem kontroli.

Veiciet pārbaudes secīgi un apstājieties pie pirmās kļūdas. Pirmkārt, izvadiet builder nodotos adrešu, maršrutu un DNS sarakstus. Otrkārt, pārliecinieties, ka establish() atgrieza deskriptoru un transporta ligzda ir aizsargāta. Treškārt, pieprasiet vienu galamērķi iekļautā prefiksā un vienu izslēgtā prefiksā. Ceturtkārt, pārbaudiet, kurš resolver tiešām atbildēja, jautājot resursdatora nosaukumu, ko var atrisināt tikai jūsu resolver.

Pabeigts rokas sitiens nepierāda nevienu no nākamajiem soļiem. Katra pārbaude izolē vienu slāni, tāpēc panākums otrajā solī neko neizsaka par ceturto.

VpnService.Builder uzziņa uzskaita visu builder virsmu. Viss, kas vajadzīgs ārpus tās, ir cita API, cita lietotne vai jūsu pašu lietotāja telpas steks, un tas ir dizaina lēmums, nevis dalītā tuneļa kļūda.

Saistītie raksti