Android හි VPN හඳුනා ගැනීම: tun0 සහ ping අපගමනය කරන්නේ ඇයි
අතුරුමුහුණත් නාමයක් යනු සම්මුතියකි; ping එක් සත්කාරකයක් ළඟා විය හැකි බව ඔප්පු කරයි. ජාලයක් ප්රකාශ කරන්නේ කුමක්දැයි NetworkCapabilities වෙතින් අසා, පසුව කොල්බැක් සඳහා ප්රතිචාර දක්වන්න.
බොහෝ 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 ලබා දුන් බව කියන වාර්තාව සෘජුවම මාර්ගගත කිරීම හෝ බැහැර කිරීමේ ලැයිස්තුව වෙත යොමු කරයි, එය යමෙකුට වැඩ කළ හැකි නිවැරදි කිරීමකි.