Android VpnService സംബന്ധിച്ച നാല് അനുമാനങ്ങൾ ഒരിക്കൽ എന്റെ ആഴ്ചയുടെ ഭൂരിഭാഗവും തിന്നു, അവയൊന്നും നെറ്റ്വർക്ക് പ്രോട്ടോക്കോളിനെക്കുറിച്ചായിരുന്നില്ല. ആപ്പ് കണക്റ്റുചെയ്തു എന്ന് പറഞ്ഞു, കീ ഐക്കൺ സ്റ്റാറ്റസ് ബാറിൽ ഇരുന്നു, ട്രാഫിക് ഇപ്പോഴും സാധാരണ റൂട്ടിലൂടെ പുറത്തുപോയി. ഞാൻ അത് നിർത്തുന്നതുവരെ ടണൽ എന്റേതാണെന്നും, ഞാൻ ചേർത്ത റൂട്ടുകളാണ് എനിക്ക് ലഭിക്കുന്ന റൂട്ടുകളെന്നും, stopSelf വിളിച്ചാൽ ഇന്റർഫേസും കൂടെ താഴുമെന്നും ഞാൻ അനുമാനിച്ചുകൊണ്ടിരുന്നു. സേവനം ഡോക്യുമെന്റ് ചെയ്തതുപോലെ കൃത്യമായി പ്രവർത്തിച്ചു. തകർന്ന ഭാഗം എന്റെ മാനസിക മാതൃകയായിരുന്നു.

മിത്ത് 1: നിങ്ങൾ അത് നിർത്തുന്നതുവരെ ടണൽ നിൽക്കും

Android ഒരു സമയത്ത് ഒരു VPN ഇന്റർഫേസ് മാത്രം സൂക്ഷിക്കുന്നു. രണ്ടാമതൊന്ന് സ്ഥാപിക്കുക, പ്ലാറ്റ്ഫോം അത് ക്യൂവിൽ ഇടുന്നില്ല: നിങ്ങളുടേത് നിർജ്ജീവമാക്കി നിങ്ങളുടെ സേവനത്തിൽ onRevoke() വിളിക്കുന്നു. നിങ്ങളുടെ കോഡ് ബട്ടൺ അമർത്തുമ്പോൾ മാത്രം എല്ലാം പൊളിച്ചുമാറ്റുന്നുവെങ്കിൽ, ഏറ്റെടുക്കൽ പിന്നിൽ ഒരു ഡിസ്ക്രിപ്റ്ററും ഒരു റീഡർ ത്രെഡും വിടുന്നു, അടുത്ത തുടക്കം രണ്ടും പാരമ്പര്യമായി നേടുന്നു.

VpnService റഫറൻസ് വ്യക്തമായി പറയുന്നു, ആപ്പിന് ഇതിനകം സമ്മതമുണ്ടെങ്കിൽ prepare() null തിരികെ നൽകുന്നു, ഉപയോക്താവ് ഇനിയും അനുവദിക്കേണ്ടതുണ്ടെങ്കിൽ Intent നൽകുന്നു. ആ സമ്മതം നിങ്ങൾ ഉദ്ദേശ്യം startActivityForResult() വഴി എത്തിച്ചാൽ മാത്രമേ വരൂ. ഈ കൈമാറ്റം ഒഴിവാക്കിയാൽ establish() null നൽകുന്നു, അത് അനുമതി പ്രശ്നമല്ല, നിശബ്ദ പരാജയമായി വായിക്കപ്പെടുന്നു.

Always-on VPN നിങ്ങൾ നിയന്ത്രിക്കാത്ത ഒരു ഉടമയെ ചേർക്കുന്നു. ബൂട്ടിന് ശേഷമോ ക്രാഷിന് ശേഷമോ സിസ്റ്റത്തിന് ടണൽ തിരികെ കൊണ്ടുവരാം, അത് ഉപയോക്താവ് കൈകൊണ്ട് ആരംഭിച്ച VPN ആപ്പിനെ മറികടക്കുന്നു. നിങ്ങളുടെ സാധാരണ ഷട്ട്ഡൗൺ അടയ്ക്കുന്ന അതേ റിസോഴ്സുകൾ അടയ്ക്കുന്ന വിധത്തിൽ onRevoke() നിർമ്മിക്കുക, അതിനെ ഒരു അരികുപ്രകരണമായല്ല, പ്രധാന നിർത്തൽ പാതയായി കാണുക. ഉപയോക്താക്കൾ VPN ആപ്പുകൾ മാറ്റുന്നു; നിങ്ങളുടെ കോഡ് അത് അതിജീവിക്കണം.

മിത്ത് 2: addRoute നിങ്ങൾ ലിസ്റ്റ് ചെയ്തത് കൃത്യമായി പിടിക്കുന്നു

