കൂടുതൽ 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 നൽകി എന്ന് പറയുന്ന റിപ്പോർട്ട് നേരിട്ട് റൂട്ടിംഗിനെയോ ഒഴിവാക്കൽ പട്ടികയെയോ സൂചിപ്പിക്കുന്നു, അത് ആർക്കെങ്കിലും പ്രവർത്തിക്കാവുന്ന ഒരു തിരുത്തലാണ്.

അനുബന്ധ ലേഖനങ്ങൾ