هغه ازموینه چې ډیری Android اپلیکیشنونه د VPN د کشف لپاره کاروي د انټرفیس نوم دی، او دا هیڅکله د VPN ازموینه نه وه. دا راپور ورکوي چې د پراختیاکوونکي د تمې وړ تار سره یو څه انټرفیس شته، چې په یو وسیله کې OpenVPN معنی لري او په بل کې بشپړ بې اړیکه شی. ping هم همدغه ډول شاهد دی: دا ثابتوي چې یو هدف ځواب ورکړ، نه دا چې ټنل کڅوړه انتقال کړه. هغه څه چې پلیټفارم واقعاً ښکاره کوي د شبکو یوه ټولګه او هغه ټرانسپورټونه دي چې هر یو یې اعلانوي، او دا بل ځواب لرونکې بله پوښتنه ده.

افسانه: که tun0 شته، VPN فعال دی

د Android VPN اپلیکیشنونه د VpnService پلي کول دي چې سیسټم ته د tun فایل ډیسکریپټر ورکوي. د انټرفیس نوم له هغه چا څخه راځي چې جوړ کړی یې دی: OpenVPN معمولاً tun0 جوړوي، PPTP او L2TP ppp0 جوړوي، WireGuard خپل انټرفیس د ټنل په نوم نوموي، او IPsec ټنل ممکن هیڅ دودیز نوم ونه ښیي. نو له همدې امله د /proc/net/dev لوستل یا د NetworkInterface شیانو شمېرل د حقیقت نه، د کنوانسیون پلټنه کوي.

د تېروتنې دواړه لوري ژوندي دي. وسیله کېدای شي د یوې محلي ټنل لپاره tun0 ولري چې د کاروونکي VPN سره هیڅ تړاو نه لري، او یو بشپړ روغ 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 سره هماغه افسانه وه

ConnectivityManager.TYPE_VPN د NetworkInfo سره د دې ازموینې دوهم نسل دی، او په یوه دلیل زوړ شوی. په عصري نسخو کې د VPN لپاره بیرته راګرځېدلی شی کېدای شي null وي پداسې حال کې چې ټنل نښلول شوی، نو هغه کوډ چې null «VPN نشته» ګڼي په خاموشۍ کې په هغو وسیلو کې جعلي منفي راپور ورکوي چې ځواب یې ترټولو مهم دی.

هغه خپرونه چې معمولاً ورسره وي هم ښه نه ده. CONNECTIVITY_CHANGE د VPN د تېرېدو د له لاسه ورکولو مستنده تاریخ لري، په شمول هغه جوړښتونه چې یوازې هغه وخت چالانېدل چې VPN ونښلول شو یا پرې شو، نه په هر شبکه بدلون. پر هغې جوړ شوی اورېدونکی داسې حالت متغیر تولیدوي چې تر بلې بشپړې بیا نښلونې پورې د پلیټفارم له نظره لرې ځي.

د پوښتنې پر ځای د کال بیکونو ته ځواب ووایاست

داسې NetworkRequest ثبت کړئ چې TRANSPORT_VPN غواړي او NET_CAPABILITY_NOT_VPN لره کوي، بیا د هغې غوښتنې سره 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 بیرته راوړ، مستقیم روټینګ یا د ایستلو لیست ته اشاره کوي، او دا هغه سمون دی چې څوک پرې کار کولای شي.

اړوندې مقالې