Android chroot VPN: kodėl tunelis veikia, o programos jo nepaiso
Chroot pakeičia tik kelių paiešką, o ne branduolį, tinklo vardų erdvę ar Android VPN registraciją. Iš to kyla du padariniai, ir abu nustebina žmones.
Telefone po chroot paleidžiate Linux distribuciją, įdiegiate jame VPN klientą, ir apvalkalas paskelbia, kad tunelis užbaigtas. Tada persijungiate į naršyklę, o srautas išvyksta per mobiliojo ryšio duomenis taip, tarsi nieko nebūtų nutikę. Arba atvirkščiai: kiekviena telefono programa praranda ryšį, nes klientas įdiegė numatytąjį maršrutą vardų erdvėje, kurią Android iš tikrųjų naudoja. Abu šie simptomai kyla iš to paties trūkstamo elemento, ir nė vienas jų nėra VPN kliento klaida.
Apvalkalas sako prisijungęs, programos nesutinka
Pirmasis rezultatas yra įprastas. Iš chroot atidarytas vartotojo erdvės tunelis gali užbaigti savo rankos paspaudimą, atspausdinti statistiką ir perduoti srautą, kurį generuoja tas pats apvalkalas, o Android programos toliau naudoja numatytąjį telefono tinklą. Niekas jų neperima, nes niekas nepranešė Android, kad VPN egzistuoja.
Antrasis rezultatas yra pavojingas. Jei chroot dalijasi Android tinklo vardų erdve, o pagal numatytuosius nustatymus taip ir yra, pakankamai privilegijų turintis procesas gali pridėti maršrutus ir TUN sąsają, kurie paveikia visą telefoną. Tada tunelis veikia kiekvienai programai, įskaitant tas, kurių nesirengėte maršrutizuoti, o telefono ryšys dabar priklauso nuo tarnybos, kuri neturi gyvavimo ciklo valdymo, ryšio indikatoriaus ir nuolatinio prisijungimo politikos.
Kurį variantą gavote, galima nustatyti viena komanda. Palyginkite ip route chroot viduje su ta pačia komanda Android apvalkale už jo ribų. Identiška išvestis reiškia, kad chroot yra pagrindinės sistemos vardų erdvėje: bet koks jo atliktas tinklo pakeitimas galioja visam telefonui. Besiskirianti išvestis reiškia, kad paleidiklis jam sukūrė vardų erdvę, ir jo tunelis Android yra nematomas iš prigimties.
Ką chroot pakeitė, o ko ne
| Object | Effect of a chroot |
|---|---|
| Pathname resolution | Changed: lookups start at the new root |
| Kernel and drivers | Unchanged: the phone's kernel, its TUN driver, its limits |
| Network namespace | Unchanged unless the launcher creates one |
| Android VPN registration | Unchanged: no app consented, no VPN is selected |
Chroot sistemos iškvietimas daro vieną dalyką: pakeičia katalogą, naudojamą kelio vardams skaidyti. Vadovo puslapis aiškiai sako, kad tai nėra saugumo riba, ir nieko nekalba apie sąsajas, maršrutus ar VPN būseną. Viskas, ko žmonės tikisi iš Linux konteinerio – privatus tinklo kamienas, filtruota failų sistema, išteklių ribos – kyla iš kitų mechanizmų, kuriuos paleidiklis galėjo naudoti arba ne.
Štai kodėl teiginiai, kad chroot izoliuoja VPN, paprastai atsako į netinkamą klausimą. Svarbus klausimas yra, kurioje vardų erdvėje procesas veikia ir kuriam SELinux domenui jis priskirtas, o abu yra jo paleidimo savybės, o ne žodžio chroot savybės.
TUN reikia trijų dalykų, o įrenginio failas yra tik vienas
Tradiciniam vartotojo erdvės tuneliui reikia TUN įrenginio, kurį jis gali atidaryti, branduolio palaikymo tam įrenginiui ir leidimo konfigūruoti sąsają bei maršrutus. Tai atskiri reikalavimai, ir kelio vardo sukūrimas po /dev nė vieno jų savaime nepatenkina:
ls -l /dev/net/tun
ip tuntap add dev tun0 mode tun
Android branduolyje paprastai būna įkompiliuotas TUN palaikymas, nes jį naudoja pačios platformos VPN paslauga, tačiau tai nereiškia, kad jūsų procesas gali juo naudotis. Sąsajos konfigūravimui reikia tinklo administravimo galios, o SELinux sprendžia, ar procesas apskritai gali pasiekti įrenginio failą. Atsisakymas atrodo kaip teisių klaida be akivaizdžios priežasties, o atsakymas yra audito žurnale:
dmesg | grep avc
logcat -d | grep "avc: denied"
Root to neišsprendžia. SELinux riboja procesus, veikiančius kaip uid 0, lygiai taip pat, kaip ir kitus, todėl chroot, paleistas iš root apvalkalo, vis tiek gali netekti įrenginio, kurį mato. Apsaugos vykdymo išjungimas tam, kad veiktų senas diegėjas, yra viso telefono sprendimas, kurio pasekmės siekia daug toliau nei tunelis, ir tai nėra pasenusio dvejetainio failo pataisymas.
Kodėl Android programos nepaiso jūsų tunelio
Palaikomas Android modelis yra VPN programa, kuri registruojasi per platformos VPN paslaugą, vieną kartą paprašo naudotojo sutikimo ir gauna savo tunelio failo deskriptorių. Tada platforma nukreipia srautą į tą deskriptorių ir įgyvendina naudotojo ar administratoriaus pasirinktą programų apimtį, todėl tas pats mechanizmas gali būti atskirai kiekvienai programai, kiekvienam profiliui ir derinamas su nuolatinio prisijungimo bei blokavimo be VPN nustatymais. Android VPN kūrimo vadovas aprašo tą rankos paspaudimą, o esmė ta, kad tai registracija, o ne maršrutizavimo triukas.
Tarnyba chroot viduje niekada nesiregistruoja. Nėra sutikimo dialogo, nėra rakto piktogramos būsenos juostoje, nėra programų įtraukimo ar išskyrimo sąrašo ir jokio dalyvavimo nuolatinio prisijungimo politikoje. Todėl programos toliau naudoja numatytąjį tinklą, o tunelis perduoda tik tai, ką siunčia pats apvalkalas.
Ėjimas kitu keliu taip pat nepadeda. Maršrutų stūmimas į pagrindinės sistemos vardų erdvę paima viską, įskaitant srautą, kurį platforma tikėjosi palikti vietiniu, ir tai daro be jokios atskiros programų kontrolės ir be galimybės naudotojui tai pamatyti ar atšaukti. Nėra jokio tarpinio nustatymo, kai chroot tarnyba maršrutizuoja srautą tik vienai programai.
Dvejetainių failų suderinamumas yra atskira siena
Net kai tinklo pusė įdomi, vykdomasis failas turi savo reikalavimus: CPU architektūrą, dinaminį įkėlėją, C biblioteką ir branduolio priemones, kurių jis tikisi. Android naudoja bionic, o ne glibc, ir senas dvejetainis failas, sukurtas darbalaukio distribucijai, gali reikalauti bibliotekų, kurių įrenginyje nebėra.
Bibliotekos failo vardo susiejimas su naujesne versija nesukuria ABI suderinamumo, o archyvuota kriptografinė biblioteka iš prieš dešimtmetį sukurto paketo nėra prižiūrimas komponentas. Jei planas tuo remiasi, planas yra vykdyti nepriežiūrimą kodą su tinklo privilegijomis telefone.
Įrodykite tai Android kontekste ir po to sutvarkykite
Bandykite tai, kas jums iš tikrųjų svarbu, iš tos pusės, kuri svarbi: atidarykite konkrečią programą, pasiekite konkretų privatų tikslą, patvirtinkite, kuris sprendėjas atsakė, tada atjunkite tunelį ir patvirtinkite dokumentuotą elgesį. Rezultatas iš terminalo chroot viduje yra įrodymas tik apie to terminalo vykdymo kontekstą ir nieko daugiau.
Jei eksperimentuodami keitėte pagrindinės sistemos maršrutus, grąžinkite juos ir užsirašykite, ką pakeitėte. Tada patikrinkite, ar telefone sukonfigūruotas nuolatinis VPN, nes senas eksperimentas, palikęs taisyklę, po kelių mėnesių gali atrodyti kaip platformos gedimas.
Jei tikrai reikia nuotolinės prieigos, naudokite palaikomą paslaugos klientą arba patvirtintą šliuzo projektą. Vertas klausimas yra ne tai, ar įsišaknijusį diegėją galima priversti veikti, o tai, ar palaikoma realizacija perkelia reikiamas programas per numatytą ribą, nepalikdama įrenginyje niekam nepriklausančių privilegijuotų pakeitimų.