ഒരു ആപ്പിന്റെ ട്രാഫിക് മുഴുവൻ മെഷീനും ഉൾപ്പെടുത്താതെ VPN വഴി എങ്ങനെ അയയ്ക്കാം
പ്രോസസ്സ് അനുസരിച്ച് VPN മാറ്റാൻ കഴിയുന്ന സ്വിച്ച് സാധാരണ ഡെസ്ക്ടോപ്പുകളിൽ ഇല്ല. ട്രാഫിക്ക് തിരഞ്ഞെടുക്കുന്ന പാളി നിങ്ങൾ തന്നെ തീരുമാനിക്കണം: ബൗണ്ട് ചെയ്ത സോക്കറ്റ്, UID നിയമം, ഫയർവാൾ പ്രൊഫൈൽ, അല്ലെങ്കിൽ SOCKS ഹോപ്പ്.
VPN ക്ലയന്റ് കണക്ട് ചെയ്യുന്നു, ബ്രൗസർ പ്രവർത്തിക്കുന്നു, എന്നിട്ടും നിങ്ങൾക്ക് യഥാർത്ഥത്തിൽ വേണ്ട ആ കമാൻഡ് ഇപ്പോഴും നിങ്ങളുടെ വീട്ടിലെ കണക്ഷനിലൂടെയാണ് പുറത്തുപോകുന്നത്. അല്ലെങ്കിൽ നേരെ മറിച്ചാണ് സംഭവിക്കുന്നത്: ടണൽ ഡിഫോൾട്ട് റൂട്ട് പിടിച്ചെടുക്കുന്നു, ലോക്കൽ ഫയൽ സെർവർ ഡെസ്ക്ടോപ്പിൽ നിന്ന് അപ്രത്യക്ഷമാകുന്നു. ഒരു ബിൽഡ് ഏജന്റിനൊപ്പം ഇത് എനിക്ക് അനുഭവപ്പെട്ടു, അതിന് ആന്തരിക ആർട്ടിഫാക്ട് മിറർ എത്തിച്ചേരേണ്ടതുണ്ടായിരുന്നു, ഹോസ്റ്റിന്റെ ബാക്കി ഭാഗം ഓഫീസ് LAN-ൽ തന്നെ നിന്നു, ക്ലയന്റ് കൃത്യമായി രണ്ട് ഓപ്ഷനുകൾ മാത്രം തന്നു, എല്ലാ ട്രാഫിക്കും അല്ലെങ്കിൽ ഒന്നുമില്ല. ഇരുവശത്തുനിന്നും ഉള്ള അഭ്യർത്ഥന ഒന്നുതന്നെയാണ്, ഈ പ്രോഗ്രാം മാത്രം, മുഴുവൻ മെഷീനും അല്ല, മിക്ക ക്ലയന്റുകളിലും ഇതിന് ഒരു ചെക്ക്ബോക്സ് ഇല്ല, കാരണം റൂട്ട് ടേബിളിന് ഒരു പ്രോഗ്രാം എന്നത് എന്താണെന്ന് ഒരിക്കലും അറിയില്ല.
ഒരു പ്രോഗ്രാമിനെ റൂട്ട് ടേബിളിന് കാണാൻ കഴിയാത്തത് എന്തുകൊണ്ട്
ഒരു പ്രോസസ്സ് ഒരു പാക്കറ്റ് അയയ്ക്കുമ്പോൾ, സ്റ്റാക്ക് റൂട്ടിംഗ് ടേബിളിൽ ലക്ഷ്യ വിലാസം തിരയുന്നു. എക്സിക്യൂട്ടബിളിന്റെ പേരോ പോർട്ടോ ആ തിരയലിൽ പ്രവേശിക്കുന്നില്ല. ഡൊമെയ്ൻ നാമങ്ങൾ അതേ കാരണത്താൽ പരാജയപ്പെടുന്നു: ഒരു ടണൽ ട്രാഫിക്കിനെ ഒരു വിലാസത്തിലേക്ക് കൊണ്ടുപോകുന്നു, ഒരു നാമം അതിലേക്ക് റിസോൾവ് ചെയ്തു കഴിയുമ്പോഴേക്കും, കേർണലിന് ഇനി ബാക്കിയുള്ള ഏക ഉപായം റൂട്ടിംഗ് മാത്രമാണ്. അതുകൊണ്ടാണ് “ഈ സൈറ്റിനു മാത്രം VPN” എന്നത് ഒരു പ്രോക്സി എന്ന അർത്ഥത്തിലും, “ഈ പ്രോഗ്രാമിനു മാത്രം VPN” എന്നത് ചെറിയ കൂട്ടം മെക്കാനിസങ്ങളിൽ ഒന്ന് എന്ന അർത്ഥത്തിലും അവസാനിക്കുന്നത്.
| Mechanism | What selects | Covers | On tunnel drop |
|---|---|---|---|
| Socket bind | source address | a client you control | connections fail |
| UID rule (Linux) | owning user | every process of one account | connections fail |
| Firewall profile (Windows) | adapter profile | one program | fails closed |
| Network namespace | namespace membership | everything started inside | connections fail |
| SOCKS hop | app proxy setting | one app or one browser profile | connections fail |
ഇവയൊന്നും പ്രോസസ്സ് അനുസരിച്ചുള്ള റൂട്ട് അല്ല. ഓരോന്നും തീരുമാനത്തെ പ്രോഗ്രാം, ഉപയോക്താവ്, അല്ലെങ്കിൽ ആപ്പിന്റെ സ്വന്തം കോൺഫിഗറേഷൻ കാണാൻ കഴിയുന്ന ഒരു പാളിയിലേക്ക് മാറ്റുന്നു.
ഒരു ലക്ഷ്യസ്ഥാനം മാത്രം എന്നത് ഇപ്പോഴും ഒരു റൂട്ട് ആണ്, പ്രോഗ്രാം നിയമമല്ല. macOS-ൽ സാധാരണ രീതി “എല്ലാ ട്രാഫിക്കും VPN വഴി അയയ്ക്കുക” എന്നത് അൺചെക്ക് ചെയ്ത് ഒരു ഹോസ്റ്റ് റൂട്ട് ചേർക്കുക എന്നതാണ്: sudo route add -host internal-tuner.example -interface ppp0, വീണ്ടും sudo route delete -host internal-tuner.example -interface ppp0 ഉപയോഗിച്ച് നീക്കം ചെയ്യുന്നു. ആദ്യം ifconfig എന്നതിൽ നിന്ന് ഇന്റർഫേസ് നാമം വായിക്കുക, കാരണം ppp0 ഒരു ഉദാഹരണം മാത്രമാണ്. ഹോസ്റ്റ് റൂട്ടിൽ വൈൽഡ്കാർഡുകൾ പ്രവർത്തിക്കില്ല, അതിനാൽ നിരവധി നാമങ്ങളുമായി സംസാരിക്കുന്ന ഒരു സേവനത്തിന് ഓരോ നാമത്തിനും ഒരു എൻട്രി വേണം, ഈ നിയമം മെഷീനിലെ എല്ലാ പ്രോസസ്സുകളെയും ഉൾക്കൊള്ളുന്നു, നിങ്ങൾ മനസ്സിൽ കരുതിയതിനെ മാത്രമല്ല.
സോക്കറ്റ് ടണൽ വിലാസത്തിലേക്ക് ബൈൻഡ് ചെയ്യുക
നിങ്ങൾ ക്ലയന്റ് നിയന്ത്രിക്കുമ്പോൾ, ബൈൻഡിംഗ് ആണ് ഏറ്റവും ചെലവുകുറഞ്ഞ സെലക്ടർ. ടണലിന്റെ ലോക്കൽ വിലാസത്തിലേക്ക് ബൈൻഡ് ചെയ്ത സോക്കറ്റ്, ലക്ഷ്യസ്ഥാനത്തിന് അവിടെ ഒരു റൂട്ട് ഉള്ളിടത്തോളം, ആ ഇന്റർഫേസിലൂടെ പുറത്തുപോകുന്നു, മെഷീനിലെ മറ്റെല്ലാം അതിന്റെ സാധാരണ പാത തുടരുന്നു. സൂക്ഷ്മത എന്നത്, ബൈൻഡ് ഉറവിട വിലാസം തിരഞ്ഞെടുക്കുന്നു, എന്നാൽ റൂട്ട് ടേബിൾ ഇപ്പോഴും പുറത്തേക്കുള്ള വഴി തിരഞ്ഞെടുക്കുന്നു എന്നതാണ്. ടണലിലേക്ക് ഒരു റൂട്ട് ഇല്ലാത്ത ട്രാഫിക്കിനെ ഒരു ബൈൻഡ് മാത്രം നീക്കില്ല, “ഞാൻ ബൈൻഡ് ചെയ്തു, എന്നിട്ടും അത് തെറ്റായ വഴിയിലൂടെ പോകുന്നു” എന്ന മിക്ക റിപ്പോർട്ടുകളുടെയും പിന്നിലെ തെറ്റ് ഇതാണ്.
import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))ഉയർന്ന തലത്തിലുള്ള ഉപകരണങ്ങൾ ഇതേ ആശയം പുറത്തുകാണിക്കുന്നു: curl --interface 10.8.0.2, PHP-യുടെ CURLOPT_INTERFACE, Python-ന്റെ HTTP ക്ലയന്റുകളിലെ source_address ആർഗുമെന്റ്. വിലാസം ടണലിന്റേതായിരിക്കണം, ഇവിടെ ഒരു തെറ്റ് സാധാരണ കണക്ഷൻ പിശകായാണ് പരാജയപ്പെടുന്നത്, റൂട്ടിംഗ് പരാതിയായല്ല. വിലാസത്തിനു പകരം ഉപകരണനാമത്തിലേക്ക് ബൈൻഡ് ചെയ്യുന്നത് Linux-ലെ ഒരു പ്രത്യേകാവകാശമാണ്, അത് Windows-ലോ macOS-ലോ പകരില്ല, അതുകൊണ്ടാണ് പോർട്ടബിൾ സ്ക്രിപ്റ്റുകൾ വിലാസം കൈമാറുന്നത്.
Linux: പ്രോഗ്രാം നാമമല്ല, ഉടമയെ പൊരുത്തപ്പെടുത്തുക
ഒരു സോക്കറ്റിന്റെ ഉടമസ്ഥ ഉപയോക്താവിനെ കേർണലിന് പൊരുത്തപ്പെടുത്താൻ കഴിയും, അതിനാൽ സമർപ്പിത അക്കൗണ്ട് തന്നെ സെലക്ടറായി മാറുന്നു.
ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100ടണൽ ഇതിനകം ഡിഫോൾട്ട് റൂട്ട് അല്ലെങ്കിൽ മാത്രമേ ഇത് പ്രവർത്തിക്കൂ. ക്ലയന്റ് --route-nopull ഉപയോഗിച്ച് ആരംഭിക്കുക, അല്ലെങ്കിൽ --pull-filter ignore "redirect-gateway" ഉപയോഗിച്ച് പുഷ് ചെയ്ത റീഡയറക്ട് OpenVPN 2.4 മുതൽ ഫിൽട്ടർ ചെയ്യുക, എന്നിട്ട് ടേബിൾ എൻട്രി സ്വയം ചേർക്കുക. അല്ലെങ്കിൽ രണ്ട് ഡിഫോൾട്ടുകളും നിലനിൽക്കും, കുറഞ്ഞ മുൻഗണനയുള്ളത് വിജയിക്കും. അതിന്റെ ബോധപൂർവമായ പതിപ്പ് ഡിഫോൾട്ട് റൂട്ട് ടണൽ ഗേറ്റ്വേയിലേക്ക് ചൂണ്ടുന്നതാണ്, അല്ലെങ്കിൽ ഡിസ്കണക്ട് സ്ക്രിപ്റ്റിൽ നിന്ന് ചെയ്യുന്നതാണ്: ടണൽ വീഴുമ്പോൾ ഇത് ട്രാഫിക്കിനെ ഇന്റർനെറ്റിൽ നിന്ന് അകറ്റി നിർത്തുന്നു, പക്ഷേ അത് ഒരു കിൽ സ്വിച്ച് ആണ്, സെലക്ടറല്ല, ആരെങ്കിലും അത് നീക്കം ചെയ്യുന്നതുവരെ അത് നിലനിൽക്കും.
കൂടുതൽ ശക്തമായ പതിപ്പ് ഒരു നെറ്റ്വർക്ക് നെയിംസ്പേസ് ആണ്. അത് സൃഷ്ടിക്കുക, ക്ലയന്റ് അതിനുള്ളിൽ പ്രവർത്തിപ്പിക്കുക, ആപ്ലിക്കേഷൻ ip netns exec ഉപയോഗിച്ച് ആരംഭിക്കുക. നെയിംസ്പേസിനു പുറത്തുള്ള ഒന്നും ടണൽ ഇന്റർഫേസ് കാണുന്നില്ല, അതിനാൽ ആപ്ലിക്കേഷന് ആകസ്മികമായി ഹോസ്റ്റ് റൂട്ടിലേക്ക് പിൻവാങ്ങാൻ കഴിയില്ല. ചെലവ് യഥാർത്ഥമാണ്: ഭൗതിക നെറ്റ്വർക്കിൽ എത്താൻ നെയിംസ്പേസിന് ഒരു veth ജോഡിയും സ്വന്തം റിസോൾവർ ഫയലും വേണം, കാരണം മൗണ്ട് നെയിംസ്പേസ് ഹോസ്റ്റിന്റെ റിസല്യൂഷൻ ക്രമീകരണങ്ങൾ പങ്കിടുന്നില്ല.
രണ്ട് പരാജയ മോഡുകൾ മിക്ക ലീക്കുകളും വിശദീകരിക്കുന്നു. നാമ വിവർത്തനം ഇപ്പോഴും ഹോസ്റ്റിന്റെ റിസോൾവറിൽ നടക്കുന്നു, അതിനാൽ TCP കണക്ഷൻ അകത്തേക്ക് പോകുമ്പോഴും ക്വറി ടണലിനു പുറത്തേക്കാണ് പോകുന്നത്. IPv6-ന് സ്വന്തമായി ip -6 rule വേണം, കാരണം ഒരു v4 നിയമം അതിനെ ഉൾക്കൊള്ളുന്നില്ല.
Windows-ഉം macOS-ഉം: ഫയർവാളിന്റെ പരിധി നിശ്ചയിക്കുകയോ പ്രോക്സി കൈമാറുകയോ ചെയ്യുക
Windows-നും പ്രോഗ്രാം അനുസരിച്ചുള്ള റൂട്ട് സെലക്ടർ ഇല്ല, പക്ഷേ അതിന്റെ ഫയർവാൾ നിയമങ്ങൾക്ക് ഒരു പ്രൊഫൈലിലേക്ക് പരിധി നിശ്ചയിക്കാം, VPN അഡാപ്റ്ററെ പബ്ലിക് ആയി തരംതിരിക്കാം, വീട്ടിലെ LAN പ്രൈവറ്റ് ആയി തുടരും. പ്രൈവറ്റ്, ഡൊമെയ്ൻ പ്രൊഫൈലുകളിൽ പ്രോഗ്രാമിനുള്ള ഔട്ട്ബൗണ്ട് ബ്ലോക്ക് നിയമങ്ങൾ സൃഷ്ടിക്കുക, പബ്ലിക് തുറന്ന് വിടുക, എന്നിട്ട് ആപ്ലിക്കേഷന് ടണലിലൂടെ മാത്രമേ നെറ്റ്വർക്കിൽ എത്താൻ കഴിയൂ. ആദ്യം കണക്ഷന്റെ നെറ്റ്വർക്ക് വിഭാഗം ക്രമീകരിക്കുക, എന്നിട്ട് ഫയർവാളിന്റെ മോണിറ്റർ പാനലിൽ നിയമം പൊരുത്തപ്പെട്ടുവെന്ന് സ്ഥിരീകരിക്കുക. ഇത് ഒരു റൂട്ട് അല്ല, ഒരു ബ്ലോക്ക് ആണ്: ടണൽ വീഴുമ്പോൾ ഇത് അടച്ച് പരാജയപ്പെടുന്നു, ഫയർവാൾ അവഗണിക്കുന്ന ഒരു ആപ്ലിക്കേഷനെ ഇതിന് തടയാൻ കഴിയില്ല.
macOS അതേ യുക്തി വ്യത്യസ്ത ഉപകരണങ്ങളോടെ പിന്തുടരുന്നു. SSH-ലൂടെ എത്തുന്ന ഒരു SOCKS ലിസ്നർ ഏറ്റവും കുറഞ്ഞ ഇടപെടലുള്ള ഓപ്ഷനാണ്, കാരണം ssh -D 1080 user@host ഒരു ലോക്കൽ പോർട്ട് സൃഷ്ടിക്കുന്നു, അത് ഉപയോഗിക്കാൻ ക്രമീകരിച്ച ആപ്ലിക്കേഷനുകൾ മാത്രം ആ പാതയിലൂടെ പോകുന്നു. ഒരു pf നിയമത്തിന് ഉപയോക്താവിനോ ഗ്രൂപ്പിനോ അനുസരിച്ച് ഒരു പ്രോഗ്രാം തടയാൻ കഴിയും, പക്ഷേ അതിന് ആ പ്രോഗ്രാമിനു മാത്രം ടണൽ തിരഞ്ഞെടുക്കാൻ കഴിയില്ല. Tunnelblick-ന് ഡൊമെയ്ൻ അനുസരിച്ച് ഫിൽട്ടർ ചെയ്യാൻ കഴിയില്ല, കാരണം റൂട്ടുകൾ വിലാസങ്ങളിൽ പ്രവർത്തിക്കുന്നു; സർവർ വളരെ വീതിയുള്ള ഒരു പ്രിഫിക്സ് പട്ടിക പുഷ് ചെയ്യുമ്പോൾ OpenConnect ഉപയോക്താക്കൾ vpn-slice എന്നതിലേക്ക് എത്തുന്നു.
പ്ലാറ്റ്ഫോം ഉപകരണങ്ങൾ നഷ്ടപ്പെടുത്തുന്നത് രണ്ട് പരിഹാരങ്ങൾ ഉൾക്കൊള്ളുന്നു. ഡൊമെയ്ൻ അനുസരിച്ച് പ്രോക്സി മാറ്റുന്ന ബ്രൗസർ എക്സ്റ്റൻഷനുകൾ “ഈ സൈറ്റ് മാത്രം” എന്നതിനുള്ള പ്രായോഗിക ഉത്തരമാണ്, കാരണം അവ നാമങ്ങൾ ഇപ്പോഴും നിലനിൽക്കുന്ന ആപ്ലിക്കേഷൻ പാളിയിൽ പ്രവർത്തിക്കുന്നു; അവ ഒരു ബ്രൗസറിനെ മാത്രം ഉൾക്കൊള്ളുന്നു, മറ്റൊന്നുമില്ല. വെണ്ടർ ക്ലയന്റ് ഒരു വിർച്വൽ മെഷീനിനുള്ളിൽ പ്രവർത്തിപ്പിക്കുക എന്നതാണ് പരുക്കൻ മാർഗം, അപ്പോൾ ഗസ്റ്റ് റൂട്ട് മാറ്റത്തിന്റെ ഉടമയാകും, ഹോസ്റ്റ് അതിന്റെ പാത നിലനിർത്തും; രണ്ട് നെറ്റ്വർക്ക് സ്റ്റാക്കുകൾ പരിപാലിക്കേണ്ട ചെലവ് ഇതിനുണ്ട്.
ബൈൻഡ് ഓപ്ഷൻ ഇല്ലാത്ത ഉപകരണങ്ങൾക്കായി ഒരു SOCKS ഹോപ്പ്
മിക്ക ആപ്ലിക്കേഷനുകളെയും ഒരു HTTP അല്ലെങ്കിൽ SOCKS പ്രോക്സിയിലേക്ക് ചൂണ്ടിക്കാം, അവയ്ക്ക് ഇന്റർഫേസുകളെക്കുറിച്ച് ഒന്നും അറിയില്ലെങ്കിൽ പോലും. ഒരു SSH ക്ലയന്റ് സർവർ വശത്ത് മാറ്റമില്ലാതെ ഒന്ന് നൽകുന്നു:
ssh -N -D 127.0.0.1:9999 [email protected]ആ പോർട്ട് ഉപയോഗിക്കാൻ ക്രമീകരിച്ച എല്ലാം ബാസ്റ്റ്യനിൽ പുറത്തുപോകുന്നു, ഡെസ്ക്ടോപ്പിലെ ബാക്കി ഭാഗം അതിന്റെ സാധാരണ കണക്ഷൻ നിലനിർത്തുന്നു. ടണൽ വിലാസത്തിലേക്ക് ബൈൻഡ് ചെയ്ത ഒരു ലോക്കൽ 3proxy ഇൻസ്റ്റൻസ് SSH ഇല്ലാതെ ഒരു പോർട്ടിന് ഇത് ചെയ്യുന്നു, stunnel ഒരു TLS പൊതിഞ്ഞ പോർട്ട് ഉൾക്കൊള്ളുന്നു. പരിധികൾ പ്രായോഗികമാണ്: ഒരു പ്രോക്സി, അത് ഉപയോഗിക്കാൻ അറിയുന്ന പ്രോട്ടോക്കോളുകൾ മാത്രം കൊണ്ടുപോകുന്നു, UDP-ന് SOCKS5 UDP അസോസിയേഷൻ വേണം, അത് പല ക്ലയന്റുകളുടെയും “SOCKS5” ക്രമീകരണം സജീവമാക്കുന്നില്ല, DNS പ്രോക്സി തന്നെ റിസോൾവ് ചെയ്യണം (curl-ൽ socks5h), അല്ലെങ്കിൽ നാമം ലോക്കൽ റിസോൾവറിലേക്ക് ചോരുന്നു.
മറ്റൊരു മെഷീനിന് ആവശ്യമില്ലെങ്കിൽ ലിസ്നർ ലൂപ്പ്ബാക്കിൽ തന്നെ നിലനിർത്തുക.
സ്റ്റാറ്റസ് സന്ദേശമല്ല, ഒരു ക്യാപ്ചർ ഉപയോഗിച്ച് പാത പരിശോധിക്കുക
ആപ്ലിക്കേഷൻ സ്റ്റാറ്റസ് ജാലകങ്ങൾ ക്രമീകരണത്തെ വിവരിക്കുന്നു, പാക്കറ്റിനെയല്ല. രണ്ട് ഇന്റർഫേസുകളിലും ക്യാപ്ചർ ചെയ്ത് താരതമ്യം ചെയ്യുക:
tcpdump -i any -n port 443
ss -tnp | grep 443കണക്ഷൻ ടണലിൽ പൊരുത്തമുള്ള എൻട്രി ഇല്ലാതെ ഭൗതിക ഇന്റർഫേസിൽ പ്രത്യക്ഷപ്പെടുന്നുവെങ്കിൽ, ക്ലയന്റ് എന്ത് റിപ്പോർട്ട് ചെയ്താലും, സെലക്ടർ പ്രാബല്യത്തിലില്ല. IPv6-ഉം റിസോൾവറും വെവ്വേറെ പരിശോധിക്കുക, ഒരു ഹെൽപ്പർ പ്രോസസ്സോ പാരമ്പര്യമായി ലഭിച്ച സിസ്റ്റം പ്രോക്സിയോ പോലുള്ള രണ്ടാമത്തെ പാതയും പരിശോധിക്കുക.
എന്നിട്ട് ആവശ്യകതയുമായി പൊരുത്തപ്പെടുന്ന അതിർത്തി തിരഞ്ഞെടുക്കുക: ഒരു സൈറ്റിന് ഒരു പ്രോക്സി മതി, ഒരു അക്കൗണ്ടിന് ഒരു UID നിയമം മതി, കണക്ഷൻ അടച്ച് പരാജയപ്പെടണമെങ്കിൽ ഒരു ഫയർവാൾ പ്രൊഫൈൽ മതി, പുറത്തുള്ള എല്ലാത്തിനും ടണൽ മറയ്ക്കാൻ നെയിംസ്പേസ് മാത്രമാണ് ഓപ്ഷൻ.