Root ist nicht das, was eine Android-VPN-App dazu bringt, Verkehr zu tragen, Lecks zu blockieren oder einen Neustart zu überleben. Menschen fassen all das als „die App hat VPN-Berechtigung“ zusammen, was drei getrennte Mechanismen verdeckt: eine Nutzerzustimmung, eine Paketschnittstelle, die das System einrichtet, und eine Sperrrichtlinie der Plattform, die nicht die App zu definieren hat. Ein Android-VPN-Entwurf zu prüfen heißt zu fragen, auf welche der drei sich eine Behauptung tatsächlich stützt, denn jede hat einen anderen Eigentümer und einen anderen Fehlermodus.

Zustimmung kommt über eine Systemaktivität

VpnService.prepare() erteilt nichts. Die Methode gibt einen Intent an die System-Zustimmungsaktivität zurück, wenn die Zustimmung fehlt, und die App startet diesen Dialog, damit der Nutzer den Dienst genehmigt. Den eigenen Prozess der App zu starten, eine Berechtigung im Manifest hinzuzufügen oder einen eigenen Bildschirm „VPN aktivieren“ anzuzeigen, erzeugt die Erlaubnis nicht.

Die Erlaubnis ist außerdem begrenzt. Sie gehört zu einem Paket in einem Nutzerprofil, sodass die persönliche Kopie und die Arbeitskopie getrennte Entscheidungen sind, und ein Geräteeigentümer kann ein verwaltetes Profil anders vorbereiten als ein persönliches. Wenn der Dialog nie erscheint und prepare() null zurückgibt, besteht die Zustimmung für dieses Paket in diesem Profil bereits; das ist kein Beleg dafür, dass die App vertrauenswürdig ist, sondern nur dafür, dass die Erlaubnis vorliegt.

Die Schnittstelle ist eine Anfrage, die das System erfüllt

Nach der Zustimmung beschreibt die App mit VpnService.Builder, was sie will: Adressen, Routen, DNS-Server, MTU und, wo unterstützt, die ein- oder auszuschließenden Anwendungen. establish() bittet das System, die Tunnelschnittstelle zu erstellen und den passenden Verkehr dorthin zu leiten. Das System besitzt die Routing-Entscheidung; die App erhält den Dateideskriptor und muss dann etwas Nützliches mit den Paketen tun.

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

Diese Tabelle ist die Architektur an einem Ort. Die App beteiligt sich an der Paketverarbeitung; sie besitzt weder die Schnittstelle noch die Routing-Tabelle oder die Zahl der Dienste, die laufen dürfen.

Der Tunnel-Socket muss seinem eigenen Tunnel entkommen

Die Verbindung, die den verschlüsselten Verkehr trägt, ist selbst ein Socket. Wird sie zurück in die Schnittstelle geleitet, die die App gerade erstellt hat, hängt der Tunnel vom Tunnel ab und bleibt stehen. VpnService.protect() bindet diesen Socket an das darunterliegende Netz, damit er die Erfassung umgeht, und deshalb schützt ein korrekter Client seinen äußeren Socket vor dem ersten Handshake.

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

Diese Befehle zeigen das installierte VPN-Netz, das Paket für Always-on und ob die Sperre gesetzt ist. Es sind reine Lese-Beobachtungen: Stimmen die Werte nicht mit dem überein, was der Entwurf behauptet, betrifft die Behauptung die Oberfläche der App und nicht den Zustand des Systems.

Sperren kann der Plattform gehören

Android dokumentiert eine Richtlinie, die Verbindungen blockiert, die das VPN nicht nutzen. Diese Durchsetzung ist ein Plattformvertrag, keine App, die Verbindungen in einer Schleife erneut versucht. Der Schalter liegt in den VPN-Einstellungen des Geräts als Verbindungen ohne VPN blockieren, und auf einem verwalteten Gerät kann ein Geräteeigentümer ihn für das ganze Profil einschalten. Der Unterschied zählt, wenn Sie eine Marketingaussage bewerten: Ein Client kann ein Schloss-Symbol anzeigen und aggressiv neu verbinden, während direkter Verkehr weiterhin möglich ist, oder abgedeckte Apps können offline bleiben, weil das System die Sperre durchsetzt.

Ein Schloss-Symbol zeichnet die App, es belegt also nur, dass die App glaubt, verbunden zu sein. Ob eine andere App ihren Netzzugang verliert, entscheidet die Plattform, daher ist die nützliche Prüfung, diese App scheitern zu sehen, während der Tunnel steht.

Auch ein „Always-on“-Label aus dem App-Store ersetzt diesen Vertrag nicht. Always-on und Sperre sind Geräteeinstellungen, oft von einem Geräteeigentümer angewandt, und ihr Verhalten für ausgeschlossene Apps definiert die Plattform. Lesen Sie die Einstellung, nicht das Abzeichen.

Vier Fragen für eine Designprüfung

Erstens, wer hat zugestimmt: welches Paket, welches Profil, und war es der Nutzer oder eine Richtlinie für verwaltete Geräte? Zweitens, was hat die App angefordert: welche Routen, welche Adressfamilien, welche ein- oder ausgeschlossenen Apps? Drittens, was passiert, wenn der Tunnel nicht verfügbar ist: blockiert das System, oder fällt der Verkehr auf das darunterliegende Netz zurück? Viertens, was macht die App mit den Paketen, die sie empfängt?

Die vierte Frage ist die, die das Berechtigungsmodell nicht beantworten kann. Zustimmung und eine TUN-Schnittstelle belegen, dass die App Verkehr empfangen kann, nicht dass sie ihn verschlüsselt, eine Gegenstelle authentifiziert oder sich sauber erholt. Das sind Implementierungseigenschaften, und dort verbringt eine ehrliche Prüfung ihre Zeit.

Eine unnötige Root-Anfrage wird nicht dadurch legitim, dass man das Ergebnis Kill Switch nennt, und ein Zustimmungsdialog ist kein Sicherheitsaudit. Halten Sie die drei Erlaubnisse getrennt, und jede Behauptung wird prüfbar.

Ähnliche Artikel