Android VPN: descriptor-ka VpnService iyo qalabka tun ee root
App-yada Android ma abuuri karaan tun0 keligood: waxa establish() soo celiyo, halka Binder joogsado iyo halka JNI bilaabmo, iyo goorta qalab uu root abuuray guuleysto.
Laba dari ayaa ka dhigi kara IP interface in ay hor timaaddo app Android, oo labaduba waxay ku dhammaadaan isla nooc file descriptor ah oo leh milkiilayaal aad u kala duwan. Mid wuxuu maraa VpnService iyo builder-keeda, kan kalena wuxuu maraa root shell iyo /dev/net/tun. Akhris kasta oo ku yimaada descriptor-kaas waa packet baxa, qoraal kastana waa packet soo gala. Waxa kala sooca dariiqyada waa yaa haya siyaasadda, yaa ka badbaada cusboonaysiinta OS, iyo inta ay ka mid ah shaxda dariiqa aad taaban karto.
Qaado dariiqa platform-ka haddii aadan magacaabi karin waxa gaarka ah ee uu diido inuu sameeyo. Diidmadaas badanaa waa TAP, qabashada ka baxsan app-yadaada, ama qaanuunka dariiqa oo framework-ku waligiis ma muujiyo.
Dariiqa platform-ka waxaad ku dhawaaqdaa ujeeddo halkii amar. Waxaad bixisaa ugu yaraan hal cinwaan, dariiqyada aad rabto, server-yada DNS iyo liis app ikhtiyaari ah, ka dib adeegga nidaamka Android wuxuu sameeyaa habaynta mudnaanta leh isagoo isticmaalaya aqoonsigiisa. Weligaas ma barato magaca interface-ka, weliganaas ma soo saarto ioctl-ka abuura, waana taas maalka.
Laba dariiqo oo lagu helo interface IP
Dariiqa root waa cuntada hore. Waxaad furtaa /dev/net/tun, waxaad wacdaa TUNSETIFF oo la socda IFF_TUN, waxaad kor u qaaddaa interface-ka ip link, oo waxaad gacanta ku darsataa cinwaanno iyo dariiqyo. Tallaabo kasta adigaa leh inaad si sax ah u sameyso, oo ay ku jiraan kuwa framework-ku si aamusan u maareyn lahaa. Hal dariiqo oo maqan waxay isticmaalaha siinaysaa warbixin la mid ah server dhintay.
Debug-ku wuu kala duwan yahay sida habaynta. Dariiqa root interface-ku wuu jiraa ama ioctl-kaagu wuxuu soo celiyay khalad aad si toos ah u akhridi karto. Dariiqa platform-ka interface-ku wuxuu jiraa kaliya ka dib marka establish() guuleysto, sidaas darteed guuldarradu waxay u timaaddaa sida exception ama descriptor null halkii ay ahaan lahayd noodhka qalabka aad ku dhex dabaalan karto.
Waxa establish() dhab ahaan soo celiyo
Builder.establish() wuxuu leeyahay saddex natiijo oo mid kastaa wuxuu u baahan yahay jawaab ka duwan. Descriptor waxay ka dhigan tahay interface-ka waa la habeeyay waana adiga aad isticmaalayso, null waxay ka dhigan tahay codsiga ma gudbin, exception la tuuray waxay ka dhigan tahay adeegga nidaamku wuu diiday. Ku darista null iyo guusha hal boolean waa habka ugu caansan ee app uga warbixiso tunnel shaqeeya oo waligiis qaadin packet. Tixraaca Builder wuxuu sheegayaa shuruudda cinwaanka, waana mudan in la akhriyo ka hor inta aadan server-ka eedayn.
Jihada waxaa go'aamiya descriptor-ka, ma aha protocol-kaaga. Akhrisku wuxuu ku siinayaa packet-yo baxa oo hore loogu doortay VPN, qoraalkuna wuxuu soo celiyaa packet-yo soo gala interface-ka. Gaadiidkaaga u gaar ah ayaa sirteeya, xaqiijiya oo frame-gareeya packet-yadaas, maxaa yeelay platform-ku wuxuu joogsadaa xadka packet-ka.
Binder waa hal boodid, JNI waa dhidib kale
Codsi builder wuxuu nidaamka uga gudbaa Binder, meel hoostiisana platform-ku wuxuu u yeedhaa kood native si uu qalabka u habeeysto. Kuwani waa laba hab oo kala duwan oo hal wicitaan lagu ururiyay. Binder waa isgaarsiin udhaxeysa hababka udhaxeysa app-kaaga iyo adeegga nidaamka, halka JNI uu yahay buundada Java ilaa native gudaha hab. Akhrinta geedka AOSP ee Android 9 waxay ka dhigtaa stack-ka mid macne ahaan cad, waana mudan in la xusuusto magacyada fasallada gudaha iyo dariiqyada faylasha ay u guuraan daabacadaha dhexdooda.
Waxa aan guurin waa heshiiska aad ku tiirsanaan karto: builder-ka, descriptor-ka uu soo celiyo, iyo wareegga nolosha adeegga ku wareegsan. App ma aha inuu wacdo macaamil adeeg gudaha ama uu dib u abuuro noodh qalab si uu interface u helo. Haddii koodkaagu ku tiirsan yahay magaca fasalka AOSP, wuu jabayaa daabacaad aadan tijaabin.
TUN waxa uu qaadaa IP, TAP waxa uu qaadaa Ethernet
TUN waa interface IP. TAP waa interface Ethernet, farqigaasuna wuxuu go'aamiyaa in buundooyinku suurtagal yihiin. Qalabka TUN ma laha cinwaan MAC iyo ma laha madaxa Ethernet uu gudbiyo, sidaas darteed macmiilka TUN kama qaybgalin karo buundada lakabka 2, sida loo qoray dariiqyada.
VpnService wuxuu ku siinayaa nooca IP, kaas oo VPN heerka app u baahan yahay oo uu taageeri karo isagoon haysan stack Ethernet cayriin. Haddii naqshaddaadu u baahan tahay buundo, dariiqa platform-ka halkaas kuma geeynayo, dariiqa root-na wuxuu ku geeynayaa kaliya haddii kernel-ka iyo oggolaanshaha qalabka ay wada shaqeeyaan.
Halka dariiqa root wali ku guuleysto
Saddex shaqo ayaa dadka ka riixda dariiqa platform-ka. Buundada lakabka 2 waxay u baahan tahay TAP. Qabashada taraafikada app-yada ka baxsan baaxaddaada VPN waxay u baahan tahay arag aysan framework-ku bixin. Dariiqa siyaasadda ee builder-ku waligiis ma muujiyo, sida shax gaar ah oo loogu talagalay hal meel, wuxuu u baahan yahay xeerar aad adigu rakibto.
Kharashaadka ayaa dambe yimaada: bootloader furan ama image root ah, siyaasadda SELinux oo ka hoos guurta, iyo qalab joojiya inuu si fiican u dhaqmo OTA ka dib. Cuntada root ah sidoo kale laguma qaybin karo qaybinta app caadiga ah, sidaas darteed kooxaha badankood waxay u hayaan dariiq ogaal gudaha ah halkii ay ka ahaan lahaayeen badeeco.
Doorashada labadooda dhexdooda
Ka bilow interface-ka aad u baahan tahay, ma aha koodka aad haysato. Haddii jawaabtu tahay qalab TUN oo leh dariiqyo ku xaddidan app-ka, dariiqa platform-ka ayaa gaaban oo ka badbaada cusboonaysiinta. Haddii jawaabtu ay ku jirto frame-yo Ethernet, qabashada app-yada kale, ama xeerar dariiqa builder-ku diido, waxaad ku sugan tahay dhulka root waana inaad u miisaaniyeyso kharash hawlgal.
Hubin xallisa doodaha badankood: marka hore dhis dariiqa platform-ka, diiwaangeli natiijada establish() si ka duwan xaaladda fadhiyada fog, oo xaqiiji hal packet jiho kasta. Markaas ka dib go'aanso in awoodda maqan ay caddaynayso in laga tago dariiqa la taageeray.