Android колдонмолорунун көбү VPN аныктоо үчүн колдонгон текшерүү — бул интерфейс аты, жана ал эч качан VPN текшерүү болгон эмес. Ал иштеп чыгуучу күткөн сап менен кандайдыр бир интерфейс бар экенин билдирет, бул бир түзмөктө OpenVPN дегенди, экинчисинде такыр байланышы жок нерсени билдирет. ping — ушундай эле далил: ал бир максат жооп бергенин далилдейт, пакетти туннель ташыганын эмес. Платформа чындыгында сунуш кылганы — тармактардын жыйындысы жана алардын ар бири жарыялаган транспорттор, ал эми бул башка жообу бар башка суроо.

Уламыш: tun0 болсо, VPN күйүп турат

Android VPN колдонмолору — системага tun файл дескрипторун берген VpnService ишке ашыруулары. Интерфейс аты аны түзгөн тараптан келет: OpenVPN адатта tun0 түзөт, PPTP жана L2TP ppp0 түзөт, WireGuard интерфейсин туннелдин аты менен атайт, ал эми IPsec туннелинин такыр салттуу аты болбошу мүмкүн. Ошондуктан /proc/net/dev окуу же NetworkInterface объектилерин саноо — шарттуулукту издейт, фактыны эмес.

Катанын эки багыты тең тирүү. Түзмөктө колдонуучунун VPN'ине эч кандай тиешеси жок жергиликтүү туннель үчүн tun0 болушу мүмкүн, ал эми толук ден соолугу чың WireGuard туннели tun0 сабын гана билген текшерүү үчүн көрүнбөй калышы мүмкүн. Бир функциядагы жалган оң жана жалган терс жыйынтыктар аны диагностика катары жараксыз кылат, анткени «VPN табылган жок» деген колдоо билетине эч бир багытта ишенүүгө болбойт.

Жеткиликтүүлүк да тарыды. Жаңы Android чыгарылыштары кадимки колдонмонун /proc'тон эмнени окуй аларын чектейт, ошондуктан Android 8'де иштеген атка негизделген текшерүү кодду өзгөртпөстөн эле кийинки түзмөктө бош тизме кайтарышы мүмкүн. Текшерүү үнсүз ачык тарапка ишке ашпаса, колдонмо туннель жакшы иштеп жаткан аппаратта VPN жок деген тыянакка келет.

Уламыш: ийгиликтүү ping туннель трафикти ташып жатканын билдирет

Ички хостко ping ошол хостко маршрут бар болгон сайын ийгиликтүү болот. Бөлүнгөн туннелде хост Wi-Fi аркылуу жеткиликтүү болушу мүмкүн, ал эми туннель күйүп турат жана такыр башка нерсе кылып жатат. Ар бир колдонмого VPN'де ping жасаган колдонмо туннелден чыгарылышы мүмкүн, ошондуктан ICMP жаңыртыгы анын сыртына чыгып, кайра келет, бул текшерүү болжолдогондон тескерисин далилдейт.

ICMP жана TCP да өз-өзүнчө фильтрленет. Жаңыртуу сурамдарына жол берип, бирок кызматка керектүү TCP портун таштаган туннель ping сынагынан өтүп, колдонмодо ишке ашпайт, ал эми бул түзмөктүн касиети эмес, каршы тараптагы брандмауэр эрежеси. Ийгиликтүү ping'дин жалгыз ак ниет окулушу — бул максат ушул учурда ушул протоколго жооп берди.

Платформа чындыгында эмнени билдирет

API 21'ден баштап ConnectivityManager.getAllNetworks() система билген ар бир тармакты кайтарат, ал эми getNetworkCapabilities(network) ошол тармактын эмнени жарыялаганын билдирет. VPN тармагы TRANSPORT_VPN алып жүрөт. Бардык тармактарды айланып өтүү бир суроого жооп берет: бул түзмөктө азыр кандайдыр бир VPN күйүп турабы?

