Բաժանված թունելավորումը VpnService հավելվածում կոտրվում է մի քանի կոնկրետ տեղերում, և յուրաքանչյուրի վերանորոգումը տարբեր է։ Հաճախորդը ցույց է տալիս միայն մեկ ձախողված նպատակակետ, ուստի առաջին խնդիրն է պարզել, թե որ սահմանին եք հանդիպում՝ builder-ի ստացած երթուղիները, proxy-ն, որը չեք կարող նույնականացնել, 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։ Գրանցեք վերջնական ցանկը և համոզվեք, որ բացառված հոսթը դեռ լուծվում է թունելից դուրս ուղով։

Proxy-ի հավատարմագրերը հնարավոր չէ արտահայտել

setHttpProxy(ProxyInfo)-ը միջերեսը ուղղում է HTTP կամ SOCKS proxy-ի, և PAC URL-ը կարող է յուրաքանչյուր նպատակակետի համար ընտրել նրանց միջև։ Ոչ ProxyInfo-ն, ոչ PAC ձևաչափը չեն կրում օգտանուն և գաղտնաբառ, ուստի նույնականացում պահանջող proxy-ն մնում է հարթակի API-ից դուրս։ Հավելվածները, որոնց դա պետք է, սովորաբար ներկառուցում են օգտագործողի տարածության կույտ, tun2socks կամ նման շարժիչ և իրենք են պատասխանում 407 մարտահրավերին։

Այդ ընտրությունն ունի հետևանքներ։ Օգտագործողի տարածության կույտը տեսնում է միայն այն երթևեկությունը, որը դուք ուղղում եք դրան, ուստի այն պետք է ապրի նույն նկարագրիչի սահմաններում և ժառանգում է նույն protect() պահանջը իր սեփական uplink սոքեթի համար։ Բաց թողեք protect()-ը և թունելը կորսվի իր իսկ տրանսպորտը, ինչը երևում է որպես առաջին փաթեթից հետո կանգնող ձեռքսեղմում։ Փորձարկեք proxy-ի դեմ, որը պահանջում է հավատարմագրեր, քանի որ բաց proxy-ն անցնում է հարթակի ուղով և ոչինչ չի ապացուցում։

Հավելվածների ցանկերն ու DNS-ը նույնպես հայտարարություններ են

Builder-ն ունի և՛ addAllowedApplication, և՛ addDisallowedApplication, և դրանք բացառում են միմյանց. երկուսն էլ կանչելը բացառություն է նետում։ Ամեն դեպքում ցանկը կիրառվում է յուրաքանչյուր օգտագործողի համար միջերեսի տեղադրման պահին, ուստի աշխատանքային պրոֆիլի հավելվածը ղեկավարվում է աշխատանքային պրոֆիլի թունելով, ոչ թե ձերով։ Այն, ինչ ոչ մի API չի տալիս, վերահսկողությունն է մեկ այլ հավելվածի որոշման վրա. դուք չեք կարող դրսից փաթեթ մղել ձեր թունել և չեք կարող փակել կամ վերակազմավորել արդեն ակտիվ VPN-ը։

DNS-ը հետևում է նույն ձևին։ addDnsServer-ը հայտարարում է resolver-ի հասցե. այն թույլ չի տալիս ձեր հավելվածին պատասխանել հարցումներին։ Եթե ուզում եք ինքներդ լուծել անունները, գործարկեք resolver և նրա հասցեն ուղղեք թունել։ Հավելվածները, որոնք DoT կամ DoH են օգտագործում ֆիքսված հոսթանվան համար, կարող են շրջանցել ձեր հայտարարած հասցեն, ուստի անունների լուծումը համարեք լավագույն ջանք, եթե նաև չեք ընդհատում հարցման ուղին։

Manifest-ը, always-on-ը և չորս քայլի թեստը

Իրավասությունը հայտարարվում է manifest-ում. BIND_VPN_SERVICE, android.net.VpnService intent զտիչը և foreground ծառայություն, եթե թունելը պետք է գոյատևի ֆոնում։ Always-on VPN-ը լրացուցիչ պահանջում է մաքուր onRevoke, քանի որ համակարգը կանչում է այն, երբ օգտագործողը փոխում է կարգավորումները կամ մեկ այլ հավելված ստանձնում է վերահսկողությունը։

Կատարեք ստուգումները հերթականությամբ և կանգ առեք առաջին ձախողման վրա։ Առաջին՝ արտածեք builder-ին տրված հասցեների, երթուղիների և DNS-ի ցանկերը։ Երկրորդ՝ հաստատեք, որ establish()-ը վերադարձրել է նկարագրիչ և որ տրանսպորտային սոքեթը պաշտպանված է։ Երրորդ՝ պահանջեք մեկ նպատակակետ ներառված նախածանցի ներսում և մեկը՝ բացառվածի ներսում։ Չորրորդ՝ ստուգեք, թե որ resolver-ն է իրականում պատասխանել՝ հարցնելով հոսթանուն, որը կարող է լուծել միայն ձեր resolver-ը։

Ավարտված ձեռքսեղմումը չի ապացուցում հետագա քայլերից ոչ մեկը։ Յուրաքանչյուր ստուգում մեկուսացնում է մեկ շերտ, ուստի երկրորդ քայլի հաջողությունը ոչինչ չի ասում չորրորդի մասին։

VpnService.Builder-ի տեղեկատուն թվարկում է builder-ի ամբողջ մակերեսը։ Ամեն ինչ, ինչ պետք է դրանից դուրս, այլ API է, այլ հավելված կամ ձեր սեփական օգտագործողի տարածության կույտը, և դա ձևավորման որոշում է, ոչ թե բաժանված թունելի սխալ։

Առնչվող հոդվածներ