Android VpnService рұқсат тізімі: рұқсат етілген беттер неге әлі де қатып қалады
Сіздің рұқсат тізіміңіз, бәлкім, дұрыс. Беттер DNS жауабы, маршрут кестесі, шешуші сокеті немесе MTU салдарынан қатып қалады. Тексеру реті осы.
Сіз доменді рұқсат тізіміне қостыңыз, сұраныс қолданбаңызға жетеді, салыстырғыш рұқсат етілді деп қайтарады, бірақ бет ешқашан жүктелмейді. Осы сәтте көпшілік салыстырғышты қайта жазып, қалыптауыш таңбалармен салыстыру қосуды бастайды. Менің тәжірибемде салыстырғыш әдетте дұрыс, ал ақау бір қабат төменде жатыр: сіз жасаған DNS жауабында, сіз орнатқан маршрутта немесе сұранысты жіберу үшін қолданған сокетте. Тізім — оңай бөлігі; пакет жолы — рұқсат тізімдері сынатын жер.
Салыстырғыш сирек кінәлі
Ең алдымен блокталғанды бүлінгеннен ажырату керек. Блокталған ат тез және көрінетін түрде сәтсіз болуы керек, өйткені браузер ат жоқ деген жауап алып, тоқтайды. Бүлінген ат қатып қалады, IPv6 арқылы қайталап көреді, басқа тасымалға ауысады және сізді айналмалы индикатормен қалдырады. Егер айналмалы индикатор көрсеңіз, рұқсат тізіміңіз клиент істей алмайтын нәрсемен жауап береді.
Бос A жазбасы — классикалық қате. Нөл жауаппен NOERROR қайтару жарамды жауап сияқты көрінеді, сондықтан stub шешуші оны қабылдайды, браузер қайталайды, AAAA тексереді, басқа шешушіні тексереді және әлдеқайда кеш бас тартады. 3 жауап коды, яғни NXDOMAIN, сұрақ бөлімін қайталап және транзакция идентификаторын көшіріп берілсе, әңгімені бірден аяқтайды. Оны әдейі қабылдамайтын әр ат үшін қолданыңыз.
IPv6 та әдепкі мәннің орнына дәл осы шешімге лайық. Егер A үшін NXDOMAIN жауап беріп, AAAA өткізсеңіз, клиент блокталған атқа IPv6 арқылы жете алады және сүзгі ағып кетеді. Кейбір іске асырулар блокталған AAAA сұраныстарына loopback мекенжайымен жауап береді, сонда байланыс балама жолға ауысудың орнына бірден сәтсіз болады. Бір саясат таңдап, оны екі жазба түріне де қолданыңыз және екеуін де журналға жазыңыз.
Барлығын ұстайтын маршрут бәріне ие болады
Тек DNS-ке негізделген құрылым ешқашан addRoute("0.0.0.0", 0) қоспайды, сондықтан TUN интерфейсіне тек сұраныстар кіреді, ал қалғанының бәрі астыңғы желіні пайдалана береді. Бұл қауіпсіз пішін және кейбір рұқсат тізімдерінің Wi-Fi-да жұмыс істеп, ұялы желіде неге сәтсіз болатынын да түсіндіреді.
Әдепкі маршрут пайда болған сәтте әр ағын сіздікі. Интерфейске келіп, не жіберілмейтін, не жауап алмайтын TCP пакеті клиенттің уақыты бітпейінше кезекте отырады және журналға жазатын қате жоқ, өйткені ештеңе қателескен жоқ. Біреудің түстен кейінгі уақытын шын мәнінде 443 порты үшін жетпейтін жіберуші болып шыққан бүлінген рұқсат тізіміне жұмсағанын көрдім. Тастауға шешім қабылдаған әр пакеттің протоколы мен межелі орнын журналға жазыңыз.
Шешуші сокеті туннельден шығуы керек
Жіберу — келесі тұзақ орны. Оператор шешушілері жиі туннель жете алмайтын жеке мекенжайда тұрады, сондықтан жіберген сұраныс ешқайда кетпейді және қолданба оқу уақытының біткенін хабарлайды. Мақұлданған сұраныстарды жетуге болатынын білетін шешушіге жіберіңіз және сол сокетті алдымен VpnService.protect()-ге беріңіз. Қорғалмаған сокет сұранысты өз туннеліңізге қайтарады, онда ол қайтадан қолданбаға жетеді және уақыт шегі іске қосылғанша айналады.
Ақау желінің үзілуіне ұқсайды, сондықтан қате есептерінде сонша ұзақ өмір сүреді. Жіберілген сұраныстар мен алынған жауаптар үшін есептегіштер ұстаңыз: бірінші сан өсіп, екіншісі нөлде қалса, сіз сокетке қарап отырсыз, тізімге емес.
Өлшем мен бақылау сомалары хабарсыз сәтсіз болады
Үнсіз тастаулар өлшемнен де келеді. Үлкен жауап жиыны бар DNS жауабы немесе мол опциялармен TCP қол алысу сіз ешқашан анық орнатпаған жол MTU-сынан асып кетуі мүмкін; фрагмент жоғарыда жоғалады және клиент не кішірек қайталайды, не әрекеттен бас тартады. Интерфейс MTU-сын 1280-ге қою ұялы жолдардың көбіне төтеп беретін консервативті таңдау, ал ешкім өлшемеген әдепкі мәнді мұралаудан анық болған артық.
Пакеттерді өзіңіз құрастырсаңыз, бақылау сомасы — екінші үнсіз қаскөй. UDP ұзындығын немесе протокол өрісін қалдыратын жалған тақырып бойынша есептелген UDP бақылау сомасы сіз жақта дұрыс көрінетін, ал қабылдаушы ізсіз лақтыратын пакет береді. Жалған тақырыбыңызды спецификациямен өріс-өріс салыстырыңыз және жөндеу кезінде бір белгілі ағын үшін есептелген бақылау сомасын басып шығарыңыз.
VpnService сіз үшін не істемейді
Оның айналасында жобалаудан бұрын екі шекараны білген жөн. Ешбір қарапайым қолданба Wi-Fi-дан тыс жүйелік прокси немесе PAC файлын орната алмайды және бұл бөлік өзгерген жоқ. Қолданба бойынша жол өзгерді: API 29-ға дейін VpnService.Builder проксиді мүлдем алып жүре алмады, ал API 29-дан бастап setHttpProxy(ProxyInfo.buildPacProxy(uri)) платформаға VPN желісі үшін бағалайтын PAC скриптін береді. Ескі API-лерді нысанағанда немесе PAC үлгісі ережені өрнектей алмағанда ережелерді өз кодыңызда бағалаңыз. UDP де тегін емес: браузерлер SOCKS прокси арқылы тек TCP жібереді, ал SOCKS5 клиенттерінің көбі UDP ASSOCIATE-ті ешқашан іске асырмайды, сондықтан проксиге негізделген құрылым TCP сау көрінгенде UDP-ні тастайды немесе ағызады.
Осы екінші шекара UDP-ге негізделген протоколдың қарапайым желіде жұмыс істеп, VPN қосылған сәтте сәтсіз болуының себебі. Егер туннель UDP тасымалдауы керек болса, жіберуші ол үшін жіберу жолын іске асыруы керек, тек басқа сокет түрімен TCP жолын ғана емес.
Осы ретпен тексеріңіз
Тізімді ретімен орындап, сәтсіз болған бірінші кезеңде тоқтаңыз, өйткені алдыңғысы ұсталмайынша келесі тексерудің бәрі шу.
- Орнатылған маршруттарды тізімдеп, DNS емес пакеттердің TUN интерфейсіне мүлдем кіретінін растаңыз.
- Бір блокталған және бір мақұлданған ат үшін сұраныс атын, шешімді және жауап кодын журналға жазыңыз.
- Шешуші сокетінің қорғалғанын және таңдалған шешушінің туннель ішінен жауап беретінін растаңыз.
- Интерфейс MTU-сын және қолмен құрастырылған бір жауаптың бақылау сомасын растаңыз.
- Сол бетті Wi-Fi-да және ұялы желіде қайталаңыз, өйткені оператор шешушілері мен жол MTU-сы өзгеше.
Бесеуі де ұсталып, бет әлі қатып тұрса, келесі күдікті — жіберушінің өзі: ұсталған сұранысты ұсталған жауаппен салыстырып, жетіспейтін байт санын немесе жартылай жабық сокетті іздеңіз. VpnService.Builder анықтамасы маршрут, DNS және MTU шарттарын қамтиды, ал protect() — builder опциясы емес, бөлек VpnService шақыруы; қосылған интерфейс тек бірінші шарттың орындалғанын білдіреді.