VPN u chrootu na Androidu: zašto tunel radi, a aplikacije ga ignoriraju
chroot mijenja razrješavanje putanja, ne jezgru, mrežni prostor imena ni registraciju VPN-a na Androidu. Iz toga slijede dva ishoda i oba iznenađuju.
Instaliraš Linux distribuciju u chrootu na telefonu, staviš VPN klijent unutra i shell objavi da je tunel uspostavljen. Zatim prijeđeš na preglednik i promet izlazi preko mobilnih podataka kao da se ništa nije dogodilo. Ili obrnuto: svaka aplikacija izgubi vezu jer je klijent dodao zadanu rutu u prostor imena koji Android stvarno koristi. Ta dva simptoma dolaze iz istog dijela koji nedostaje i nijedan nije greška VPN klijenta.
Shell kaže povezano, aplikacije se ne slažu
Prvi ishod je uobičajen. Tunel u korisničkom prostoru otvoren iz chroota može dovršiti rukovanje, ispisati statistiku i prenositi promet koji stvara isti shell, dok Androidove aplikacije nastavljaju koristiti zadanu mrežu telefona. Ništa ih ne presreće jer ništa nije reklo Androidu da VPN postoji.
Drugi ishod je opasan. Ako chroot dijeli Androidov mrežni prostor imena, što je zadano, proces s dovoljno privilegija može dodati rute i TUN sučelje koji utječu na cijeli telefon. Tada tunel radi za svaku aplikaciju, uključujući one koje nisi namjeravao usmjeriti, a veza telefona sada ovisi o demonu bez upravljanja životnim ciklusom, bez pokazatelja veze i bez politike stalne uključenosti.
Koji si od dva ishoda dobio može se odgovoriti jednom naredbom. Usporedi ip route unutar chroota s istom naredbom iz Androidova shella izvana. Identičan izlaz znači da je chroot u prostoru imena domaćina: svaka mrežna promjena koju napravi vrijedi za cijeli telefon. Različit izlaz znači da je pokretač stvorio zaseban prostor imena za njega i njegov je tunel po konstrukciji nevidljiv Androidu.
Što je chroot promijenio, a što nije
| 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 |
Sistemski poziv chroot radi jednu stvar: mijenja direktorij koji se koristi za razrješavanje putanja. Stranica priručnika izričito kaže da to nije sigurnosna granica i ne govori ništa o sučeljima, rutama ni stanju VPN-a. Sve što ljudi očekuju od Linux kontejnera — zaseban mrežni stog, filtriran datotečni sustav, ograničenja resursa — dolazi iz drugih mehanizama koje je pokretač možda upotrijebio, a možda i nije.
Zato tvrdnje da chroot izolira VPN obično odgovaraju na pogrešno pitanje. Relevantno je pitanje u kojem prostoru imena proces radi i u kojem je SELinux domenu ograničen, a oboje su svojstva toga kako je pokrenut, ne riječi chroot.
TUN treba tri stvari, a čvor uređaja je samo jedna
Tradicionalni tunel u korisničkom prostoru treba TUN uređaj koji može otvoriti, podršku jezgre za taj uređaj i dopuštenje za konfiguriranje sučelja i ruta. To su odvojeni zahtjevi i stvaranje imena putanje pod /dev samo po sebi ne zadovoljava nijedan od njih:
ls -l /dev/net/tun
ip tuntap add dev tun0 mode tun
Na Androidu je podrška za TUN obično ugrađena u jezgru jer je koristi vlastita VPN usluga platforme, no to ne znači da je tvoj proces smije koristiti. Konfiguracija sučelja zahtijeva sposobnost administracije mreže, a SELinux odlučuje smije li proces uopće doći do čvora uređaja. Odbijanje izgleda kao pogreška dopuštenja bez očitog uzroka, a odgovor je u revizijskom tragu:
dmesg | grep avc
logcat -d | grep "avc: denied"
Root to ne rješava. SELinux ograničava procese s uid 0 jednako kao i ostale, pa chroot pokrenut iz root shella može dobiti odbijenicu za uređaj koji vidi. Isključivanje provedbe da bi stari instalater proradio odluka je za cijeli telefon s posljedicama daleko izvan tunela i nije popravak zastarjele binarne datoteke.
Zašto Androidove aplikacije ignoriraju tvoj tunel
Podržani Androidov model je VPN aplikacija koja se registrira preko VPN usluge platforme, jednom zatraži pristanak korisnika i dobije datotečni deskriptor za svoj tunel. Platforma zatim usmjerava promet u taj deskriptor i provodi opseg aplikacija koji je odabrao korisnik ili administrator, zato isti mehanizam može biti po aplikaciji, po profilu i kombiniran s postavkama stalne uključenosti i blokiranja bez VPN-a. Androidov vodič za razvoj VPN-a opisuje to rukovanje i ključno je da je to registracija, a ne trik s usmjeravanjem.
Demon unutar chroota nikada se ne registrira. Nema dijaloga za pristanak, nema ikone ključa u statusnoj traci, nema popisa uključivanja ni isključivanja po aplikacijama i nema sudjelovanja u politici stalne uključenosti. Aplikacije zato nastavljaju koristiti zadanu mrežu, a tunel prenosi samo ono što sam shell šalje.
Ni suprotni smjer ne pomaže. Guranje ruta u prostor imena domaćina hvata sve, uključujući promet koji je platforma očekivala zadržati lokalnim, i to čini bez kontrole po aplikacijama i bez načina da korisnik to vidi ili opozove. Nema srednje postavke u kojoj demon u chrootu usmjerava promet samo jedne aplikacije.
Binarska kompatibilnost je zaseban zid
Čak i kad je mrežna strana zanimljiva, izvršna datoteka ima svoje zahtjeve: arhitekturu procesora, dinamički učitavač, C biblioteku i mogućnosti jezgre koje očekuje. Android koristi bionic, a ne glibc, a stara binarna datoteka izgrađena za stolnu distribuciju može trebati biblioteke kojih više nema na uređaju.
Povezivanje imena bibliotečne datoteke s novijom verzijom ne stvara ABI kompatibilnost, a arhivirana kriptografska biblioteka iz paketa starog desetljeće nije održavana komponenta. Ako plan ovisi o tome, plan je pokretati neodržavani kod s mrežnim privilegijama na telefonu.
Dokaži to u Androidovu kontekstu i počisti za sobom
Testiraj ono što te stvarno zanima, sa strane koja je bitna: otvori određenu aplikaciju, dođi do određenog privatnog odredišta, potvrdi koji je razrješivač odgovorio, zatim prekini tunel i potvrdi dokumentirano ponašanje. Rezultat iz terminala unutar chroota dokaz je o kontekstu izvršavanja tog terminala i ništa više.
Ako si tijekom eksperimenta promijenio rute domaćina, vrati ih i zabilježi što si promijenio. Zatim provjeri ima li telefon postavljen VPN sa stalnom uključenošću, jer stari eksperiment koji je ostavio pravilo može se mjesecima kasnije činiti kao kvar platforme.
Za stvarnu potrebu za daljinskim pristupom upotrijebi podržani klijent usluge ili odobren dizajn pristupnika. Pitanje koje vrijedi postaviti nije može li se instalater s rootom natjerati da radi, nego prenosi li podržana implementacija aplikacije koje trebaš preko granice koju si namjeravao, bez ostavljanja privilegiranih promjena bez vlasnika na uređaju.