VPN v chroot na Androidu: proč tunel funguje a aplikace ho ignorují
chroot mění rozlišování cest, ne jádro, síťový jmenný prostor ani registraci VPN v Androidu. Z toho plynou dva výsledky a oba lidi překvapí.
Nainstalujete na telefon distribuci Linuxu běžící v chroot, dáte dovnitř klienta VPN a shell oznámí dokončený tunel. Pak přepnete do prohlížeče a provoz odchází přes mobilní data, jako by se nic nestalo. Nebo naopak: všechny aplikace v telefonu ztratí připojení, protože klient přidal výchozí trasu do jmenného prostoru, který Android skutečně používá. Oba tyto příznaky pocházejí ze stejného chybějícího dílku a ani jeden není chyba klienta VPN.
Shell říká připojeno, aplikace nesouhlasí
První výsledek je ten obvyklý. Tunel v uživatelském prostoru otevřený z chroot může dokončit handshake, vytisknout statistiky a přenášet provoz, který generuje tentýž shell, zatímco aplikace Androidu dál používají výchozí síť telefonu. Nic je nezachycuje, protože nic neřeklo Androidu, že VPN existuje.
Druhý výsledek je nebezpečný. Pokud chroot sdílí síťový jmenný prostor Androidu, což je výchozí stav, proces s dostatkem oprávnění může přidat trasy a rozhraní TUN, které ovlivní celý telefon. Pak tunel funguje pro každou aplikaci, včetně těch, které jste směrovat nechtěli, a připojení telefonu teď závisí na démonu bez správy životního cyklu, bez indikátoru připojení a bez zásady trvalého zapnutí.
Který ze dvou výsledků jste dostali, se dá zjistit jediným příkazem. Porovnejte ip route uvnitř chroot s týmž příkazem ze shellu Androidu venku. Stejný výstup znamená, že chroot je v jmenném prostoru hostitele: každá síťová změna, kterou provede, platí pro celý telefon. Odlišný výstup znamená, že pro něj spouštěč vytvořil jmenný prostor a jeho tunel je konstrukčně pro Android neviditelný.
Co chroot změnil a co 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 |
Systémové volání chroot dělá jednu věc: mění adresář používaný k rozlišování cest. Manuálová stránka výslovně říká, že to není bezpečnostní hranice, a neříká nic o rozhraních, trasách ani stavu VPN. Vše, co lidé od kontejneru Linuxu očekávají — soukromý síťový zásobník, filtrovaný souborový systém, limity prostředků — pochází z jiných mechanismů, které spouštěč mohl a nemusel použít.
Proto tvrzení, že chroot izoluje VPN, obvykle odpovídají na špatnou otázku. Podstatná otázka je, ve kterém jmenném prostoru proces běží a do které domény SELinux je uzavřen, a obojí je vlastnost toho, jak byl spuštěn, ne slova chroot.
TUN potřebuje tři věci a uzel zařízení je jen jedna
Tradiční tunel v uživatelském prostoru potřebuje zařízení TUN, které může otevřít, podporu tohoto zařízení v jádře a oprávnění nakonfigurovat rozhraní a trasy. To jsou oddělené požadavky a vytvoření názvu cesty pod /dev samo o sobě nesplní ani jeden z nich:
ls -l /dev/net/tun
ip tuntap add dev tun0 mode tun
V Androidu bývá podpora TUN zkompilovaná v jádře, protože ji používá vlastní služba VPN platformy, ale to neznamená, že ji váš proces smí použít. Konfigurace rozhraní vyžaduje schopnost správy sítě a SELinux rozhoduje, zda se proces vůbec dostane k uzlu zařízení. Odmítnutí vypadá jako chyba oprávnění bez zjevné příčiny a odpověď je v auditní stopě:
dmesg | grep avc
logcat -d | grep "avc: denied"
Root to neřeší. SELinux omezuje procesy s uid 0 stejně jako ostatní, takže chroot spuštěný z root shellu může být odmítnut u zařízení, které vidí. Vypnutí vynucování, aby fungoval starý instalátor, je rozhodnutí pro celý telefon s následky daleko za tunelem a není opravou zastaralého binárního souboru.
Proč aplikace Androidu váš tunel ignorují
Podporovaný model Androidu je aplikace VPN, která se zaregistruje u služby VPN platformy, jednou požádá uživatele o souhlas a dostane deskriptor souboru pro svůj tunel. Platforma pak směruje provoz do tohoto deskriptoru a vynucuje rozsah aplikací, který zvolil uživatel nebo správce, proto tentýž mechanismus může být pro aplikaci, pro profil a kombinovaný s trvalým zapnutím a blokováním bez VPN. Průvodce vývojem VPN pro Android tento handshake popisuje a klíčové je, že jde o registraci, ne o směrovací trik.
Démon uvnitř chroot se nikdy nezaregistruje. Není dialog souhlasu, žádná ikona klíče ve stavovém řádku, žádný seznam zahrnutí či vyloučení podle aplikací a žádná účast v zásadě trvalého zapnutí. Aplikace proto dál používají výchozí síť a tunel nese jen to, co pošle sám shell.
Ani opačný směr nepomáhá. Protlačení tras do jmenného prostoru hostitele zachytí všechno, včetně provozu, který platforma očekávala ponechat lokálně, a dělá to bez řízení po aplikacích a bez možnosti uživatele to vidět nebo zrušit. Neexistuje střední nastavení, kde démon v chroot směruje provoz jen jedné aplikace.
Binární kompatibilita je samostatná zeď
I když je síťová stránka zajímavá, spustitelný soubor má své požadavky: architekturu procesoru, dynamický zavaděč, knihovnu C a možnosti jádra, které očekává. Android používá bionic, ne glibc, a starý binární soubor sestavený pro desktopovou distribuci může potřebovat knihovny, které na zařízení už nejsou.
Propojení názvu knihovny s novější verzí nevytváří kompatibilitu ABI a archivovaná kryptografická knihovna z deset let starého balíčku není udržovaná komponenta. Pokud na tom plán závisí, plán znamená spouštět neudržovaný kód se síťovými oprávněními v telefonu.
Dokažte to v kontextu Androidu a pak ukliďte
Testujte to, na čem vám skutečně záleží, ze strany, která je důležitá: otevřete konkrétní aplikaci, dosáhněte konkrétního soukromého cíle, ověřte, který resolver odpověděl, pak tunel odpojte a ověřte dokumentované chování. Výsledek z terminálu uvnitř chroot je důkaz o kontextu provádění tohoto terminálu a nic víc.
Pokud jste během experimentu změnili trasy hostitele, vraťte je a zapište, co jste změnili. Pak zkontrolujte, zda má telefon nastavenou VPN s trvalým zapnutím, protože starý experiment, který nechal pravidlo, může po měsících vypadat jako závada platformy.
Pro skutečnou potřebu vzdáleného přístupu použijte podporovaného klienta služby nebo schválený návrh brány. Otázka, která stojí za to, není, zda lze rozchodit instalátor s rootem, ale zda podporovaná implementace přenese aplikace, které potřebujete, přes zamýšlenou hranici, aniž by na zařízení nechala privilegované změny bez vlastníka.