VPN

Android fournit des API permettant aux développeurs de créer un réseau privé virtuel (VPN) de Google Cloud. Ce guide vous explique comment développer et tester propre client VPN pour les appareils Android.

Présentation

Les VPN permettent aux appareils qui ne sont pas physiquement connectés à un réseau d'accéder de façon sécurisée au réseau.

Android inclut un client VPN intégré (PPTP et L2TP/IPSec), qui est parfois appelé ancien VPN. Android 4.0 (niveau d'API 14) a introduit des API pour que les applications les développeurs pouvaient fournir leurs propres solutions VPN. Vous empaquetez votre solution VPN dans une application que les gens installent sur l'appareil. Les développeurs créent généralement un VPN application pour l'une des raisons suivantes:

  • Proposer des protocoles VPN qui ne sont pas compatibles avec le client intégré
  • Aider les utilisateurs à se connecter à un service VPN sans configuration complexe

Le reste de ce guide explique comment développer des applications VPN (VPN toujours activé et par application) et ne couvre pas client VPN intégré.

Expérience utilisateur

Android fournit une interface utilisateur pour aider quelqu'un à configurer, démarrer et arrêter votre solution VPN. L'UI du système rend également la personne qui utilise l'appareil qu'une connexion VPN active est activée. Android affiche les composants d'UI suivants pour Connexions VPN:

  • Avant qu'une application VPN puisse devenir active pour la première fois, le système affiche une boîte de dialogue de demande de connexion. La boîte de dialogue invite l'utilisateur de l'appareil à confirmer qu'il fait confiance au VPN et accepter la demande.
  • L'écran "Paramètres de VPN" (Paramètres > Réseau et Internet > VPN) indique applications dans lesquelles une personne acceptait les demandes de connexion. Un bouton permet de configurer les options système ou oublier le VPN.
  • La barre de configuration rapide affiche un panneau d'informations lorsqu'une connexion actif. Appuyez sur le libellé pour afficher une boîte de dialogue contenant plus d'informations et un lien à "Paramètres".
  • La barre d'état inclut une icône VPN (clé) indiquant qu'une connexion est active.

Votre application doit également fournir une interface utilisateur afin que la personne qui utilise l'appareil puisse configurer les options de votre service. Par exemple, votre solution peut avoir besoin capturer les paramètres d'authentification du compte. Les applications doivent afficher l'interface utilisateur suivante:

  • Contrôles pour démarrer et arrêter manuellement une connexion. VPN permanent peuvent se connecter en cas de besoin, mais permettez-leur de configurer la connexion à chaque fois qu'ils utilisent votre VPN.
  • Notification non ignorable lorsque le service est actif. La notification peut afficher l'état de la connexion ou fournir plus d'informations, telles que des statistiques sur le réseau. Appuyez sur la notification pour afficher votre application au premier plan. Supprimez le une notification lorsque le service devient inactif.

Service VPN

Votre application connecte le réseau système d'un utilisateur (ou une entreprise ) à une passerelle VPN. Chaque utilisateur (ou profil professionnel) peut exécuter application VPN différente. Vous créez un service VPN que le système utilise pour démarrer et arrêter votre VPN et suivre l'état de la connexion. Votre service VPN hérite des VpnService

Le service sert également de conteneur pour les connexions à la passerelle VPN les interfaces de leurs périphériques locaux. Votre appel d'instance de service VpnService.Builder pour établir une nouvelle interface locale.

<ph type="x-smartling-placeholder">
</ph>
Figure 1 : Comment VpnService connecte Android à la passerelle VPN,
Diagramme d&#39;architecture en blocs montrant comment VpnService crée un TUN local
         de mise en réseau de systèmes.

Votre application transfère les données suivantes pour connecter l'appareil à la passerelle VPN:

  • Lit les paquets IP sortants à partir du descripteur de fichier de l'interface locale, chiffre et les envoie vers la passerelle VPN.
  • Écrit les paquets entrants (reçus et déchiffrés par la passerelle VPN) sur le le descripteur de fichier de l'interface locale.

Il n'y a qu'un seul service actif par utilisateur ou par profil. En lançant un nouveau service, arrête automatiquement un service existant.

Ajouter un service

Pour ajouter un service VPN à votre application, créez un service Android héritant de VpnService Déclarer le service VPN dans votre application manifeste avec les ajouts suivants:

  • Protéger le service avec le BIND_VPN_SERVICE afin que seul le système puisse s'associer à votre service.
  • Promouvez le service avec le filtre d'intent "android.net.VpnService" afin que : le système peut trouver votre service.

Cet exemple montre comment déclarer le service dans le fichier manifeste de votre application:

<service android:name=".MyVpnService"
         android:permission="android.permission.BIND_VPN_SERVICE">
     <intent-filter>
         <action android:name="android.net.VpnService"/>
     </intent-filter>
</service>

Maintenant que votre application déclare le service, le système peut démarrer automatiquement et arrêter le service VPN de votre application si nécessaire. Par exemple, le système contrôle votre service lorsque vous exécutez un VPN permanent.

Préparer un service

Pour préparer l'application à devenir le service VPN actuel de l'utilisateur, appelez VpnService.prepare() Si la personne qui utilise l'appareil déjà autorisée pour votre application, la méthode renvoie un intent d'activité. Vous utilisez cet intent pour démarrer une activité système qui demande une autorisation. La système affiche une boîte de dialogue semblable à d'autres boîtes de dialogue d'autorisations, comme l'accès à la caméra ou aux contacts. Si votre application est déjà préparée, la méthode renvoie null

Une seule application peut être le service VPN actuellement préparé. Toujours appeler VpnService.prepare(), car il est possible qu'une autre personne ait défini l'application en tant que service VPN depuis le dernier appel de la méthode par votre application. Pour en savoir plus, consultez dans la section Cycle de vie du service.

Associer un service

Une fois le service en cours d'exécution, vous pouvez établir une nouvelle interface locale connecté à une passerelle VPN. Pour demander l'autorisation et vous connecter à votre service pour la passerelle VPN, vous devez effectuer les étapes dans l'ordre suivant:

  1. Appelez VpnService.prepare() pour demander l'autorisation (lorsque si nécessaire).
  2. Appelez VpnService.protect() pour conserver le socket de tunnel de votre application en dehors du VPN du système et évitez une connexion circulaire.
  3. Appelez DatagramSocket.connect() pour connecter le tunnel de votre application socket à la passerelle VPN.
  4. Appeler les méthodes VpnService.Builder pour configurer un nouveau réseau local l'interface TUN pour le trafic VPN.
  5. Appelez VpnService.Builder.establish() pour que le système établit l'interface TUN locale et commence à acheminer le trafic via de commande.

Une passerelle VPN suggère normalement des paramètres pour l'interface TUN locale pendant une poignée de main. Votre application appelle des méthodes VpnService.Builder pour configurer un comme illustré dans l'exemple suivant:

Kotlin

// Configure a new interface from our VpnService instance. This must be done
// from inside a VpnService.
val builder = Builder()

// Create a local TUN interface using predetermined addresses. In your app,
// you typically use values returned from the VPN gateway during handshaking.
val localTunnel = builder
        .addAddress("192.168.2.2", 24)
        .addRoute("0.0.0.0", 0)
        .addDnsServer("192.168.1.1")
        .establish()

Java

// Configure a new interface from our VpnService instance. This must be done
// from inside a VpnService.
VpnService.Builder builder = new VpnService.Builder();

// Create a local TUN interface using predetermined addresses. In your app,
// you typically use values returned from the VPN gateway during handshaking.
ParcelFileDescriptor localTunnel = builder
    .addAddress("192.168.2.2", 24)
    .addRoute("0.0.0.0", 0)
    .addDnsServer("192.168.1.1")
    .establish();

L'exemple de la section VPN par application présente une configuration IPv6 incluant d'autres options. Vous devez ajouter les valeurs VpnService.Builder suivantes : avant de pouvoir créer une nouvelle interface:

addAddress()
Ajoutez au moins une adresse IPv4 ou IPv6, ainsi qu'un masque de sous-réseau que le système définit comme adresse d'interface d'interface TUN locale. Votre application reçoit généralement l'adresse IP et les masques de sous-réseau d'une passerelle VPN lors d'un handshake.
addRoute()
Ajoutez au moins une route si vous souhaitez que le système envoie du trafic via le VPN de commande. Les itinéraires sont filtrés par adresse de destination. Pour accepter tout le trafic, définissez un une route ouverte comme 0.0.0.0/0 ou ::/0.

La méthode establish() renvoie une Instance ParcelFileDescriptor utilisée par votre application pour les opérations de lecture et d'écriture paquets vers et depuis le tampon de l'interface. establish() renvoie null si votre application n'est pas préparée ou si quelqu'un révoque le l'autorisation.

Cycle de vie des services

Votre application doit suivre l'état du VPN sélectionné par le système et de tout VPN connexions externes. Mettez à jour l'interface utilisateur de votre application pour que cette personne continue à utiliser de chaque changement.

Démarrer un service

Vous pouvez démarrer votre service VPN de différentes manières:

  • Votre application démarre le service, généralement parce qu'une personne a appuyé sur un bouton de connexion.
  • Le système démarre le service, car le VPN permanent est activé.

Votre application démarre le service VPN en transmettant un intent à startService() Pour en savoir plus, consultez la section Démarrage d'un service.

Le système démarre votre service en arrière-plan en appelant onStartCommand() Cependant, Android impose des restrictions les applications en arrière-plan de la version 8.0 (niveau d'API 26) ou ultérieure ; Si vous les acceptez, niveau d'API, vous devez faire passer votre service au premier plan en appelant Service.startForeground() Pour en savoir plus, consultez la section Exécution d'un au premier plan.

Arrêter un service

Une personne utilisant l'appareil peut arrêter votre service via l'interface utilisateur de votre application. Arrêtez le au lieu de simplement fermer la connexion. Le système arrête également lorsque la personne qui utilise l'appareil effectue les opérations suivantes sur l'écran "VPN" de l'application Paramètres:

  • déconnecte ou oublie l'application de VPN
  • désactive le VPN permanent pour une connexion active

Le système appelle la méthode onRevoke() de votre service, mais cet appel peut ne pas se produire sur le thread principal. Lorsque le système appelle cette méthode, l'autre interface réseau achemine déjà le trafic. Vous pouvez vous débarrasser en toute sécurité des ressources suivantes:

VPN permanent

Android peut démarrer un service VPN au démarrage de l'appareil et le maintenir en exécution pendant l'appareil est allumé. Cette fonctionnalité, appelée VPN permanent, est disponible dans Android 7.0 (niveau d'API 24) ou version ultérieure Tandis qu'Android gère le service, du cycle de vie de la solution, c'est votre service VPN qui est responsable . Un VPN permanent peut également bloquer les connexions qui n'utilisent pas le VPN.

Expérience utilisateur

Dans Android 8.0 ou version ultérieure, le système affiche les boîtes de dialogue suivantes pour que le personne utilisant l'appareil compatible avec le VPN permanent:

  • Lorsque les connexions VPN permanentes se déconnectent ou ne peuvent pas se connecter, les utilisateurs voient un notification non ignorable. Appuyez sur la notification pour afficher une boîte de dialogue qui . La notification disparaît lorsque le VPN se reconnecte ou si un utilisateur désactive le VPN permanent.
  • Le VPN permanent permet à la personne qui utilise un appareil de bloquer n'importe quel réseau connexions qui n'utilisent pas le VPN. Lorsque vous activez cette option, le menu l'application avertit les utilisateurs qu'ils n'ont pas de connexion Internet avant que le VPN entre les réseaux. L'application Paramètres invite l'utilisateur de l'appareil à continuer ou annuler.

Parce que le système (et non une personne) démarre et arrête une connexion permanente, vous devez adapter le comportement et l'interface utilisateur de votre application:

  1. Désactiver toute UI qui déconnecte la connexion, car le système et les paramètres pour contrôler la connexion.
  2. Enregistrez les configurations entre chaque démarrage de l'application et configurez une connexion avec le les derniers paramètres. Comme le système lance votre application à la demande, utilisant l'appareil peuvent ne pas toujours vouloir configurer une connexion.

Vous pouvez également utiliser des configurations gérées pour configurer . Les configurations gérées aident un administrateur informatique à configurer votre VPN à distance.

Détecter en permanence

Android n'inclut pas d'API permettant de vérifier si le système a lancé votre VPN Google Cloud. Mais, lorsque votre application signale une instance de service qu'elle démarre, vous pouvez en déduire que que le système a lancé des services non signalés pour le VPN permanent. Voici un exemple :

  1. Créez une instance Intent pour démarrer le service VPN.
  2. Signalez le service VPN en ajoutant un extra à l'intent.
  3. Dans la méthode onStartCommand() du service, recherchez dans les extras de l'argument intent.

Connexions bloquées

Une personne (ou un administrateur informatique) qui utilise l'appareil peut forcer tout le trafic à utiliser le VPN. Le système bloque tout trafic réseau qui n'utilise pas le VPN. Personnes utilisant les votre appareil peut trouver le bouton bascule Bloquer les connexions sans VPN dans les options de VPN panneau des paramètres.

Désactiver le mode Always-on

Si votre application n'est actuellement pas compatible avec le VPN permanent, vous pouvez le désactiver (dans Android 8.1 ou version ultérieure) en paramétrant le SERVICE_META_DATA_SUPPORTS_ALWAYS_ON les métadonnées du service sur false. L'exemple de fichier manifeste d'application suivant montre comment ajouter l'élément de métadonnées:

<service android:name=".MyVpnService"
         android:permission="android.permission.BIND_VPN_SERVICE">
     <intent-filter>
         <action android:name="android.net.VpnService"/>
     </intent-filter>
     <meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
             android:value=false/>
</service>

Lorsque votre appli désactive le VPN permanent, le système désactive l'UI des options dans les paramètres.

VPN par application

Les applications VPN peuvent filtrer les applications installées qui sont autorisées à envoyer du trafic via le Connexion VPN. Vous pouvez créer une liste d'autorisation ou une liste d'interdictions mais pas les deux. Si vous ne créez pas de listes d'autorisation ou d'interdiction, le système envoie tout le trafic réseau via le VPN.

Votre application VPN doit définir les listes avant que la connexion soit établie. Si vous vous devez modifier les listes, établir une nouvelle connexion VPN. Une application doit être installées sur l'appareil lorsque vous l'ajoutez à une liste.

Kotlin

// The apps that will have access to the VPN.
val appPackages = arrayOf(
        "com.android.chrome",
        "com.google.android.youtube",
        "com.example.a.missing.app")

// Loop through the app packages in the array and confirm that the app is
// installed before adding the app to the allowed list.
val builder = Builder()
for (appPackage in appPackages) {
    try {
        packageManager.getPackageInfo(appPackage, 0)
        builder.addAllowedApplication(appPackage)
    } catch (e: PackageManager.NameNotFoundException) {
        // The app isn't installed.
    }
}

// Complete the VPN interface config.
val localTunnel = builder
        .addAddress("2001:db8::1", 64)
        .addRoute("::", 0)
        .establish()

Java

// The apps that will have access to the VPN.
String[] appPackages = {
    "com.android.chrome",
    "com.google.android.youtube",
    "com.example.a.missing.app"};

// Loop through the app packages in the array and confirm that the app is
// installed before adding the app to the allowed list.
VpnService.Builder builder = new VpnService.Builder();
PackageManager packageManager = getPackageManager();
for (String appPackage: appPackages) {
  try {
    packageManager.getPackageInfo(appPackage, 0);
    builder.addAllowedApplication(appPackage);
  } catch (PackageManager.NameNotFoundException e) {
    // The app isn't installed.
  }
}

// Complete the VPN interface config.
ParcelFileDescriptor localTunnel = builder
    .addAddress("2001:db8::1", 64)
    .addRoute("::", 0)
    .establish();

Applications autorisées

Pour ajouter une application à la liste d'autorisation, appelez VpnService.Builder.addAllowedApplication() Si la liste comprend une ou plusieurs applications, alors seules celles-ci utilisent le VPN. Toutes les autres applications (qui ne figurent pas dans la liste) utilisent les réseaux du système comme si le VPN n'est pas exécutée. Lorsque la liste d'autorisation est vide, toutes les applications utilisent le VPN.

Applications non autorisées

Pour ajouter une application à la liste des applications non autorisées, appelez VpnService.Builder.addDisallowedApplication() Les applications non autorisées utilisent la mise en réseau du système comme si le VPN n'était pas en cours d'exécution. Toutes les autres applications utilisent le VPN.

Contourner le VPN

Votre VPN peut permettre aux applications de le contourner et de sélectionner leur propre réseau. À contourner le VPN, appelez VpnService.Builder.allowBypass() lorsque en établissant une interface VPN. Une fois que vous avez démarré votre VPN Google Cloud. Si une application ne lie pas son processus ou son socket à un le trafic réseau de l'application continue via le VPN.

Les applications associées à un réseau spécifique n'ont aucune connexion lorsqu'un utilisateur bloque le trafic qui ne passe pas par le VPN. Pour envoyer du trafic via un réseau réseau, méthodes d'appel des applications, telles que ConnectivityManager.bindProcessToNetwork() ou Network.bindSocket() avant de brancher la prise de courant.

Exemple de code

Le projet Android Open Source inclut une application exemple appelée ToyVPN. Cette application vous montre comment configurer et connecter un service VPN.