Экинчи, тарыраак суроо башка чакырууну талап кылат. getActiveNetwork() колдонмонун трафиги азыр колдоно турган тармакты кайтарат, ал эми ага ошол эле мүмкүнчүлүктү текшерүү мындай жооп берет: менин трафигим VPN аркылуу өтөбү? Экөө шайкеш келбеши мүмкүн, жана бул шайкешсиздик маалыматтуу. Күйүп турган, бирок азыркы эмес VPN колдонмо боюнча маршруттоого же бөлүнгөн туннелдин конфигурациясына көрсөтөт, жоголгон туннелге эмес.

Network active = cm.getActiveNetwork();
NetworkCapabilities caps = cm.getNetworkCapabilities(active);
boolean viaVpn = caps != null
    && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);

Эки чакырууну тең коргоңуз. Мүмкүнчүлүктөр тизмелөө менен суроо ортосунда жоголгон тармак үчүн null болушу мүмкүн, ал эми активдүү тармак өткөрүү учурунда null болушу мүмкүн. NET_CAPABILITY_NOT_VPN каршы багытта пайдалуу — тармактын VPN транспортунун желеги жок болгону эмес, анын такыр туннель эместигин ырастоо үчүн.

NetworkInfo API менен ошол эле уламыш болгон

NetworkInfo менен ConnectivityManager.TYPE_VPN — бул текшерүүнүн экинчи мууну, жана ал себепсиз эскирген эмес. Заманбап чыгарылыштарда туннель туташкан кезде VPN үчүн кайтарылган объект null болушу мүмкүн, ошондуктан null'ды «VPN жок» деп караган код жооп эң маанилүү болгон түзмөктөрдө үнсүз жалган терс жыйынтык билдирет.

Аны менен кошо жүргөн берүү да жакшыраак эмес. CONNECTIVITY_CHANGE'тин VPN өтүүлөрүн өткөрүп жиберүү боюнча документтелген тарыхы бар, анын ичинде ар бир тармактык өзгөрүүдө эмес, VPN туташканда же ажыраганда гана иштеген курулуштар да бар. Ага курулган угуучу кийинки толук кайра туташууга чейин платформанын көз карашынан алыстаган абал өзгөрмөсүн жаратат.

Сурамжылоонун ордуна кайтарым чакырууларга жооп бериңиз

TRANSPORT_VPN талап кылган жана NET_CAPABILITY_NOT_VPN'ди алып салган NetworkRequest каттаңыз, анан ошол сурам менен registerNetworkCallback чакырыңыз. Ошондо onAvailable жана onLost жарыялоо качан өзгөрөрүн айтып берет, жана бул сизди чындап кызыктырган окуя. Компонент токтогондо кайтарым чакыруунун каттоосун жокко чыгарыңыз, болбосо колдонмо өлүк экранга шилтеме кармап, кайтарым чакыруу уланат.

NetworkRequest req = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
    .build();
cm.registerNetworkCallback(req, callback);

Бул ACCESS_NETWORK_STATE талап кылат, ал кадимки уруксат: root жок, колдонуучунун макулдук диалогу жок, VPN уруксаты жок. Таймер менен сурамжылоо — адамдар кайрылган альтернатива, ал батареяны күйгүзөт жана интервалдан кыска өтүүнү өткөрүп жиберет, ал эми бул колдонуучу билдирген так ошол өтүү.

Жооп дагы эмнени айта албайт

Бул API'лердин эч бири туннелдин ден соолугун, кайсы серверде бүтөрүн же белгилүү бир колдонмонун трафиги анын ичинде экенин билдирбейт. VPN тармагы пайдалуу маршруттарсыз болушу мүмкүн, ал эми ар бир колдонмого туннель суроо берген колдонмону чыгарып салышы мүмкүн.

Ошондуктан текшерүү көргөнүн жазыңыз, болгону логикалык маанини эмес. Тармак идентификаторун, жарыяланган транспортторду жана ошол тармактын активдүү болгонун журналга жазыңыз. «VPN табылган жок» деген отчет жараксыз, ал эми тармак TRANSPORT_VPN жарыялады, бирок getActiveNetwork() Wi-Fi кайтарды деген отчет түздөн-түз маршруттоого же чыгарып салуу тизмесине көрсөтөт, жана бул бирөө иштей ала турган оңдоо.

Тектеш макалалар