തെറ്റായ ധാരണ, VpnService ആപ്പ് ഒരു സിസ്റ്റം സ്വിച്ച് തിരിക്കുന്നു, അതിനുശേഷം ഫോൺ സംരക്ഷിതമാണ് എന്നതാണ്. യഥാർത്ഥത്തിൽ സംഭവിക്കുന്നത് കൂടുതൽ ഇടുങ്ങിയതാണ്: ആപ്പ് സമ്മതം ചോദിക്കുന്നു, ഒരു ഇന്റർഫേസ് നിർമ്മിക്കുന്നു, ഫയൽ ഡിസ്ക്രിപ്റ്റർ വഴി പാക്കറ്റുകൾ വായിക്കുകയും എഴുതുകയും ചെയ്യുന്നു, നിൽക്കുമ്പോൾ ഇന്റർഫേസ് തിരികെ നൽകുന്നു. ഒരേ സമയം അത്തരം ഒരു ടണൽ മാത്രമേ ജീവനോടെ ഇരിക്കാൻ കഴിയൂ, സിസ്റ്റത്തിന് ചോദിക്കാതെ അത് എടുത്തുകളയാം. പ്രോട്ടോക്കോളിന് ആളുകൾ കുറ്റപ്പെടുത്തുന്ന ആശയക്കുഴപ്പമുള്ള പെരുമാറ്റത്തിന്റെ ഭൂരിഭാഗവും ഈ ഉടമസ്ഥതാ മാതൃകയിൽ നിന്നാണ് വരുന്നത്.

ഓരോ ജീവിതചക്ര മാറ്റവും അതിരിലെ കേസല്ല, ഡിസൈനിന്റെ ഭാഗമായി കാണുക.

മിത്ത്: ആപ്പ് ഫോണിന്റെ VPN ഓൺ ചെയ്യുന്നു

VpnService.prepare() ൽ നിന്ന് ഫ്ലോ തുടങ്ങുന്നു, അത് ഉപയോക്താവ് സ്വീകരിക്കേണ്ട Intent നൽകുന്നു, തുടർന്ന് establish() ലേക്ക് പോകുന്നു, അത് പിന്നീടും ആപ്പ് നിയന്ത്രിക്കാത്ത കാരണങ്ങളാൽ പരാജയപ്പെടാം. രണ്ടാമത് ഒരു ടണൽ സ്ഥാപിക്കുന്നത് ആദ്യ ഇന്റർഫേസ് നിഷ്ക്രിയമാക്കുകയും സിസ്റ്റം അറിയിപ്പ് മാറ്റിസ്ഥാപിക്കുകയും ചെയ്യുന്നു. ആ ക്രമത്തിൽ എവിടെയും ആപ്പിന് ഉപകരണം മുഴുവന്റെ സ്വിച്ച് ഇല്ല; അതിന് നൽകിയ ഡിസ്ക്രിപ്റ്ററും അതിൽ എത്തുന്ന പാക്കറ്റുകളുമാണ് ഉള്ളത്. സ്ഥിരമായ അറിയിപ്പുപോലും ആപ്പിന്റെ ഡിസൈനിന്റേതല്ല, സിസ്റ്റത്തിന്റേതാണ്.

ഇന്റർഫേസ് പിടിച്ചെടുക്കുന്നതല്ല, നൽകുന്നതാണ്, അതിനാൽ മറ്റൊരു ക്ലയന്റിന് എപ്പോൾ വേണമെങ്കിലും സ്ഥലം എടുക്കാം. ആപ്പ് അത് റിട്ടേൺ മൂല്യത്തിലൂടെയല്ല, കോൾബാക്കിലൂടെയാണ് അറിയുന്നത്.

ആപ്പ് ബലമായി നിർത്തിയത് അറിയിപ്പ് പാനലിൽ കാണുന്നതും അതേ കാരണത്താലാണ്: സിസ്റ്റം താൻ എന്ത് നൽകി എന്ന് റിപ്പോർട്ട് ചെയ്യുന്നു, ആപ്പ് എന്ത് കാണിക്കാൻ തിരഞ്ഞെടുത്തു എന്നല്ല.

മിത്ത്: സമ്മതം ഒരിക്കൽ മാത്രം നൽകുന്നു

സിസ്റ്റം ടണൽ മറ്റൊരു ക്ലയന്റിന് കൈമാറുമ്പോൾ, ബേസ് ക്ലാസ് onBind() ൽ നിന്ന് തിരികെ നൽകുന്ന binder-ൽ ഒരു റദ്ദാക്കൽ ഇടപാട് അയയ്ക്കുന്നു. ആ binder തന്റേതുകൊണ്ട് മാറ്റിസ്ഥാപിക്കുന്ന ആപ്പ് റദ്ദാക്കൽ ഇടപാട് സ്വയം കൈമാറണം, അല്ലെങ്കിൽ VpnService.onRevoke() ഒരിക്കലും പ്രവർത്തിക്കുകയില്ല, സേവനം ഇനി നിലവിലില്ലാത്ത ഡിസ്ക്രിപ്റ്ററിലേക്ക് എഴുതിക്കൊണ്ടിരിക്കും. ഉപയോക്താവിനും അനുമതി പിൻവലിക്കാം, റീസ്റ്റാർട്ടിലോ എപ്പോഴും ഓൺ വീണ്ടും കണക്ട് ചെയ്യുമ്പോഴോ സിസ്റ്റത്തിന് സേവനം നിർത്താം.

