VPN ક્લાયન્ટ જોડાય છે, બ્રાઉઝર કામ કરે છે, અને તમને ખરેખર જે એક આદેશની પરવા છે તે હજી પણ તમારા ઘરના જોડાણમાંથી જ નીકળે છે। અથવા ઊલટું બને છે: ટનલ ડિફોલ્ટ રૂટ પકડી લે છે અને સ્થાનિક ફાઇલ સર્વર ડેસ્કટોપ પરથી અદૃશ્ય થઈ જાય છે। મને આ એક બિલ્ડ એજન્ટ સાથે અનુભવ થયો, જેને આંતરિક આર્ટિફેક્ટ મિરર સુધી પહોંચવાનું હતું જ્યારે બાકીનો હોસ્ટ ઓફિસ LAN પર જ રહ્યો, અને ક્લાયન્ટે બરાબર બે વિકલ્પ આપ્યા: આખો ટ્રાફિક કે કંઈ નહીં। બંને દિશામાં વિનંતી એક જ છે, આ પ્રોગ્રામ અને આખું મશીન નહીં, અને મોટાભાગના ક્લાયન્ટમાં તેના માટે ચેકબોક્સ નથી, કારણ કે રૂટ ટેબલને કદી ખબર ન પડી કે પ્રોગ્રામ શું છે।

રૂટ ટેબલ તમારો પ્રોગ્રામ કેમ જોઈ શકતું નથી

જ્યારે પ્રક્રિયા પેકેટ મોકલે છે, સ્ટેક રૂટિંગ ટેબલમાં ગંતવ્ય સરનામું શોધે છે। ના એક્ઝિક્યુટેબલનું નામ, ના પોર્ટ એ શોધમાં આવે છે। ડોમેન નામો એ જ કારણે નિષ્ફળ જાય છે: ટનલ ટ્રાફિકને સરનામે લઈ જાય છે, અને નામ સરનામામાં ફેરવાય ત્યાં સુધીમાં રૂટિંગ એ જ એકમાત્ર લિવર છે જે કર્નલ પાસે બાકી છે। તેથી «ફક્ત આ સાઇટ માટે VPN» આખરે પ્રોક્સીનો અર્થ થાય છે, અને «ફક્ત આ પ્રોગ્રામ માટે VPN» નાના મિકેનિઝમ-સમૂહમાંથી એકનો અર્થ થાય છે।

MechanismWhat selectsCoversOn tunnel drop
Socket bindsource addressa client you controlconnections fail
UID rule (Linux)owning userevery process of one accountconnections fail
Firewall profile (Windows)adapter profileone programfails closed
Network namespacenamespace membershipeverything started insideconnections fail
SOCKS hopapp proxy settingone app or one browser profileconnections 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 નિયમ પૂરતો છે, જોડાણ બંધ રહીને નિષ્ફળ જવું જોઈએ ત્યારે ફાયરવોલ પ્રોફાઇલ પૂરતું છે, અને નેમસ્પેસ એ જ એકમાત્ર વિકલ્પ છે જે ટનલને તેની બહારની દરેક વસ્તુથી છુપાવે છે।

સંબંધિત લેખો