Android VpnService-те бөлінген туннель: шынында нені маршруттауға болады
VpnService тек builder өз дескрипторына жіберген пакеттерді ғана өткізеді. Бөлінген туннельді кінәламас бұрын префикстерді, прокси аутентификациясын, DNS пен қолданба тізімдерін тексеріңіз.
VpnService қолданбасындағы бөлінген туннель бірнеше нақты жерде бұзылады, әрқайсысының жөндеуі бөлек. Клиент тек бір сәтсіз бағытты көрсетеді, сондықтан бірінші жұмыс қай шекараға соғылып тұрғаныңызды анықтау: builder алған маршруттар, аутентификациялай алмайтын прокси, тек жариялаған resolver немесе платформа әр пайдаланушыға қолданатын қолданба тізімі. Дәл сондықтан төрт қадамды тексеруді ұстаймын. Ол төмендегі тәртіппен жүреді және бірінші сәтсіздікте тоқтайды.
Builder платформаға нені бергенін растаңыз
VpnService.Builder — декларациялар тізімі. establish() виртуалды интерфейс үшін ParcelFileDescriptor қайтарады, ал платформа сол дескрипторға addAddress мен addRoute префикстеріне сәйкес келетін трафикті ғана жібереді; addDnsServer клиенттерге қай resolver-ден сұрауды айтады. Қосқан префикстеріңіздің барлығынан тыс бағыт интерфейс не уәде етсе де, қолданбаңызға ешқашан жетпейді. Осы бір факт кодты өзгертуге дейінгі бүлінген бөлінген туннель туралы хабарламалардың көбін түсіндіреді.
Builder жинаған мекенжай, маршрут және DNS тізімдерін журналға жазып, оларды сәтсіз бағыттармен салыстырыңыз. Басқару хосты үшін жетпейтін /32 бүлінген туннельден әлдеқайда жиі кездеседі. Тізім дұрыс болса, әрі қарай жүріңіз; қате болса, қалған тексеру тізімі бос әрекет.
excludeRoute тек API 33-тен бар
Бағытқа негізделген шығару — ең жиі қолдау тақырыбына айналатын сұраныс. builder.excludeRoute(IpPrefix) API 33-те келді; оған дейін жалғыз қолдау көрсетілетін жуықтау — шығарылған префикстен басқа барлығына маршрут қосу, яғни толықтырушы префикстерді өзіңіз есептеуіңіз керек. Екі шақыру айна бейнесі емес: біреуі интерфейстің маршрут жиынынан азайтады, екіншісі жиынды нөлден құрады, ал ескі құрылғы танымайтын шақыруды лақтырады немесе үнсіз елемейді. Build.VERSION.SDK_INT бойынша тармақталып, екі жолды да нақты жабдықта сынаңыз.
Толықтырғыштарды есептегенде префикс туралануына назар аударыңыз. /16 маршрут ішіндегі /24 шығару қалған бөлікті шынында сипаттайтын жапқыш префикстерді қажет етеді, бір бүлінген /8 емес. Соңғы тізімді журналға жазып, шығарылған хост әлі де туннельден тыс жолмен шешілетінін растаңыз.
Прокси тіркелгі деректерін өрнектеу мүмкін емес
setHttpProxy(ProxyInfo) интерфейсті HTTP немесе SOCKS проксиіне бағыттайды, ал PAC URL әр бағыт үшін олардың арасында таңдай алады. ProxyInfo да, PAC форматы да пайдаланушы аты мен құпиясөзді тасымайды, сондықтан аутентификация қажет ететін прокси платформа API-інен тыс қалады. Оны қажет ететін қолданбалар әдетте пайдаланушы кеңістігінің стегін, tun2socks немесе ұқсас қозғалтқышты кірістіріп, 407 шақыруына өздері жауап береді.
Бұл таңдаудың салдары бар. Пайдаланушы кеңістігінің стегі тек өзіне бағыттаған трафикті көреді, сондықтан ол сол дескриптор шекарасында өмір сүруі керек және өз uplink сокеті үшін сол protect() талабын мұра етеді. protect()-ті өткізіп жіберсеңіз, туннель өз транспортын ұстап алады, бұл бірінші пакеттен кейін тұрып қалатын қол алысу түрінде көрінеді. Тіркелгі деректерін талап ететін проксиге қарсы сынаңыз, өйткені ашық прокси платформа жолымен өтеді және ештеңені дәлелдемейді.
Қолданба тізімдері мен DNS те декларация
Builder-де addAllowedApplication да, addDisallowedApplication да бар, және олар бірін-бірі жоққа шығарады: екеуін шақырсаңыз, ерекше жағдай пайда болады. Қалай болғанда да тізім интерфейсті орнату кезінде әр пайдаланушыға қолданылады, сондықтан жұмыс профилінің қолданбасын сіздің туннеліңіз емес, жұмыс профилінің туннелі басқарады. Ешбір API бермейтіні — басқа қолданбаның шешіміне бақылау: пакетті сырттан туннеліңізге итере алмайсыз және әлдеқашан белсенді VPN-ді жаба немесе қайта конфигурациялай алмайсыз.
DNS сол үлгіні ұстанады. addDnsServer resolver мекенжайын жариялайды; ол қолданбаңызға сұраныстарға жауап беруге мүмкіндік бермейді. Атауларды өзіңіз шешкіңіз келсе, resolver іске қосып, оның мекенжайын туннельге бағыттаңыз. Тұрақты хост атына DoT немесе DoH қолданатын қолданбалар сіз жариялаған мекенжайды айналып өте алады, сондықтан сұраныс жолын да ұстамасаңыз, атауларды шешуді ең жақсы әрекет деп қабылдаңыз.
Manifest, always-on және төрт қадамды тест
Жарамдылық manifest-те жарияланады: BIND_VPN_SERVICE, android.net.VpnService intent сүзгісі және туннель фонда өмір сүруі керек болса, foreground қызметі. Always-on VPN қосымша таза onRevoke талап етеді, өйткені жүйе оны пайдаланушы параметрлерді өзгерткенде немесе басқа қолданба бақылауды алғанда шақырады.
Тексерулерді ретімен орындап, бірінші сәтсіздікте тоқтаңыз. Бірінші, builder-ге берілген мекенжай, маршрут және DNS тізімдерін шығарыңыз. Екінші, establish() дескриптор қайтарғанын және транспорт сокеті қорғалғанын растаңыз. Үшінші, қосылған префикс ішіндегі бір және шығарылған префикс ішіндегі бір бағытты сұраңыз. Төртінші, тек сіздің resolver-іңіз шеше алатын хост атын сұрап, қай resolver шынында жауап бергенін тексеріңіз.
Аяқталған қол алысу кейінгі қадамдардың ешқайсысын дәлелдемейді. Әр тексеру бір қабатты оқшаулайды, сондықтан екінші қадамдағы сәттілік төртінші туралы ештеңе айтпайды.
VpnService.Builder анықтамасы builder-дің бүкіл бетін тізімдейді. Одан тыс қажет нәрсенің бәрі — басқа API, басқа қолданба немесе өз пайдаланушы кеңістігіңіздің стегі, және бұл дизайн шешімі, бөлінген туннель ақауы емес.