ഇത് കൈകാര്യം ചെയ്യുന്നത് ഒരു ലോഗ് വരിയല്ല, വ്യക്തമായ ജോലിയാണ്: ഡിസ്ക്രിപ്റ്റർ വായിക്കുന്നത് നിർത്തുക, അത് അടയ്ക്കുക, കണക്ടഡ് ഫ്ലാഗ് മായ്ക്കുക, ഉപയോക്താവ് ഏത് അവസ്ഥയിലാണെന്ന് പറയുക. തുടർന്ന് ആപ്പ് വീണ്ടും സ്ഥാപിക്കണോ, വീണ്ടും ചോദിക്കണോ, കാത്തിരിക്കണോ എന്ന് തീരുമാനിക്കുക, കാരണം എപ്പോഴും ഓൺ ക്രമീകരണത്തിൽ സിസ്റ്റത്തിന് സേവനം സ്വയം തിരികെ കൊണ്ടുവരാം.

റദ്ദാക്കലിനെ അവസ്ഥയല്ല, അപവാദമായി കാണുന്ന ആപ്പ്, താൻ എഴുതുന്ന ഓരോ പാക്കറ്റും വലിച്ചെറിയപ്പെടുമ്പോഴും കണക്ടഡ് എന്ന് റിപ്പോർട്ട് ചെയ്യും, സ്വകാര്യതാ ഉപകരണത്തിന് സാധ്യമായ ഏറ്റവും മോശം പരാജയ മോഡ് ഇതാണ്.

മിത്ത്: ഇന്റർഫേസ് നിങ്ങൾക്കുവേണ്ടി ട്രാഫിക് ഫിൽട്ടർ ചെയ്യുന്നു

വരുന്നത് അസംസ്കൃത IP ആണ്. പിടിച്ചെടുക്കുകയോ ഫിൽട്ടർ ചെയ്യുകയോ ചെയ്യുക എന്നാൽ IP, TCP, UDP, IPv6 ഹെഡറുകൾ പാഴ്സ് ചെയ്യുക, ഫ്ലോകൾ ട്രാക്ക് ചെയ്യുക, മറുപടികൾ ഡിസ്ക്രിപ്റ്ററിലേക്ക് തിരികെ എഴുതുക എന്നിവയാണ്, ഇത് ഒരു ക്യാപ്ചർ ആപ്പിനെ സിസ്റ്റം സൗകര്യമല്ലാതെ ചെറിയ ഒരു നെറ്റ്വർക്ക് സ്റ്റാക്ക് ആക്കുന്നു. protect() ഉള്ളത് ആപ്പിന്റെ സ്വന്തം ട്രാൻസ്പോർട്ട് സോക്കറ്റ് തന്നെത്താൻ പിടിക്കുന്നതിനുപകരം സ്വന്തം ടണൽ ഒഴിവാക്കാൻ വേണ്ടിയാണ്, ടണൽ ഉയർന്നതിനുശേഷം നിർമ്മിക്കുന്ന ഓരോ സോക്കറ്റിലും പരിശോധിക്കാൻ യോഗ്യമായ ഒരു ബൂളിയൻ അത് തിരികെ നൽകുന്നു.

ബിൽഡറിലെ അനുവദനീയവും നിരോധിതവുമായ ആപ്പ് പട്ടികകൾ ആരുടെ ട്രാഫിക് ഇന്റർഫേസിലേക്ക് കയറുന്നു എന്ന് തീരുമാനിക്കുന്നു. അവ ഇന്റർഫേസ് വഹിക്കുന്ന IP പാക്കറ്റുകൾക്കപ്പുറമുള്ള പേലോഡിലേക്ക് പ്രവേശനം നൽകുന്നില്ല, ഒരു API-യും മറ്റൊരു ക്ലയന്റിന്റെ ടണൽ വെളിപ്പെടുത്തുന്നില്ല അല്ലെങ്കിൽ സിസ്റ്റത്തിന്റെ VPN പ്രൊഫൈലുകൾ ലിസ്റ്റ് ചെയ്യുന്നു. നെറ്റ്വർക്ക് കഴിവുകൾ ഒരു നെറ്റ്വർക്ക് VPN ട്രാൻസ്പോർട്ട് ആണെന്ന് പറയാം, പക്ഷേ ടണൽ ആരുടേതെന്ന് പറയാനാവില്ല.

