Du får en Linux-distribusjon som kjører under chroot på telefonen, installerer en VPN-klient i den, og skallet melder at tunnelen er ferdig. Så bytter du til en nettleser, og trafikken går ut over mobildata som om ingenting hadde skjedd. Eller det motsatte: hver app på telefonen mister tilkoblingen fordi klienten la inn en standardrute i navnerommet Android faktisk bruker. Begge symptomene kommer fra den samme manglende brikken, og ingen av dem er en feil i VPN-klienten.

Skallet sier tilkoblet, appene er uenige

Det første utfallet er det vanlige. En brukerromstunnel åpnet fra chroot kan fullføre håndtrykket, skrive ut statistikken og frakte trafikk som det samme skallet genererer, mens Androids apper fortsetter å bruke telefonens standardnettverk. Ingenting fanger dem opp, fordi ingenting fortalte Android at en VPN finnes.

Det andre utfallet er det farlige. Hvis chroot deler Androids nettverksnavnerom, noe den gjør som standard, kan en prosess med nok privilegier legge til ruter og et TUN-grensesnitt som påvirker hele telefonen. Da virker tunnelen for hver app, også de du ikke hadde tenkt å rute, og telefonens tilkobling avhenger nå av en tjeneste uten livssyklusstyring, uten tilkoblingsindikator og uten alltid-på-policy.

Hvilket av de to du fikk, kan avgjøres med én kommando. Sammenlign ip route inne i chroot med den samme kommandoen fra et Android-skall utenfor. Identisk utdata betyr at chroot er i vertens navnerom: enhver nettverksendring den gjør, gjelder hele telefonen. Ulike utdata betyr at oppstarteren laget et navnerom for den, og tunnelen er usynlig for Android av natur.

Hva chroot endret og hva den ikke endret

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

Systemkallet chroot gjør én ting: det endrer katalogen som brukes til å slå opp banenavn. Man-siden sier tydelig at det ikke er en sikkerhetsgrense, og den sier ingenting om grensesnitt, ruter eller VPN-tilstand. Alt folk forventer av en Linux-container — en privat nettverksstakk, et filtrert filsystem, ressursgrenser — kommer fra andre mekanismer som oppstarteren kan ha brukt eller ikke.

Derfor svarer påstander om at chroot isolerer en VPN vanligvis på feil spørsmål. Det relevante spørsmålet er hvilket navnerom prosessen kjører i og hvilket SELinux-domene den er begrenset til, og begge er egenskaper ved hvordan den ble startet, ikke ved ordet chroot.

TUN trenger tre ting, og en enhetsnode er bare én

En tradisjonell brukerromstunnel trenger en TUN-enhet den kan åpne, kjernestøtte for den enheten og tillatelse til å konfigurere grensesnittet og rutene. Dette er separate krav, og å lage et banenavn under /dev oppfyller ingen av dem i seg selv:

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

På Android har kjernen vanligvis TUN-støtte kompilert inn, fordi plattformens egen VPN-tjeneste bruker det, men det betyr ikke at prosessen din får bruke det. Grensesnittkonfigurasjon krever nettverksadministrasjonsrettigheter, og SELinux avgjør om prosessen i det hele tatt får nå enhetsnoden. En avvisning ser ut som en tilgangsfeil uten åpenbar årsak, og svaret finnes i revisjonsloggen:

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

Root løser ikke dette. SELinux begrenser prosesser som kjører som uid 0 akkurat som andre, så en chroot startet fra et root-skall kan fortsatt bli nektet en enhet den ser. Å slå av håndhevelsen for å få en gammel installasjonspakke til å virke er en beslutning for hele telefonen med konsekvenser langt utover tunnelen, og det er ingen retting av en utdatert binærfil.

Hvorfor Android-apper ignorerer tunnelen din

Androids støttede modell er en VPN-app som registrerer seg gjennom plattformens VPN-tjeneste, ber brukeren om samtykke én gang og mottar en fildeskriptor for tunnelen. Plattformen ruter deretter trafikken inn i den deskriptoren og håndhever appomfanget brukeren eller administratoren valgte, og derfor kan den samme mekanismen være per app, per profil og kombinert med alltid-på og blokker-uten-VPN-innstillinger. Androids VPN-utviklingsveiledning beskriver det håndtrykket, og poenget er at det er en registrering, ikke et rutetriks.

En tjeneste inne i chroot registrerer seg aldri. Det finnes ingen samtykkedialog, ingen nøkkelikon i statuslinjen, ingen liste for å inkludere eller utelate apper, og ingen deltakelse i alltid-på-policyen. Appene fortsetter derfor å bruke standardnettverket, og tunnelen frakter bare det skallet selv sender.

Den andre veien hjelper heller ikke. Å dytte ruter inn i vertens navnerom fanger alt, også trafikk plattformen forventet å holde lokalt, og det skjer uten kontroll per app og uten at brukeren kan se eller trekke det tilbake. Det finnes ingen mellominnstilling der en chroot-tjeneste ruter trafikk for bare én app.

Binærkompatibilitet er en egen mur

Selv når nettverkssiden er interessant, har den kjørbare filen sine egne krav: CPU-arkitektur, den dynamiske lasteren, C-biblioteket og kjernelavnene den forventer. Android bruker bionic i stedet for glibc, og en gammel binærfil bygget for en skrivebordsdistribusjon kan trenge biblioteker som ikke lenger finnes på enheten.

Å lenke et bibliotekfilnavn symbolsk til en nyere versjon gir ikke ABI-kompatibilitet, og et arkivert kryptobibliotek fra en ti år gammel pakke er ikke en vedlikeholdt komponent. Hvis planen avhenger av det, er planen å kjøre uvedlikeholdt kode med nettverksprivilegier på en telefon.

Bevis det i Android-konteksten og rydd opp etterpå

Test det du faktisk bryr deg om, fra den siden som betyr noe: åpne den bestemte appen, nå den bestemte private destinasjonen, bekreft hvilken resolver som svarte, koble deretter fra tunnelen og bekreft den dokumenterte oppførselen. Et resultat fra en terminal inne i chroot er bevis om den terminalens kjørekontekst og ingenting mer.

Hvis du endret vertsruter mens du eksperimenterte, sett dem tilbake og skriv ned hva du endret. Sjekk deretter om telefonen har en alltid-på-VPN konfigurert, fordi et eldre eksperiment som la igjen en regel kan se ut som en plattformfeil måneder senere.

For et reelt behov for fjernaksess, bruk tjenestens støttede klient eller en godkjent gateway-utforming. Spørsmålet som er verdt å stille er ikke om en rootet installasjonspakke kan fås til å kjøre, men om en støttet implementering frakter appene du trenger over grensen du mente, uten å legge igjen eierløse privilegerte endringer på enheten.

Relaterte artikler