Gesplete tonneling in 'n VpnService-program breek op 'n paar spesifieke plekke, en die herstel verskil vir elkeen. Die kliënt wys net die een bestemming wat faal, so die eerste werk is om uit te maak watter grens jy tref: die roetes wat die builder ontvang het, die proxy waarvoor jy nie kan authentiseer nie, die resolver wat jy net geadverteer het, of die programlys wat die platform per gebruiker toepas. Ek hou juis daarom 'n kontrole van vier stappe. Dit loop in die volgorde hieronder en stop by die eerste fout.

Bevestig wat die builder aan die platform oorhandig het

VpnService.Builder is 'n verklaringslys. establish() gee 'n ParcelFileDescriptor vir 'n virtuele koppelvlak terug, en die platform stuur net verkeer wat by die voorvoegsels van addAddress en addRoute pas na daardie descriptor; addDnsServer sê vir kliënte watter resolver om te vra. 'n Bestemming buite elke voorvoegsel wat jy bygevoeg het, bereik nooit jou program nie, maak nie saak wat die koppelvlak belowe nie. Daardie enkele feit verduidelik die meeste klagtes oor gebreekte gesplete tonneling voordat enige kode verander word.

Log die adres-, roete- en DNS-lyste wat jou builder saamgestel het, en vergelyk dit met die bestemmings wat faal. Een ontbrekende /32 vir 'n bestuurhost kom baie meer voor as 'n gebreekte tonnel. As die lys reg is, gaan voort; as dit verkeerd is, is die res van die kontrolelys vermorste moeite.

excludeRoute bestaan eers vanaf API 33

Bestemmingsgebaseerde uitsluiting is die versoek wat die meeste in 'n ondersteuningsdraad ontaard. builder.excludeRoute(IpPrefix) het in API 33 gekom; voor dit was die enigste ondersteunde benadering om roetes te voeg vir alles behalwe die uitgeslote voorvoegsel, wat beteken jy moet die komplementêre voorvoegsels self bereken. Die twee oproepe is nie spieëlbeelde nie: een trek van die koppelvlak se roetestel af, die ander bou die stel van nuuts af, en 'n ouer toestel sal 'n oproep wat dit nie ken nie gooi of stilweg ignoreer. Vertak op Build.VERSION.SDK_INT en toets albei paaie op werklike hardeware.

Wanneer jy komplemente bereken, let op voorvoegselbelyning. 'n /24-uitsluiting binne 'n /16-roete het die dekkende voorvoegsels nodig wat die oorblywende deel werklik beskryf, nie een misvormde /8 nie. Log die finale lys en verifieer dat die uitgeslote host steeds deur 'n nie-tonnelpad resolveer.

Proxy-aanmelding is nie uitdrukbaar nie

setHttpProxy(ProxyInfo) rig die koppelvlak na 'n HTTP- of SOCKS-proxy, en 'n PAC-URL kan per bestemming tussen hulle kies. Nie ProxyInfo nie en ook nie die PAC-formaat dra 'n gebruikersnaam en wagwoord nie, so 'n geauthentiseerde proxy val buite die platform-API. Programme wat een nodig het, bou gewoonlik 'n gebruikerspasie-stapel in, tun2socks of 'n soortgelyke enjin, en antwoord self die 407-uitdaging.

Daardie keuse het gevolge. 'n Gebruikerspasie-stapel sien net verkeer wat jy na hom roeteer, so dit moet binne dieselfde descriptor-grens leef, en dit erf dieselfde protect()-vereiste vir sy eie opstuur-sok. Los protect() uit en die tonnel vang sy eie transport, wat wys as 'n handdruk wat ná die eerste pakket vassteek. Toets teen 'n proxy wat aanmeldings eis, want 'n oop proxy slaag op die platformpad en bewys niks.

Programlyste en DNS is ook verklarings

Builder het beide addAllowedApplication en addDisallowedApplication, en hulle sluit mekaar uit: om albei te roep, gooi 'n fout. In elk geval word die lys per gebruiker by koppelvlakopstelling toegepas, so 'n werkprofiel-program word deur die werkprofiel se tonnel beheer eerder as joune. Wat geen API gee nie, is beheer oor 'n ander program se besluit: jy kan nie 'n pakket van buite in jou tonnel dwing nie, en jy kan nie 'n VPN wat reeds aktief is sluit of herkonfigureer nie.

DNS volg dieselfde patroon. addDnsServer adverteer 'n resolver-adres; dit laat jou program nie vrae antwoord nie. Wil jy name self resolveer, hardloop 'n resolver en roeteer sy adres in die tonnel in. Programme wat DoT of DoH na 'n vaste hostnaam gebruik, kan die adres wat jy geadverteer het omseil, so hanteer naamresolusie as beste poging tensy jy ook die navraagpad onderskep.

Manifes, altyd-aan en die vierstap-toets

Geskiktheid word in die manifes verklaar: BIND_VPN_SERVICE, die android.net.VpnService-intentfilter, en 'n voorgronddiens as die tonnel in die agtergrond moet oorleef. Altyd-aan VPN vereis boonop 'n skoon onRevoke, want die stelsel roep dit wanneer die gebruiker instellings verander of 'n ander program oorneem.

Voer die kontroles in volgorde uit en stop by die eerste fout. Eerstens, stort die adres-, roete- en DNS-lyste wat aan die builder gegee is. Tweedens, bevestig dat establish() 'n descriptor teruggegee het en dat die transportsok beskerm is. Derdens, vra een bestemming binne 'n ingeslote voorvoegsel en een binne 'n uitgeslote voorvoegsel. Vierdens, kyk watter resolver werklik geantwoord het deur 'n hostnaam te vra wat net jou resolver kan resolveer.

'n Voltooide handdruk bewys nie een van die latere stappe nie. Elke kontrole isoleer een laag, so 'n slaag by stap twee sê niks oor stap vier nie.

Die VpnService.Builder-verwysing lys die volle builder-oppervlak. Enigiets wat jy daarbenewens nodig het, is 'n ander API, 'n ander program of jou eie gebruikerspasie-stapel, en dit is 'n ontwerpbesluit eerder as 'n fout in gesplete tonneling.

Verwante artikels