Ìṣàyẹ̀wò tí ọ̀pọ̀lọpọ̀ àwọn app Android ń lò láti ṣàwárí VPN ni orúkọ interface, kò sì tilẹ̀ jẹ́ ìṣàyẹ̀wò VPN rí. Ó ń ròyìn pé interface kan wà pẹ̀lú okùn tí olùdàgbàsókè retí, èyí tí ó túmọ̀ sí OpenVPN lórí ẹ̀rọ kan àti nǹkan tí kò ní í ṣe lórí ẹ̀rọ mìíràn. ping jẹ́ irú ẹ̀rí kan náà: ó fi hàn pé ibi-àfojúsùn kan dáhùn, kì í ṣe pé ọ̀nà-abẹ́ gbé pákẹ́ẹ̀tì náà. Ohun tí pẹlẹ́fọ́ọ̀mù ń fi hàn ní ti gidi ni àkójọpọ̀ nẹ́tíwọ́kì àti àwọn ìrìnàjò tí ọ̀kọ̀ọ̀kan wọn ń kéde, ìyẹn sì jẹ́ ìbéèrè mìíràn pẹ̀lú ìdáhùn mìíràn.

Àròsọ: bí tun0 bá wà, VPN ń ṣiṣẹ́

Àwọn app VPN Android jẹ́ ìmúṣẹ VpnService tí wọ́n ń fi descriptor fáìlì tun fún ẹ̀rọ náà. Orúkọ interface wá láti ọ̀dọ̀ ẹni tí ó dá a: OpenVPN máa ń ṣe tun0, PPTP àti L2TP ń ṣe ppp0, WireGuard ń pe interface rẹ̀ ní orúkọ ọ̀nà-abẹ́, àti ọ̀nà-abẹ́ IPsec lè má fi orúkọ ìbílẹ̀ kankan hàn rárá. Nítorí náà kíkà /proc/net/dev tàbí kíkà àwọn ohun NetworkInterface ń wá àdéhùn, kì í ṣe òtítọ́.

Àwọn ọ̀nà méjèèjì ti àṣìṣe wà láàyè. Ẹ̀rọ kan lè ní tun0 fún ọ̀nà-abẹ́ àdúgbò tí kò ní í ṣe pẹ̀lú VPN olùlò, àti ọ̀nà-abẹ́ WireGuard tí ó ní ìlera pípé lè jẹ́ aláìlè-rí fún ìṣàyẹ̀wò tí ó kàn mọ okùn tun0. Àwọn èsì òdì tí kì í ṣe òtítọ́ àti àwọn èsì òdì àìtọ́ nínú iṣẹ́ kan náà ń jẹ́ kí ó di aláìlè-lò gẹ́gẹ́ bí ìṣàyẹ̀wò àrùn, nítorí pé tikẹ́ẹ̀tì ìtìlẹ́yìn tí ó sọ «a kò rí VPN kankan» kò ṣeé gbẹ́kẹ̀lé ní ọ̀nà kankan.

Ìwọlé náà ti dín kù pẹ̀lú. Àwọn ìtújáde Android tuntun ń dín ohun tí app lasan lè kà láti /proc kù, nítorí náà ìṣàyẹ̀wò tí ó dá lórí orúkọ tí ó ṣiṣẹ́ lórí Android 8 lè dá àkójọ òfìfo padà lórí ẹ̀rọ tí ó tẹ̀lé láìsí ìyípadà kóòdù kankan. Nígbà tí ìṣàyẹ̀wò bá kùnà ní ìdákẹ́jẹ́ sí ẹ̀gbẹ́ ṣíṣí, app náà parí pé kò sí VPN lórí hardware tí ọ̀nà-abẹ́ náà wà ní àìlódi.

Àròsọ: ping tí ó ṣàṣeyọrí túmọ̀ sí pé ọ̀nà-abẹ́ ń gbé ìrìnàjò

