Android VpnService માં સ્પ્લિટ ટનલિંગ: ખરેખર શું રૂટ કરી શકાય
VpnService ફક્ત એ જ પેકેટ મોકલે છે જે builder તેના ડિસ્ક્રિપ્ટરને આપે છે. સ્પ્લિટ ટનલિંગને દોષ આપતા પહેલાં પ્રીફિક્સ, પ્રોક્સી પ્રમાણીકરણ, DNS અને એપ્લિકેશન યાદીઓ તપાસો.
VpnService એપમાં સ્પ્લિટ ટનલિંગ થોડી ચોક્કસ જગ્યાએ તૂટે છે અને દરેક માટે સુધારો અલગ છે. ક્લાયન્ટ ફક્ત એક નિષ્ફળ ગંતવ્ય બતાવે છે, તેથી પહેલું કામ એ છે કે તમે કઈ સીમા સ્પર્શી રહ્યા છો તે શોધવું: builder ને મળેલા રૂટ, જે પ્રોક્સીને તમે પ્રમાણિત કરી શકતા નથી, જે resolver તમે ફક્ત જાહેર કર્યો છે, અથવા પ્લેટફોર્મ દરેક વપરાશકર્તા માટે લાગુ કરે તે એપ્લિકેશન યાદી. એટલે જ હું ચાર પગલાંની તપાસ રાખું છું. તે નીચેના ક્રમમાં ચાલે છે અને પહેલી નિષ્ફળતા પર અટકે છે.
builder એ પ્લેટફોર્મને શું આપ્યું તેની ખાતરી કરો
VpnService.Builder એ ઘોષણાઓની યાદી છે. establish() વર્ચ્યુઅલ ઇન્ટરફેસ માટે ParcelFileDescriptor પાછું આપે છે, અને પ્લેટફોર્મ તે ડિસ્ક્રિપ્ટરમાં ફક્ત addAddress અને addRoute ના પ્રીફિક્સ સાથે મેળ ખાતો ટ્રાફિક મોકલે છે; addDnsServer ક્લાયન્ટને કહે છે કે કયા resolver ને પૂછવું. તમે ઉમેરેલા દરેક પ્રીફિક્સની બહારનું ગંતવ્ય ક્યારેય તમારી એપ સુધી પહોંચતું નથી, ઇન્ટરફેસ શું વચન આપે તે પ્રમાણે. એ એક હકીકત કોડ બદલતાં પહેલાં જ તૂટેલા સ્પ્લિટ ટનલિંગની મોટાભાગની ફરિયાદો સમજાવે છે.
તમારા builder એ બનાવેલી સરનામાં, રૂટ અને DNS યાદીઓ લોગ કરો, પછી તેમને નિષ્ફળ ગંતવ્યો સાથે સરખાવો. મેનેજમેન્ટ હોસ્ટ માટે ખૂટતું /32 તૂટેલા ટનલ કરતાં ઘણું સામાન્ય છે. યાદી યોગ્ય હોય તો આગળ વધો; ખોટી હોય તો બાકીની ચેકલિસ્ટ વ્યર્થ મહેનત છે.
excludeRoute ફક્ત API 33 થી છે
ગંતવ્ય આધારિત બાકાત એ એવી વિનંતી છે જે સૌથી વધુ સપોર્ટ થ્રેડમાં પરિણમે છે. builder.excludeRoute(IpPrefix) API 33 માં આવ્યું; તે પહેલાં એકમાત્ર સમર્થિત અંદાજ એ છે કે બાકાત પ્રીફિક્સ સિવાય બધા માટે રૂટ ઉમેરવા, એટલે પૂરક પ્રીફિક્સ તમારે જ ગણવા પડે. બે કૉલ અરીસાની છબી નથી: એક ઇન્ટરફેસના રૂટ સેટમાંથી બાદ કરે છે, બીજું સેટ શૂન્યથી બનાવે છે, અને જૂનું ઉપકરણ જે કૉલ ઓળખતું નથી તેને ફેંકશે અથવા ચૂપચાપ અવગણશે. Build.VERSION.SDK_INT પર શાખા પાડો અને બંને માર્ગો વાસ્તવિક હાર્ડવેર પર ચકાસો.
પૂરક ગણતી વખતે પ્રીફિક્સ સંરેખણ પર ધ્યાન આપો. /16 રૂટની અંદર /24 બાકાત માટે બાકીનો ભાગ ખરેખર વર્ણવતા આવરણ પ્રીફિક્સ જોઈએ, એક વિકૃત /8 નહીં. અંતિમ યાદી લોગ કરો અને ખાતરી કરો કે બાકાત હોસ્ટ હજુ ટનલની બહારના માર્ગે રિઝોલ્વ થાય છે.
પ્રોક્સી ઓળખપત્રો વ્યક્ત કરી શકાતા નથી
setHttpProxy(ProxyInfo) ઇન્ટરફેસને HTTP અથવા SOCKS પ્રોક્સી તરફ દોરે છે, અને PAC URL દરેક ગંતવ્ય માટે તેમની વચ્ચે પસંદગી કરી શકે છે. ProxyInfo કે PAC ફોર્મેટ વપરાશકર્તાનામ અને પાસવર્ડ ધરાવતું નથી, તેથી પ્રમાણીકરણ માંગતી પ્રોક્સી પ્લેટફોર્મ API ની બહાર રહે છે. જે એપ્સને તેની જરૂર હોય છે તે સામાન્ય રીતે userspace સ્ટેક, tun2socks અથવા સમાન એન્જિન ઉમેરે છે અને 407 પડકારનો જવાબ જાતે આપે છે.
આ પસંદગીના પરિણામો છે. userspace સ્ટેક ફક્ત તે ટ્રાફિક જુએ છે જે તમે તેની તરફ રૂટ કરો છો, તેથી તેને એ જ ડિસ્ક્રિપ્ટર સીમાની અંદર રહેવું પડે છે, અને પોતાના uplink સોકેટ માટે એ જ protect() આવશ્યકતા વારસામાં મળે છે. protect() છોડી દો તો ટનલ પોતાનું ટ્રાન્સપોર્ટ પકડી લે છે, જે પહેલા પેકેટ પછી અટકી જતા હેન્ડશેક તરીકે દેખાય છે. એવી પ્રોક્સી સામે પરીક્ષણ કરો જે ઓળખપત્રો માંગે છે, કારણ કે ખુલ્લી પ્રોક્સી પ્લેટફોર્મના માર્ગે પસાર થાય છે અને કંઈ સાબિત કરતી નથી.
એપ-વાર યાદીઓ અને DNS પણ ઘોષણાઓ છે
Builder માં addAllowedApplication અને addDisallowedApplication બંને છે, અને તે એકબીજાને બાકાત રાખે છે: બંને કૉલ કરવાથી અપવાદ ફેંકાય છે. કોઈ પણ રીતે યાદી ઇન્ટરફેસ સેટઅપ વખતે દરેક વપરાશકર્તા માટે લાગુ થાય છે, તેથી વર્ક પ્રોફાઇલની એપ તમારા ટનલને બદલે વર્ક પ્રોફાઇલના ટનલ દ્વારા સંચાલિત થાય છે. કોઈ API તમને બીજી એપના નિર્ણય પર નિયંત્રણ આપતું નથી: તમે બહારથી પેકેટને તમારા ટનલમાં ધકેલી શકતા નથી, અને પહેલેથી સક્રિય VPN ને બંધ કે ફરી ગોઠવી શકતા નથી.
DNS એ જ પેટર્ન અનુસરે છે. addDnsServer resolver નું સરનામું જાહેર કરે છે; તે તમારી એપને પ્રશ્નોના જવાબ આપવા દેતું નથી. જો તમે નામ જાતે રિઝોલ્વ કરવા માંગો તો resolver ચલાવો અને તેનું સરનામું ટનલમાં રૂટ કરો. નિશ્ચિત હોસ્ટનામ પર DoT કે DoH વાપરતી એપ્સ તમે જાહેર કરેલા સરનામાને ટાળી શકે છે, તેથી જ્યાં સુધી તમે પ્રશ્નનો માર્ગ પણ રોકતા ન હો ત્યાં સુધી નામ-રિઝોલ્યુશનને શ્રેષ્ઠ પ્રયાસ ગણો.
મેનિફેસ્ટ, always-on અને ચાર-પગલાંની કસોટી
પાત્રતા મેનિફેસ્ટમાં જાહેર થાય છે: BIND_VPN_SERVICE, android.net.VpnService intent ફિલ્ટર અને foreground સેવા જો ટનલને બેકગ્રાઉન્ડમાં ટકી રહેવું હોય. Always-on VPN વધુમાં સ્વચ્છ onRevoke માંગે છે, કારણ કે વપરાશકર્તા સેટિંગ્સ બદલે અથવા બીજી એપ નિયંત્રણ લે ત્યારે સિસ્ટમ તેને કૉલ કરે છે.
તપાસો ક્રમમાં ચલાવો અને પહેલી નિષ્ફળતા પર અટકો. પ્રથમ, builder ને આપેલી સરનામાં, રૂટ અને DNS યાદીઓ કાઢો. બીજું, ખાતરી કરો કે establish() એ ડિસ્ક્રિપ્ટર પાછું આપ્યું અને ટ્રાન્સપોર્ટ સોકેટ સુરક્ષિત છે. ત્રીજું, સમાવિષ્ટ પ્રીફિક્સની અંદર એક અને બાકાત પ્રીફિક્સની અંદર એક ગંતવ્ય માંગો. ચોથું, ફક્ત તમારો resolver જ રિઝોલ્વ કરી શકે એવું હોસ્ટનામ પૂછીને તપાસો કે કયો resolver ખરેખર જવાબ આપ્યો.
પૂર્ણ થયેલો હેન્ડશેક પછીના પગલાંમાંથી એક પણ સાબિત કરતો નથી. દરેક તપાસ એક સ્તર અલગ કરે છે, તેથી બીજા પગલાની સફળતા ચોથા વિશે કંઈ કહેતી નથી.
VpnService.Builder સંદર્ભ builder ની સંપૂર્ણ સપાટી સૂચિબદ્ધ કરે છે. તેની બહાર જે જોઈએ તે બીજું API, બીજી એપ અથવા તમારો પોતાનો userspace સ્ટેક છે, અને તે સ્પ્લિટ-ટનલ બગ નહીં પણ ડિઝાઇન નિર્ણય છે.