Android chroot VPN: hvorfor tunnelen virker mens appene ser bort fra den
Chroot forandrer bare hvordan stier slås opp, ikke kjernen, nettverksnavnerommet eller VPN-registreringen i Android. Det gir to mulige utfall, og begge forundrer folk.
Du får en Linux-distribusjon til å kjøre under chroot på mobilen, legger inn en VPN-klient i den, og skallet sier at tunnelen er oppe. Så åpner du nettleseren, og trafikken går ut over mobilnettet som om ingenting hadde skjedd. Eller motsatt: alle apper på mobilen mister forbindelsen fordi klienten la en standardrute i det navnerommet Android faktisk bruker. De to symptomene stammer fra samme hull, og ingen av dem er en feil i VPN-klienten.
Skallet sier tilkoblet, appene er uenige
Det første utfallet er det normale. En tunnel i brukerrommet som åpnes fra chroot, kan fullføre forhandlingen, skrive ut statistikk og bære trafikk som samme skallet lager, mens Android-appene fortsetter å bruke mobilens standardnett. Ingenting fanger dem opp, for ingenting har fortalt Android at det finnes en VPN.
Det andre utfallet er det farlige. Dersom chroot deler nettverksnavnerommet til Android, noe den gjør som standard, kan en prosess med nok rettigheter legge til ruter og et TUN-grensesnitt som gjelder hele mobilen. Da virker tunnelen for alle apper, også dem du ikke hadde tenkt å sende gjennom den, og mobilens forbindelse henger nå på en tjeneste uten livssyklusstyring, uten tilkoblingsindikator og uten alltid-på-regel.
Hvilket av de to du endte med, kan avgjøres med én kommando. Sammenlign ip route inne i chroot med samme kommando fra et Android-skal utenfor. Lik utskrift betyr at chroot ligger i vertens navnerom: enhver nettverksendring den gjør, gjelder hele mobilen. Forskjellig utskrift betyr at oppstarteren laget et eget navnerom for den, og at tunnelen er usynlig for Android i kraft av konstruksjonen.
Hva chroot forandret og hva den lot være
| 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 |
Systemkallet chroot gjør én ting: det bytter katalogen som brukes når stier skal slås opp. Man-siden sier rett ut at dette ikke er noen sikkerhetsgrense, og den nevner ingenting om grensesnitt, ruter eller VPN-tilstand. Alt folk forventer av en Linux-container — egen nettverksstakk, filtrert filsystem, ressursgrenser — kommer fra andre mekanismer som oppstarteren kanskje eller kanskje ikke har brukt.
Derfor svarer påstander om at chroot isolerer en VPN som regel på feil spørsmål. Det relevante spørsmålet er hvilket navnerom prosessen ligger i og hvilket SELinux-domene den er bundet til, og begge er egenskaper ved måten den ble startet på, ikke ved ordet chroot.
TUN trenger tre ting, og en enhetsnode er bare én av dem
En tradisjonell tunnel i brukerrommet trenger en TUN-enhet den kan åpne, kjernestøtte for den enheten, og tillatelse til å sette opp grensesnittet og rutene. Dette er tre separate krav, og en sti under /dev oppfyller ikke noe av det av seg selv:
ls -l /dev/net/tun
ip tuntap add dev tun0 mode tun
På Android er TUN-støtte vanligvis kompilert inn i kjernen, siden plattformens egen VPN-tjeneste bruker den, men det betyr ikke at din prosess får bruke den. Oppsett av grensesnitt krever nettverksadministrasjonsrettighet, og SELinux bestemmer om prosessen i det hele tatt får nå enhetsnoden. En avvisning ser ut som en tilgangsfeil uten synlig årsak, og svaret ligger i revisjonssporet:
dmesg | grep avc
logcat -d | grep "avc: denied"
Root løser ikke dette. SELinux begrenser prosesser som kjører som uid 0 på samme måte som alle andre, så en chroot startet fra et root-skal kan fortsatt bli nektet en enhet den ser. Å skru av håndhevingen for å få en gammel installasjonspakke til å gå er en avgjørelse for hele mobilen med virkninger langt utenfor tunnelen, og det er ingen reparasjon av en utdatert binærfil.
Hvorfor Android-apper ser bort fra tunnelen din
Androids støttede modell er en VPN-app som registrerer seg gjennom plattformens VPN-tjeneste, spør brukeren om samtykke én gang og får en fildeskriptor for tunnelen sin. Plattformen sender deretter trafikken inn i den deskriptoren og håndhever appomfanget som brukeren eller administratoren valgte, og derfor kan samme mekanisme være per app, per profil og kombineres med alltid-på og blokker-uten-VPN. Veiledningen for VPN-utvikling på Android beskriver denne forhandlingen, og hovedpoenget er at det er en registrering, ikke et rutetriks.
En tjeneste inne i chroot registrerer seg aldri. Det finnes ingen samtykkedialog, ingen nøkkel i statuslinjen, ingen liste over hvilke apper som skal med eller holdes utenfor, og ingen deltakelse i alltid-på-regelen. Appene bruker derfor fortsatt standardnettet, og tunnelen bærer bare det skallet selv sender.
Motsatt vei hjelper heller ikke. Å presse ruter inn i vertens navnerom fanger opp alt, også trafikk plattformen regnet med å holde lokalt, og det skjer uten styring per app og uten at brukeren kan se eller trekke det tilbake. Det finnes ingen mellomløsning der en chroot-tjeneste ruter trafikk for bare én app.
Binærkompatibilitet er en egen mur
Selv når nettsiden av saken er interessant, stiller den kjørbare filen egne krav: prosessorarkitektur, den dynamiske linkeren, C-biblioteket og kjernefunksjonene den forutsetter. Android bruker bionic og ikke glibc, og en gammel binærfil bygget for en skrivebordsdistribusjon kan trenge biblioteker som ikke finnes på enheten lenger.
Å peke et biblioteknavn symbolsk til en nyere versjon gir ingen ABI-kompatibilitet, og et arkivert kryptobibliotek fra en pakke som er ti år gammel er ikke en vedlikeholdt komponent. Henger planen på dette, er planen å kjøre uvedlikeholdt kode med nettverksrettigheter på en mobil.
Bevis det i Android-sammenheng og rydd opp etterpå
Test det du faktisk bryr deg om, fra den siden som betyr noe: åpne den aktuelle appen, nå den aktuelle private adressen, bekreft hvilken resolver som svarte, koble så fra tunnelen og bekreft oppførselen dokumentasjonen lover. Et resultat fra en terminal inne i chroot sier bare noe om den terminalens kjøremiljø, og ingenting mer.
Hvis du endret ruter på verten mens du prøvde deg fram, sett dem tilbake og skriv ned hva du endret. Sjekk så om mobilen har en alltid-på-VPN satt opp, for et eldre forsøk som ble liggende igjen med en regel kan se ut som en plattformfeil mange måneder senere.
Trenger du ekte fjernaksess, bruk tjenestens støttede klient eller en godkjent gateway-løsning. Spørsmålet det er verdt å stille, er ikke om en rootet installasjonspakke kan fås til å kjøre, men om en støttet løsning bærer appene du trenger over den grensen du mente, uten å etterlate eierløse privilegerte endringer på enheten.