ping sí host inú ilé ń ṣàṣeyọrí nígbà gbogbo tí ọ̀nà kan sí host náà bá wà. Pẹ̀lú ọ̀nà-abẹ́ pínpín, host náà lè ṣeé dé nípasẹ̀ Wi-Fi nígbà tí ọ̀nà-abẹ́ náà wà lórí iṣẹ́ tí ó ń ṣe nǹkan mìíràn pátápátá. Pẹ̀lú VPN fún app kọ̀ọ̀kan, app tí ó ń ṣe ping lè jẹ́ ìyọkúrò kúrò nínú ọ̀nà-abẹ́, nítorí náà ìró ICMP jáde sí ìta rẹ̀ tí ó sì padà, èyí tí ó fi ìdíkejì ohun tí ìṣàyẹ̀wò náà ro hàn.

ICMP àti TCP pẹ̀lú ni a ń ṣe àyọkúrò lọ́tọ̀ọ̀tọ̀. Ọ̀nà-abẹ́ tí ó gba àwọn ìbéèrè ìró láàyè ṣùgbọ́n tí ó ju port TCP tí iṣẹ́ kan nílò sílẹ̀ yóò kọjá ìdánwò ping yóò sì kùnà nínú app, ìyẹn sì jẹ́ òfin odi-ina ní ẹ̀gbẹ́ kejì kì í ṣe àbùdá ẹ̀rọ náà. Ìwé kíkà tòótọ́ kan ṣoṣo ti ping tí ó ṣàṣeyọrí ni pé ibi-àfojúsùn yìí dáhùn sí ìlànà yìí ní àkókò yìí.

Ohun tí pẹlẹ́fọ́ọ̀mù ń ròyìn ní ti gidi

Láti API 21, ConnectivityManager.getAllNetworks() ń dá gbogbo nẹ́tíwọ́kì tí ẹ̀rọ náà mọ̀ padà, getNetworkCapabilities(network) sì ń ròyìn ohun tí nẹ́tíwọ́kì náà kéde. Nẹ́tíwọ́kì VPN ń gbé TRANSPORT_VPN. Yíyí ká gbogbo nẹ́tíwọ́kì ń dáhùn ìbéèrè kan: ṣé VPN kan wà lórí iṣẹ́ lórí ẹ̀rọ yìí ní báyìí?

Ìbéèrè kejì, tí ó dín jù, nílò ìpè mìíràn. getActiveNetwork() ń dá nẹ́tíwọ́kì tí ìrìnàjò app yóò lò ní báyìí padà, pípẹ̀wò agbára kan náà lórí rẹ̀ sì ń dáhùn: ṣé ìrìnàjò mi yóò gba VPN kọjá? Àwọn méjèèjì lè má fohùn ṣọ̀kan, àìfohùnṣọ̀kan náà sì ní ìsọfúnni. VPN tí ó wà lórí iṣẹ́ ṣùgbọ́n tí kì í ṣe ti báyìí ń tọ́ka sí ìtọ́sọ́nà fún app kọ̀ọ̀kan tàbí ìṣètò ọ̀nà-abẹ́ pínpín, kì í ṣe ọ̀nà-abẹ́ tí ó sọnù.

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

Dáàbò bo àwọn ìpè méjèèjì. Àwọn agbára lè jẹ́ null fún nẹ́tíwọ́kì tí ó sọnù láàrin kíkà àti bíbéèrè, nẹ́tíwọ́kì aláṣiṣẹ́ sì lè jẹ́ null nígbà ìfiránṣẹ́. NET_CAPABILITY_NOT_VPN wúlò ní ọ̀nà òdìkejì, láti jẹ́rìí pé nẹ́tíwọ́kì kan kì í ṣe ọ̀nà-abẹ́ dájúdájú dípò kíkàn jẹ́ pé kò ní àmì ìrìnàjò VPN.

NetworkInfo jẹ́ àròsọ kan náà pẹ̀lú API

ConnectivityManager.TYPE_VPN pẹ̀lú NetworkInfo jẹ́ ìran kejì ìṣàyẹ̀wò yìí, ó sì ti di ìgbàlódé fún ìdí kan. Nínú àwọn ìtújáde òde òní ohun tí a dá padà fún VPN lè jẹ́ null nígbà tí ọ̀nà-abẹ́ náà so mọ́, nítorí náà kóòdù tí ó ka null sí «kò sí VPN» ń ròyìn èsì òdì àìtọ́ ní ìdákẹ́jẹ́ lórí àwọn ẹ̀rọ tí ìdáhùn náà ṣe pàtàkì jù.