അതുകൊണ്ടാണ് മറ്റ് ആപ്പുകളെക്കുറിച്ചുള്ള അവസ്ഥാ ചോദ്യങ്ങൾക്ക് വൈരുദ്ധ്യാത്മക ഉത്തരങ്ങൾ ലഭിക്കുന്നത്: വിവരം നിങ്ങളുടെ പ്രോസസ്സിന് വെളിപ്പെടുത്തിയിട്ടില്ല എന്ന് മാത്രം.

ജീവിതചക്രം യഥാർത്ഥത്തിൽ ആവശ്യപ്പെടുന്നത്

നിങ്ങൾ നിയന്ത്രിക്കുന്ന അവസ്ഥകൾ ട്രാക്ക് ചെയ്യുക: തയ്യാറായി, സ്ഥാപിച്ചു, റദ്ദാക്കി, നിർത്തി. വീണ്ടും കണക്ട് ചെയ്യൽ പൊളിച്ചെടുക്കലും തുടർന്ന് സ്ഥാപിക്കലും ആയിരിക്കണം, ഡിസ്ക്രിപ്റ്ററിനും ട്രാൻസ്പോർട്ട് സോക്കറ്റിനും ഒരൊറ്റ ഉടമയോടെ, കാരണം സ്ഥാപിക്കാൻ മത്സരിക്കുന്ന രണ്ട് ഘടകങ്ങൾ ലഭ്യമായ ഒരേയൊരു സ്ഥലത്തിനായി വഴക്കിടും. ആധുനിക Android-ൽ ബാക്ക്ഗ്രൗണ്ട് സ്റ്റാർട്ടുകൾ പരിമിതമാണ്, അതിനാൽ ബൂട്ട് ബ്രോഡ്കാസ്റ്റ് ഉറപ്പല്ല; API ലെവൽ അനുവദിക്കുന്നിടത്ത് അതിന്റെ അറിയിപ്പോടെ ഫോർഗ്രൗണ്ട് സേവനം ഉപയോഗിക്കുക.

അന്തിമ അവസ്ഥ മാത്രമല്ല, മാറ്റം ലോഗ് ചെയ്യുക, എല്ലാ പാതയും പരിശോധിക്കാൻ കഴിയുന്നത്ര ചെറുതായി അവസ്ഥാ യന്ത്രം സൂക്ഷിക്കുക. പരിശോധനയിൽ എത്തിച്ചേരാനാവാത്ത അവസ്ഥ, ലോഗ് ഇല്ലാതെ ഫീൽഡിൽ നേരിടേണ്ടിവരുന്ന അവസ്ഥയാണ്.

ഉപകരണത്തിൽ ജീവിതചക്രം പരിശോധിക്കുക

എമുലേറ്ററുകൾക്ക് കണക്റ്റിവിറ്റി വ്യാജമാക്കാം, പക്ഷേ സമ്മതത്തിന്റെയും റദ്ദാക്കലിന്റെയും പാത വിശ്വസനീയമായി അല്ല, അതിനാൽ സ്ഥലം മോഷ്ടിക്കാൻ രണ്ടാമതൊരു VPN ക്ലയന്റ് ഇൻസ്റ്റാൾ ചെയ്ത യഥാർത്ഥ ഉപകരണത്തിൽ ഇവ പ്രവർത്തിപ്പിക്കുക.

adb shell dumpsys connectivity | grep -i -A3 vpn
adb shell dumpsys activity services | grep -i -A2 vpnservice
adb logcat -s VpnService:V AndroidRuntime:E
adb shell am force-stop com.example.vpnapp

ടണൽ തുടങ്ങുക, അറിയിപ്പും ഇന്റർഫേസും സ്ഥിരീകരിക്കുക, തുടർന്ന് മറ്റേ ക്ലയന്റ് കണക്ട് ചെയ്ത് റദ്ദാക്കൽ കോൾബാക്ക് പ്രവർത്തിക്കുന്നുണ്ടോ, അവസ്ഥ മായുന്നുണ്ടോ എന്ന് നോക്കുക. ആപ്പ് ബലമായി നിർത്തി, ഇപ്പോഴും ജീവനുള്ള ഡിസ്ക്രിപ്റ്റർ റിപ്പോർട്ട് ചെയ്യുന്നതുണ്ടോ എന്ന് പരിശോധിക്കുക.

എപ്പോഴും ഓൺ റീസ്റ്റാർട്ടിനുശേഷം ക്രമം ആവർത്തിക്കുക, കാരണം ആ പാത ഉപയോക്താവ് തുടങ്ങിയ കണക്ഷനിൽ നിന്ന് വ്യത്യസ്തമാണ്. നിങ്ങൾ തിരയുന്നത് പച്ച ഐക്കണല്ല, ഇനി തന്റേതല്ലാത്ത ഡിസ്ക്രിപ്റ്റർ ഉപയോഗിക്കുന്നത് ആപ്പ് നിർത്തി എന്ന തെളിവാണ്.

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