ഏത് പാക്കറ്റുകൾ നിങ്ങളുടെ ഡിസ്ക്രിപ്റ്ററിലേക്ക് എത്തുന്നു എന്ന് റൂട്ടുകൾ തീരുമാനിക്കുന്നു, പരിധിയിലെ പിഴവ് ചില ട്രാഫിക് ടണലിലൂടെ പോകുകയും ചിലത് പോകാതിരിക്കുകയും ചെയ്യുന്ന ശല്യപ്പെടുത്തുന്ന അവസ്ഥ സൃഷ്ടിക്കുന്നു. addRoute("0.0.0.0", 0) മുഴുവൻ IPv4 എടുക്കുന്നു, അതായത് ഇപ്പോൾ ഓരോ പാക്കറ്റും നിങ്ങളിലേക്ക് വരുന്നു, അത് കൈമാറണം അല്ലെങ്കിൽ ഉപേക്ഷിക്കണം. ഒരു ഹോസ്റ്റിനുള്ള /32 മിക്കവാറും ഒന്നും എടുക്കുന്നില്ല, ബാക്കിയെല്ലാം നിങ്ങളുടെ VPN ഒരിക്കലും ഇൻസ്റ്റാൾ ചെയ്യാത്തതുപോലെ പ്രവർത്തിക്കുന്നു.

കുടുംബങ്ങൾ വെവ്വേറെയാണ് കണക്കാക്കുന്നത്. IPv4 മാത്രമുള്ള റൂട്ട് IPv6 അടിസ്ഥാന നെറ്റ്വർക്കിൽ വിടുന്നു, അതിനാൽ ഇരട്ട-സ്റ്റാക്ക് ഹോസ്റ്റിന് ടണലിനുള്ളിൽ പൂർണ്ണമായി ബന്ധിപ്പിച്ചതുപോലെ തോന്നുമ്പോഴും പുറത്ത് പേര് പരിഹരിച്ച് ബന്ധിപ്പിക്കാൻ കഴിയും.

DNS അതേ യുക്തി പിന്തുടരുന്നു. addDnsServer() ഉപയോഗിച്ച് ചേർത്ത സെർവറുകൾ ടണലിന്റെ റിസോൾവർ ഉപയോഗിക്കുന്ന ആപ്പുകളിലേക്ക് പോകുന്നു, എന്നാൽ സ്വന്തം എൻക്രിപ്റ്റ് ചെയ്ത DNS എൻഡ്പോയിന്റോ ഹോസ്റ്റ്നാമിൽ സെറ്റ് ചെയ്ത Private DNS ഓ ഉള്ള ആപ്പ് അവയെ പൂർണ്ണമായി അവഗണിക്കുന്നു. ഒരു ആപ്പിന് പേരുകൾ പരാജയപ്പെടുകയും മറ്റൊന്നിന് വിജയിക്കുകയും ചെയ്യുമ്പോൾ, ഒരു റൂട്ടിൽ പോലും തൊടുന്നതിന് മുമ്പ് റിസോൾവർ പാത പരിശോധിക്കുക.

മിത്ത് 3: ആപ്പ് അനുസരിച്ചുള്ള നിയമങ്ങൾ ഇരുവശത്തേക്കും തിരിക്കാവുന്ന ഒരു സ്വിച്ചാണ്

addDisallowedApplication() ഉം addAllowedApplication() ഉം രണ്ട് ഫിൽട്ടറുകളല്ല, രണ്ട് മോഡുകളാണ്. ബിൽഡർ ഒരു ടണലിന് ഒരു മാതൃക മാത്രം സ്വീകരിക്കുന്നു, അതിനാൽ മൂന്ന് പാക്കേജുകൾ ഒഴികെ എല്ലാം ആഗ്രഹിക്കുന്ന ആപ്പ് വിലക്കിയ പട്ടിക ഉപയോഗിച്ച് അനുവദിച്ച പട്ടിക ശൂന്യമായി വിടുന്നു. രണ്ടും പരസ്പരം ഒഴിവാക്കുന്നതാണ്, സെറ്റിംഗ്സ് സ്ക്രീൻ ഇതിനകം രണ്ട് ടോഗിളുകളും വാഗ്ദാനം ചെയ്ത ശേഷം ആളുകൾ ഇത് റൺടൈമിൽ അറിയുന്നു.

പാക്കേജ് ദൃശ്യതയും കടിക്കുന്നു. Android 11 മുതൽ നിങ്ങൾ കാണുന്ന പാക്കേജുകൾക്ക് മാത്രമേ പേര് നൽകാൻ കഴിയൂ, അതിനാൽ നിങ്ങളുടെ ആപ്പിന് പ്രവർത്തിപ്പിക്കാൻ അനുവാദമില്ലാത്ത ഒരു ക്വറിയിൽ നിന്ന് നിർമ്മിച്ച ഒഴിവാക്കൽ പട്ടിക നിശബ്ദമായി എൻട്രികൾ നഷ്ടപ്പെടുത്തും. പട്ടിക വിശ്വസിക്കുന്നതിന് മുമ്പ് പാക്കേജ് മാനേജർ യഥാർത്ഥത്തിൽ എന്ത് തിരികെ നൽകുന്നു എന്നതുമായി താരതമ്യം ചെയ്യുക.

