VPN per app op Android: een app uitsluiten is niet het blokkeren ervan
De lijst per app op het scherm hoort bij één tunneleigenaar, en een app uitsluiten leidt die om de tunnel heen in plaats van van het netwerk af. Begin daar.
Twee mensen stellen dezelfde vraag en krijgen onverenigbare antwoorden, omdat ze op verschillende plekken staan. De een heeft het VPN-instellingenscherm van het systeem open en bewerkt een lijst met apps. De ander schrijft VpnService.Builder.addDisallowedApplication() in een editor. Beiden noemen het een VPN-filter per app. Slechts één van hen bezit de controle die hij beschrijft, en geen van beiden blokkeert iets.
Begin bij het scherm dat de gebruiker ziet
Open Instellingen, zoek de VPN-vermelding en kijk naar de verbinding die echt actief is. Biedt de client een lijst per app, dan hoort die lijst bij de eigen tunnel van de client. Het platform publiceert geen algemene API waarmee een ongerelateerde app de app-selectie van een andere VPN kan lezen of wijzigen, dus een tweede app kan die lijst niet voor de gebruiker repareren.
Dit is de eerste splitsing in de wandeling. Heeft de geïnstalleerde VPN die instelling niet, dan valt er niets omheen te programmeren: de functie ontbreekt in het product dat de tunnel bezit. Heeft hij die wel, dan zit de juiste oplossing in dat scherm, uitgevoerd door wie het kan openen.
Volg het pakket een tunnel in
Wanneer je eigen app een tunnel bouwt, maakt hij een TUN-interface aan en verklaart welke apps hun verkeer erin laten lopen. De lidmaatschapsaanroepen gebeuren voordat de interface tot stand komt, en daarna ligt de regelset voor die sessie vast:
val builder = VpnService.Builder()
builder.addAddress("10.8.0.2", 32)
builder.addRoute("0.0.0.0", 0)
builder.addDisallowedApplication("com.example.bypass")
val tun = builder.establish() // membership decided hereDie aanroepen gelden voor de tunnel die je app zojuist heeft gemaakt en voor niets anders. Het is geen beleid voor het hele apparaat, ze blijven niet bestaan voor andere clients, en ze kunnen niet in iemands anders VPN komen. Wanneer een aanroep van de builder een uitzondering gooit omdat het pakket niet kan worden opgelost, wordt de interface nooit tot stand gebracht, wat een schone en geen stille fout is.
Waarom de uitsluiting op een blokkade leek
Een uitgesloten app wordt om je tunnel heen naar het onderliggende netwerk geleid. Dat is het tegenovergestelde van hem blokkeren: het verkeer verlaat het apparaat nog steeds, alleen buiten de interface die jij beheert. Een app in firewallstijl doet het omgekeerde. Hij laat het verkeer van de app zijn tunnel binnen en gooit de pakketten daarna weg, of weigert ze door te sturen, zodat de interface dezelfde is en de richting van het beleid is omgekeerd.
Het werk achter die omkering is geen configuratievlag. Je leest IP-pakketten uit de tunneldescriptor, beslist per stroom en stuurt ze door een beschermde socket of gooit ze weg. Alles wat je niet afhandelt, stopt gewoon, en daarom ziet een half afgemaakte tunnel eruit als een kapot netwerk in plaats van een werkend filter. Is je doel een blokkade, begroot dan pakketafhandeling, een voorgronddienst en een geschreven beleid voor verkeer dat je niet kunt classificeren.
Wat er breekt als je het zelf bouwt
Android staat doorgaans maar één actieve VPN tegelijk toe, dus je filtertunnel en een privacytunnel concurreren om dezelfde plek, tenzij de producten ketenen ondersteunen. Always-on VPN met verbindingsblokkade verandert de faalmodus op een manier die hier telt: verkeer dat de tunnel niet in kan, wordt weggegooid in plaats van direct verzonden, wat een ontwerp tegen lekken wil en wat een debugsessie zelden verwacht.
Pakketzichtbaarheid is de tweede valkuil. Het omzetten van de pakketnaam van een app kan mislukken met NameNotFoundException, en op nieuwere Android-versies hangt de set pakketten die je kunt zien af van de querys die je hebt gedeclareerd. Handel de uitzondering af in plaats van aan te nemen dat elke naam wordt omgezet, en lees de lijst opnieuw wanneer apps worden geïnstalleerd of verwijderd in plaats van hem voor altijd te cachen.
Beheerde apparaten voegen een derde eigenaar toe. Een beleid voor bedrijfsmobiliteit kan een VPN per app of een always-on profiel instellen, en een gewone app kan dat niet overschrijven. Controleer of het apparaat beheerd wordt voordat je je eigen code debugt, want in dat geval is de lijst die je probeert te wijzigen misschien door niemand die de telefoon vasthoudt te bewerken.
Test het met een app die je beheert
Test niet met de app die je probeert te filteren. Gebruik een tweede app waarvan je het netwerkgedrag kunt observeren, en controleer of het verkeer via je tunnel naar buiten gaat terwijl dat van het doel dat niet doet. Blijven beide binnen, dan werkt het beleid en is het doel uitgesloten; gaat geen van beide naar buiten, dan is de tunnel zelf fout en is de app-lijst niet het probleem.
Bepaal daarna welke van drie dingen je werkelijk bouwt. Een tunnel per app is de builder-API, met de lijst als deel van je profiel. Een apparaatfirewall is pakketafhandeling plus een levenscyclus die je kunt verdedigen. Iemands anders VPN wijzigen is helemaal geen ondersteund pad, en het eerlijke antwoord daar is dat de instelling bij dat product hoort.