Ìkéde tí ó máa ń bá a lọ pẹ̀lú kò sàn jù. CONNECTIVITY_CHANGE ní ìtàn tí a kọ sílẹ̀ nípa pípàdánù àwọn ìyípadà VPN, pẹ̀lú àwọn build tí ó máa ń tan kìkì nígbà tí VPN so mọ́ tàbí já, dípò ní gbogbo ìyípadà nẹ́tíwọ́kì. Olùgbọ́ tí a kọ́ lórí rẹ̀ ń dá oníyípadà ipò tí ó ń jìnnà sí ojú-ìwòye pẹlẹ́fọ́ọ̀mù títí dé ìsopọ̀ kíkún tó kàn.

Dáhùn àwọn callback dípò ṣíṣe ìwádìí lẹ́ẹ̀kọ̀ọ̀kan

Forúkọsílẹ̀ NetworkRequest tí ó nílò TRANSPORT_VPN tí ó sì yọ NET_CAPABILITY_NOT_VPN kúrò, lẹ́yìn náà pe registerNetworkCallback pẹ̀lú ìbéèrè náà. Nígbà náà onAvailable àti onLost yóò sọ fún ọ nígbà tí ìkéde náà yípadà, ìyẹn sì ni ìṣẹ̀lẹ̀ tí ó ṣe pàtàkì fún ọ ní ti gidi. Yọ ìforúkọsílẹ̀ callback kúrò nígbà tí ẹ̀yà náà dúró, bí bẹ́ẹ̀ kọ́ app yóò di ìtọ́kasí sí ojú-ìwé tí ó ti kú mú àti callback yóò máa tan.

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

Èyí nílò ACCESS_NETWORK_STATE, tí ó jẹ́ àṣẹ lasan: kò sí root, kò sí àpótí ìfọwọ́sí olùlò, kò sí àṣẹ VPN. Ìwádìí pẹ̀lú aago ìdánwò ni ààyò tí àwọn ènìyàn ń gbára lé, ó sì ń jo bátírì nígbà tí ó ṣì ń pàdánù ìyípadà tí ó kúrú ju àkókò-àárín lọ, ìyẹn sì ni ìyípadà tí olùlò ń ròyìn.

Ohun tí ìdáhùn kò tíì lè sọ fún ọ

Kò sí ọ̀kan nínú àwọn API wọ̀nyí tí ń ròyìn bóyá ọ̀nà-abẹ́ náà ní ìlera, orí server wo ni ó ń parí, tàbí bóyá ìrìnàjò app pàtàkì kan wà nínú rẹ̀. Nẹ́tíwọ́kì VPN lè wà láìsí àwọn ọ̀nà tí ó ṣeé lò, ọ̀nà-abẹ́ fún app kọ̀ọ̀kan sì lè yọ app tí ó ń béèrè ìbéèrè náà kúrò.

Nítorí náà kọ ohun tí ìṣàyẹ̀wò náà rí sílẹ̀, kì í ṣe boolean nìkan. Kọ ìdánimọ̀ nẹ́tíwọ́kì, àwọn ìrìnàjò tí a kéde àti bóyá nẹ́tíwọ́kì náà wà lórí iṣẹ́. Ìròyìn tí ó sọ «a kò rí VPN kankan» kò wúlò, nígbà tí ìròyìn tí ó sọ pé nẹ́tíwọ́kì kan kéde TRANSPORT_VPN ṣùgbọ́n getActiveNetwork() dá Wi-Fi padà ń tọ́ka tààrà sí ìtọ́sọ́nà tàbí àkójọ ìyọkúrò, ìyẹn sì jẹ́ àtúnṣe tí ẹnìkan lè ṣiṣẹ́ lórí.

Àwọn àpilẹ̀kọ tó jọra