Root er ikke det som gjør at en Android-VPN-app kan frakte trafikk, blokkere lekkasjer eller overleve en omstart. Folk oppsummerer alt dette som „appen har VPN-tillatelse“, noe som skjuler tre atskilte mekanismer: et samtykke fra brukeren, et pakkegrensesnitt systemet oppretter, og en blokkeringspolicy på plattformen som ikke er appens å definere. Å vurdere et Android-VPN-design betyr å spørre hvilken av de tre en påstand faktisk hviler på, fordi hver har en annen eier og en annen feilmodus.

Samtykke kommer gjennom en systemaktivitet

VpnService.prepare() gir ingenting. Den returnerer en intent til systemets samtykkeaktivitet når samtykke mangler, og appen starter dialogen slik at brukeren kan godkjenne tjenesten. Å starte appens egen prosess, legge til en tillatelse i manifestet eller vise en egen „aktiver VPN“-skjerm oppretter ikke tillatelsen.

Tillatelsen er også avgrenset. Den tilhører en pakke i en brukerprofil, så den personlige kopien og arbeidskopien er separate beslutninger, og en enhetseier kan forberede en administrert profil annerledes enn en personlig. Hvis dialogen aldri vises og prepare() returnerer null, finnes samtykket allerede for den pakken i den profilen; det er ikke bevis for at appen er pålitelig, bare at tillatelsen er på plass.

Grensesnittet er en forespørsel systemet oppfyller

Etter samtykket beskriver appen hva den vil ha med VpnService.Builder: adresser, ruter, DNS-servere, MTU og, der det støttes, appene som skal inkluderes eller utelates. establish() ber systemet opprette tunnelgrensesnittet og lede den matchende trafikken inn i det. Systemet eier rutingsbeslutningen; appen mottar fildeskriptoren og må deretter gjøre noe nyttig med pakkene.

What you observeWho actually owns it
VPN consent dialogThe system, triggered by prepare()
Routes, DNS and app listsThe app requests them; the system applies them
One active VPN per profileThe platform; a new service replaces the old one
Always-on and block-without-VPNDevice policy enforced by the platform

Den tabellen er arkitekturen på ett sted. Appen deltar i pakkehåndtering; den eier ikke grensesnittet, rutetabellen eller antallet tjenester som kan kjøre.

Tunnelsocketen må unnslippe sin egen tunnel

Forbindelsen som frakter den krypterte trafikken, er selv en socket. Hvis den rutes tilbake til grensesnittet appen nettopp opprettet, avhenger tunnelen av tunnelen og stopper. VpnService.protect() binder socketen til det underliggende nettverket slik at den omgår opptaket, og derfor beskytter en korrekt klient den ytre socketen før det første håndtrykket.

adb shell dumpsys connectivity | grep -i -A5 vpn
adb shell settings get global always_on_vpn_app
adb shell settings get global always_on_vpn_lockdown

Disse kommandoene viser det installerte VPN-nettverket, pakken for alltid på og om låsing er satt. De er kun leseobservasjoner: hvis verdiene ikke stemmer med det designet hevder, gjelder påstanden appens grensesnitt og ikke systemets tilstand.

Blokkering kan tilhøre plattformen

Android dokumenterer en policy som blokkerer tilkoblinger som ikke bruker VPN. Den håndhevelsen er en plattformkontrakt, ikke en app som gjentar tilkoblingsforsøk i en løkke. Bryteren ligger i enhetens VPN-innstillinger som Blokker tilkoblinger uten VPN, og på en administrert enhet kan eieren slå den på for hele profilen. Forskjellen teller når du vurderer en markedsføringspåstand: en klient kan vise et hengelåsikon og koble til på nytt aggressivt mens direkte trafikk fortsatt er mulig, eller dekkede apper kan forbli frakoblet fordi systemet håndhever låsingen.

Hengelåsikonet tegnes av appen, så det beviser bare at appen tror den er tilkoblet. Om en annen app mister nettverkstilgangen avgjøres av plattformen, så den nyttige kontrollen er å se den appen feile mens tunnelen er oppe.

En „alltid på“-etikett fra appbutikken erstatter heller ikke den kontrakten. Alltid på og låsing er enhetsinnstillinger, ofte brukt av en enhetseier, og deres oppførsel for utelatte apper defineres av plattformen. Les innstillingen, ikke merket.

Fire spørsmål for en designgjennomgang

For det første, hvem samtykket: hvilken pakke, hvilken profil, og var det brukeren eller en policy for administrerte enheter? For det andre, hva ba appen om: hvilke ruter, hvilke adressefamilier, hvilke inkluderte eller utelatte apper? For det tredje, hva skjer når tunnelen ikke er tilgjengelig: blokkerer systemet, eller faller trafikken tilbake til det underliggende nettverket? For det fjerde, hva gjør appen med pakkene den mottar?

Det fjerde spørsmålet er det tillatelsesmodellen ikke kan svare på. Samtykke og et TUN-grensesnitt beviser at appen kan motta trafikk, ikke at den krypterer den, autentiserer en motpart eller gjenoppretter seg rent. Det er implementeringsegenskaper, og det er der en ærlig gjennomgang bruker tiden sin.

En unødvendig root-forespørsel blir ikke legitim av å kalle resultatet en kill switch, og en samtykkedialog er ikke en sikkerhetsrevisjon. Hold de tre tillatelsene atskilt, og hver påstand blir kontrollerbar.

Relaterte artikler