Du får en Linux-distribution att köra under chroot på telefonen, installerar en VPN-klient i den, och skalet meddelar att tunneln är klar. Sedan byter du till webbläsaren och trafiken går ut över mobildata som om ingenting hade hänt. Eller tvärtom: varje app på telefonen tappar anslutningen eftersom klienten la in en standardrutt i den namnrymd Android faktiskt använder. Båda symptomen kommer från samma sak som saknas, och ingen av dem är en bugg i VPN-klienten.

Skalet säger ansluten, apparna håller inte med

Det första utfallet är det vanliga. En tunnel i användarrymden som öppnas från chroot kan slutföra handskakningen, skriva ut statistik och bära trafik som samma skal genererar, medan Androids appar fortsätter använda telefonens standardnätverk. Inget fångar upp dem, eftersom inget har berättat för Android att det finns en VPN.

Det andra utfallet är det farliga. Om chroot delar Androids nätverksnamnrymd, vilket den gör som standard, kan en process med tillräckliga privilegier lägga till rutter och ett TUN-gränssnitt som påverkar hela telefonen. Då fungerar tunneln för varje app, även de du inte tänkt routa, och telefonens anslutning beror nu på en tjänst utan livscykelhantering, utan anslutningsindikator och utan alltid-på-policy.

Vilket av de två du fick går att avgöra med ett enda kommando. Jämför ip route inne i chroot med samma kommando från ett Android-skal utanför. Identisk utdata betyder att chroot är i värdens namnrymd: varje nätverksändring den gör gäller hela telefonen. Annan utdata betyder att startaren skapade en namnrymd åt den, och att dess tunnel är osynlig för Android av konstruktionen.

Vad chroot ändrade och vad den inte ändrade

ObjectEffect of a chroot
Pathname resolutionChanged: lookups start at the new root
Kernel and driversUnchanged: the phone's kernel, its TUN driver, its limits
Network namespaceUnchanged unless the launcher creates one
Android VPN registrationUnchanged: no app consented, no VPN is selected

Systemanropet chroot gör en sak: det byter den katalog som används för att slå upp sökvägsnamn. Man-sidan säger uttryckligen att det inte är en säkerhetsgräns, och den säger ingenting om gränssnitt, rutter eller VPN-status. Allt folk förväntar sig av en Linux-container — en privat nätverksstack, ett filtrerat filsystem, resursgränser — kommer från andra mekanismer som startaren kan eller inte kan ha använt.

Därför svarar påståenden om att chroot isolerar en VPN oftast på fel fråga. Den relevanta frågan är vilken namnrymd processen kör i och vilken SELinux-domän den är begränsad till, och båda är egenskaper hos hur den startades, inte hos ordet chroot.

TUN behöver tre saker, och en enhetsnod är bara en

En traditionell tunnel i användarrymden behöver en TUN-enhet den kan öppna, kärnstöd för den enheten och tillstånd att konfigurera gränssnittet och rutterna. Det är separata krav, och att skapa ett sökvägsnamn under /dev uppfyller inget av dem i sig:

ls -l /dev/net/tun
ip tuntap add dev tun0 mode tun

På Android har kärnan oftast TUN-stöd inkompilerat, eftersom plattformens egen VPN-tjänst använder det, men det betyder inte att din process får använda det. Gränssnittskonfiguration kräver nätverksadministrationsbehörighet, och SELinux avgör om processen alls får nå enhetsnoden. En avvisning ser ut som ett behörighetsfel utan uppenbar orsak, och svaret finns i granskningsloggen:

dmesg | grep avc
logcat -d | grep "avc: denied"

Root löser inte detta. SELinux begränsar processer som kör som uid 0 precis som andra, så en chroot som startats från ett root-skal kan fortfarande nekas en enhet den ser. Att stänga av verkställandet för att få en gammal installationsprogram att fungera är ett beslut för hela telefonen med konsekvenser långt utanför tunneln, och det är ingen lagning av en föråldrad binärfil.

Varför Android-appar ignorerar din tunnel

Androids stödda modell är en VPN-app som registrerar sig via plattformens VPN-tjänst, frågar användaren om samtycke en gång och får en fildeskriptor för sin tunnel. Plattformen dirigerar sedan trafiken in i den deskriptorn och verkställer appomfattningen som användaren eller administratören valde, vilket är varför samma mekanism kan vara per app, per profil och kombineras med alltid-på och blockera-utan-VPN. Androids utvecklarhandbok för VPN beskriver den handskakningen, och poängen är att det är en registrering, inte ett routingtrick.

En tjänst inne i chroot registrerar sig aldrig. Det finns ingen samtyckesdialog, ingen nyckelikon i statusfältet, ingen lista för att ta med eller undanta appar, och inget deltagande i alltid-på-policyn. Apparna fortsätter därför använda standardnätverket, och tunneln bär bara det skalet självt skickar.

Andra hållet hjälper inte heller. Att trycka in rutter i värdens namnrymd fångar allt, inklusive trafik plattformen väntade sig hålla lokal, och det görs utan kontroll per app och utan att användaren kan se eller återkalla det. Det finns ingen mellaninställning där en chroot-tjänst routar trafik för bara en app.

Binärkompatibilitet är en egen mur

Även när nätverkssidan är intressant har den körbara filen egna krav: CPU-arkitektur, den dynamiska lastaren, C-biblioteket och de kärnfunktioner den förväntar sig. Android använder bionic i stället för glibc, och en gammal binärfil byggd för en skrivbordsdistribution kan behöva bibliotek som inte längre finns på enheten.

Att symboliskt länka ett biblioteksfilnamn till en nyare version skapar ingen ABI-kompatibilitet, och ett arkiverat kryptobibliotek från ett tio år gammalt paket är inte en underhållen komponent. Om planen hänger på det är planen att köra icke-underhållen kod med nätverksprivilegier på en telefon.

Bevisa det i Android-sammanhang och städa efteråt

Testa det du faktiskt bryr dig om, från den sida som betyder något: öppna den specifika appen, nå den specifika privata destinationen, bekräfta vilken resolver som svarade, koppla sedan från tunneln och bekräfta det dokumenterade beteendet. Ett resultat från en terminal inne i chroot är bevis om just den terminalens körmiljö och ingenting mer.

Om du ändrade värdrutter under experimenten, återställ dem och skriv ned vad du ändrade. Kontrollera sedan om telefonen har en alltid-på-VPN konfigurerad, för ett äldre experiment som lämnade en regel kvar kan se ut som ett plattformsfel månader senare.

För ett verkligt behov av fjärråtkomst, använd tjänstens stödda klient eller en godkänd gateway-design. Frågan som är värd att ställa är inte om ett rootat installationsprogram kan fås att köra, utan om en stödd implementering bär de appar du behöver över den gräns du avsåg, utan att lämna ägarlösa privilegierade ändringar på enheten.

Relaterade artiklar