വർക്ക് പ്രൊഫൈലുകൾ പ്രേക്ഷകരെ വീണ്ടും വിഭജിക്കുന്നു. പ്രൊഫൈലിനുള്ളിൽ ആരംഭിച്ച ടണൽ ആ പ്രൊഫൈലിനെയും അതിന്റെ ആപ്പുകളെയും ഉൾക്കൊള്ളുന്നു, വ്യക്തിഗത വശം അതിന്റെ സ്വന്തം കണക്റ്റിവിറ്റി നിലനിർത്തുന്നു. അത് ഒരിക്കൽ എടുക്കുന്ന ഒരു പരിധി തീരുമാനമാണ്, അതിന്റെ സ്ഥാനം സപ്പോർട്ട് ടിക്കറ്റിലല്ല, ഇന്റർഫേസിലാണ്.

മിത്ത് 4: stopSelf ടണൽ അവസാനിപ്പിക്കുന്നു

ഇല്ല. ഇന്റർഫേസ് establish() തിരികെ നൽകുന്ന ഡിസ്ക്രിപ്റ്ററിൽ ജീവിക്കുന്നു, ആ ഡിസ്ക്രിപ്റ്റർ തുറന്നിരിക്കെ സേവന ഒബ്ജക്റ്റിന് മരിക്കാം. ആദ്യം ParcelFileDescriptor അടയ്ക്കുക, റഫറൻസ് വിടുക, റീഡർ, റൈറ്റർ ത്രെഡുകൾ ചേരുകയോ തടയുകയോ ചെയ്യുക, പിന്നീട് stopForeground(true) ഉം stopSelf() ഉം ആ ക്രമത്തിൽ വിളിക്കുക.

മറന്നുപോയ ഡിസ്ക്രിപ്റ്റർ ആണ് ഒരു സേവനം അതിന്റെ സ്വന്തം നിർത്തൽ അഭ്യർത്ഥനയെ അതിജീവിച്ചതായി തോന്നുന്നതിന്റെ സാധാരണ കാരണം, അത് അത് ചേർത്ത ആപ്പിനെക്കാൾ കൂടുതൽ കാലം ജീവിക്കുന്ന കാലഹരണപ്പെട്ട ഒരു റൂട്ട് വിശദീകരിക്കുന്നു.

വിപരീത തെറ്റും അത്രതന്നെ സാധാരണമാണ്: റീഡർ ത്രെഡ് വായനയുടെ നടുവിലായിരിക്കെ ഡിസ്ക്രിപ്റ്റർ അടയ്ക്കുക, പിന്നീട് ആ ത്രെഡിനെ ആരും കോഡ് എഴുതാത്ത ഒരു എക്സെപ്ഷൻ കൈകാര്യം ചെയ്യാൻ വിടുക. ഷട്ട്ഡൗൺ ക്രമം ഒരിടത്ത് സൂക്ഷിക്കുക, ഉപയോക്തൃ പ്രവർത്തനവും onRevoke() ഉം അതിലേക്ക് വിളിക്കട്ടെ.

ടണൽ മരിച്ചതുപോലെ തോന്നുമ്പോൾ എന്ത് പരിശോധിക്കണം

ടണൽ ഉയരുന്നതിന് മുമ്പ് ദീർഘകാല സോക്കറ്റുകൾ protect() ഉപയോഗിച്ച് സംരക്ഷിക്കുക. അതില്ലാതെ ടണലിന്റെ സ്വന്തം ഗതാഗതം വീണ്ടും ടണലിലേക്ക് റൂട്ട് ചെയ്യപ്പെടുകയും കണക്ഷൻ സെർവർ തകരാറിനോട് കൃത്യമായി സാമ്യമുള്ള രീതിയിൽ കുടുങ്ങുകയും ചെയ്യും. വിദൂര നെറ്റ്വർക്കിന് പിന്നിൽ മാത്രം നിലനിൽക്കുന്ന വിലാസത്തിനെതിരെ പരീക്ഷിക്കുക, കാഷെയിൽ നിന്നോ അടിസ്ഥാന പാതയിൽ നിന്നോ ഉത്തരം നൽകുന്ന പൊതു സൈറ്റിനെതിരെയല്ല.

establish() ന്റെ ഫലം, റൂട്ടുകൾ, ഒഴിവാക്കിയ പാക്കേജുകൾ, നിർത്തലിന്റെ കാരണം എന്നിവ ലോഗ് ചെയ്യുക. ആ നാല് വരികൾ പാക്കറ്റ് ക്യാപ്ചർ ഇല്ലാതെ സമ്മത പ്രശ്നത്തെ പരിധി പ്രശ്നത്തിൽ നിന്നും ലൈഫ്സൈക്കിൾ പ്രശ്നത്തിൽ നിന്നും വേർതിരിക്കുന്നു.

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