Жоқ, VpnService қолданбасы телефонның VPN-ін қоса алмайды
Қолданба бір туннельге және оның өмірлік цикліне ие, телефонның VPN қосқышына емес. Келісімді кері қайтаруға болады, бір уақытта тек бір VPN жұмыс істейді, ал пакеттерді өзіңіз талдауыңыз керек.
Қате болжам — VpnService қолданбасы жүйелік қосқышты аударып, содан кейін телефон қорғалған деп санау. Іс жүзінде болатыны тар: қолданба келісім сұрайды, интерфейс құрады, файл дескрипторы арқылы пакеттерді оқып жазады және тоқтағанда интерфейсті қайтарады. Бір уақытта осындай бір ғана туннель тірі бола алады, ал жүйе оны сұрамай-ақ алып қоя алады. Адамдар протоколға таңатын шатастыратын мінез-құлықтың көбі осы меншік моделінен шығады.
Өмірлік циклдің әрбір ауысуын шеткі жағдай емес, дизайнның бөлігі ретінде қарастырыңыз.
Аңыз: қолданба телефонның VPN-ін қосады
Ағын VpnService.prepare()-ден басталады, ол пайдаланушы қабылдауға тиіс Intent қайтарады, және establish()-мен жалғасады, ол кейін қолданба бақыламайтын себептермен әлі де сәтсіз аяқталуы мүмкін. Екінші туннельді орнату бірінші интерфейсті өшіреді және жүйелік хабарламаны алмастырады. Осы реттіліктің ешбір жерінде қолданба бүкіл құрылғының қосқышына ие емес; ол өзіне берілген дескрипторға және оған қонатын пакеттерге ие. Тіпті тұрақты хабарлама да қолданбаның дизайнына емес, жүйеге тиесілі.
Интерфейс тартып алынбайды, беріледі, сондықтан басқа клиент орынды кез келген уақытта ала алады. Қолданба мұны қайтару мәні арқылы емес, кері шақыру арқылы біледі.
Қолданбаны мәжбүрлеп тоқтату хабарлама панелінде дәл сол себептен көрінеді: жүйе не бергенін хабарлайды, қолданба нені көрсетуді таңдағанын емес.
Аңыз: келісім бір рет беріледі
Жүйе туннельді басқа клиентке тапсырғанда, базалық класс onBind()-ден қайтаратын binder-ге кері қайтару транзакциясын жібереді. Сол binder-ді өзінікімен алмастыратын қолданба кері қайтару транзакциясын өзі жіберуі керек, әйтпесе VpnService.onRevoke() ешқашан іске қосылмайды және қызмет енді жоқ дескрипторға жаза береді. Келісімді пайдаланушы да кері қайтара алады, ал жүйе қайта жүктеу немесе үнемі қосылып тұратын қайта қосылу кезінде қызметті тоқтата алады.
Онымен айналысу — журнал жолы емес, нақты жұмыс: дескрипторды оқуды тоқтатыңыз, оны жабыңыз, қосылған жалаушасын тазалаңыз және пайдаланушыға қандай күйде екенін айтыңыз. Содан кейін қолданба қайта орнатуы, қайта сұрауы немесе күтуі керек пе, соны шешіңіз, өйткені үнемі қосылып тұратын конфигурацияда жүйе қызметті өзі қайтаруы мүмкін.
Кері қайтаруды күй емес, ерекшелік деп санайтын қолданба қосылғанын хабарлайды, ал оның жазған әрбір пакеті тасталады, бұл құпиялылық құралы үшін мүмкін болатын ең нашар ақау режимі.
Аңыз: интерфейс трафикті сіз үшін сүзеді
Келген нәрсе — шикі IP. Ұстау немесе сүзу IP, TCP, UDP және IPv6 тақырыптарын талдауды, ағындарды бақылауды және жауаптарды дескрипторға қайта жазуды білдіреді, бұл ұстаушы қолданбаны жүйелік құрал емес, шағын желілік стекке айналдырады. protect() қолданбаның өз транспорттық сокеті өзін ұстамай, өз туннелін айналып өтуі үшін бар және туннель көтерілгеннен кейін жасалған әрбір сокетте тексеруге тұрарлық логикалық мән қайтарады.
Құрастырушының рұқсат етілген және тыйым салынған қолданбалар тізімдері кімнің трафигі интерфейске кіретінін анықтайды. Олар интерфейс тасымалдайтын IP пакеттерінен тыс пайдалы жүктемеге қол жеткізбейді, және ешбір API басқа клиенттің туннелін ашпайды немесе жүйенің VPN профильдерін тізімдейді. Желі мүмкіндіктері желінің VPN транспорты екенін айта алады, бірақ туннель кімдікі екенін айта алмайды.
Сондықтан басқа қолданбалар туралы күй сұрақтарына қайшы жауаптар келеді: ақпарат жай ғана сіздің процесіңізге ашылмаған.
Өмірлік цикл шын мәнінде нені талап етеді
Өзіңіз бақылайтын күйлерді қадағалаңыз: дайындалған, орнатылған, кері қайтарылған, тоқтатылған. Қайта қосылу бұзу, содан кейін орнату болуы керек, дескриптор мен транспорттық сокеттің бір ғана иесімен, өйткені орнатуға жарысатын екі компонент жалғыз бос орын үшін таласады. Заманауи Android-те фондық іске қосулар шектелген, сондықтан жүктелу кезіндегі таратылым кепілдік емес; API деңгейі рұқсат ететін жерде хабарламасы бар алдыңғы план қызметін пайдаланыңыз.
Тек соңғы күйді емес, ауысуды журналға жазыңыз, және әрбір жолды тексеруге болатындай күй машинасын шағын ұстаңыз. Сынақта жете алмайтын күй — журналсыз далада кездесетін күй.
Өмірлік циклді құрылғыда сынаңыз
Эмуляторлар байланысты жалғандай алады, бірақ келісім мен кері қайтару жолын сенімді түрде емес, сондықтан бұларды орынды ұрлау үшін екінші VPN клиенті орнатылған нақты құрылғыда іске қосыңыз.
adb shell dumpsys connectivity | grep -i -A3 vpn
adb shell dumpsys activity services | grep -i -A2 vpnservice
adb logcat -s VpnService:V AndroidRuntime:E
adb shell am force-stop com.example.vpnapp
Туннельді іске қосыңыз, хабарлама мен интерфейсті растаңыз, содан кейін басқа клиентті қосып, кері қайтару кері шақыруының орындалатынын және күйдің тазаланатынын бақылаңыз. Қолданбаны мәжбүрлеп тоқтатып, әлі де тірі дескриптор туралы хабарлайтын нәрсе бар-жоғын тексеріңіз.
Үнемі қосылып тұратын қайта жүктеуден кейін реттілікті қайталаңыз, өйткені бұл жол пайдаланушы бастаған қосылудан өзгеше. Сіз жасыл белгіні емес, қолданбаның енді өзіне тиесілі емес дескрипторды пайдалануды тоқтатқанына дәлел іздейсіз.