VPN

Android fornisce agli sviluppatori API per creare una rete privata virtuale (VPN) soluzioni. Dopo aver letto questa guida, saprai come sviluppare e testare il tuo un proprio client VPN per i dispositivi basati su Android.

Panoramica

Le VPN consentono ai dispositivi che non si trovano fisicamente su una rete di accedere in modo sicuro in ogni rete.

Android include un client VPN integrato (PPTP e L2TP/IPSec), che a volte viene chiamata VPN legacy. Android 4.0 (livello API 14) ha introdotto le API per consentire gli sviluppatori potevano fornire le proprie soluzioni VPN. Pacchettizza la tua soluzione VPN in un'app che gli utenti installano sul dispositivo. Gli sviluppatori normalmente creano una VPN per uno dei seguenti motivi:

  • Per offrire protocolli VPN non supportati dal client incorporato.
  • Per consentire alle persone di collegarsi a un servizio VPN senza bisogno di complesse configurazioni.

Il resto di questa guida spiega come sviluppare app VPN (incluse sempre attiva e per app) e non copre la un client VPN integrato.

Esperienza utente

Android fornisce un'interfaccia utente (UI) per aiutare gli utenti a configurare, avviare e interrompere la tua soluzione VPN. Inoltre, l'interfaccia utente di sistema rende la persona che utilizza il dispositivo di una connessione VPN attiva. Android mostra i seguenti componenti dell'interfaccia utente per Connessioni VPN:

  • Prima che un'app VPN possa diventare attiva per la prima volta, il sistema visualizza finestra di dialogo per la richiesta di connessione. La finestra di dialogo chiede alla persona che utilizza il dispositivo di confermare che la VPN è attendibile e accettare la richiesta.
  • La schermata Impostazioni VPN (Impostazioni > Rete e internet > VPN) mostra la VPN app in cui una persona ha accettato richieste di connessione. C'è un pulsante per configurare opzioni di sistema di Google Cloud o rimuovi la VPN.
  • La barra Impostazioni rapide mostra un riquadro informativo quando è attiva una connessione attivo. Se tocchi l'etichetta, viene visualizzata una finestra di dialogo con ulteriori informazioni e un link su Impostazioni.
  • La barra di stato include un'icona VPN (chiave) che indica una connessione attiva.

L'app deve inoltre fornire una UI in modo che la persona che utilizza il dispositivo possa e configurare le opzioni del tuo servizio. Ad esempio, la tua soluzione potrebbe dover acquisire le impostazioni di autenticazione dell'account. Le app dovrebbero mostrare la seguente UI:

  • Controlli per avviare e interrompere manualmente una connessione. VPN sempre attiva possono connettersi quando necessario, ma consentono alle persone di configurare la connessione volta che usano la tua VPN.
  • Una notifica non ignorabile quando il servizio è attivo. La notifica può mostrare lo stato della connessione o fornire ulteriori informazioni, ad esempio le statistiche di rete. Se tocchi la notifica, la tua app viene messa in primo piano. Rimuovi il quando il servizio diventa inattivo.

Servizio VPN

L'app connette la rete di sistema per un utente (o un profilo) a un gateway VPN. Ogni utente (o profilo di lavoro) può eseguire un un'altra app VPN. Crei un servizio VPN che il sistema utilizza per avviare e interrompere la VPN e monitorare lo stato della connessione. Il tuo servizio VPN eredita VpnService

Il servizio funge anche da container per le connessioni del gateway VPN all'interfaccia dei loro dispositivi locali. Chiamata all'istanza di servizio VpnService.Builder per creare una nuova interfaccia locale.

Figura 1. In che modo VpnService connette Android networking al gateway VPN
Diagramma dell'architettura a blocchi che mostra come VpnService crea un TUN locale
         nel networking di sistema.

L'app trasferisce i seguenti dati per connettere il dispositivo al gateway VPN:

  • Legge i pacchetti IP in uscita dal descrittore di file dell'interfaccia locale, cripta e li invia al gateway VPN.
  • Scrive i pacchetti in entrata (ricevuti e decriptati dal gateway VPN) nella il descrittore di file dell'interfaccia locale.
di Gemini Advanced.

È attivo un solo servizio per utente o profilo. L'avvio di un nuovo servizio, interrompe automaticamente un servizio esistente.

Aggiungi un servizio

Per aggiungere un servizio VPN alla tua app, crea un servizio Android che eredita da VpnService Dichiara il servizio VPN nella tua app file manifest con le seguenti aggiunte:

  • Proteggi il servizio con BIND_VPN_SERVICE in modo che solo il sistema possa associarsi al tuo servizio.
  • Pubblicizza il servizio con il filtro per intent "android.net.VpnService" in modo che il sistema può trovare il tuo servizio.

Questo esempio mostra come dichiarare il servizio nel file manifest dell'app:

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

Ora che la tua app dichiara il servizio, il sistema può avviare automaticamente e interrompere il servizio VPN dell'app quando necessario. Ad esempio, il controllo di sistema il tuo servizio quando esegui la VPN sempre attiva.

prepara un servizio

Per preparare l'app a diventare il servizio VPN attuale dell'utente, chiama VpnService.prepare() Se la persona che utilizza il dispositivo non ha hai già concesso l'autorizzazione alla tua app, il metodo restituisce un intent di attività. Utilizzi questo intent per avviare un'attività di sistema che richiede l'autorizzazione. La mostra una finestra di dialogo simile ad altre finestre di dialogo di autorizzazione, come alla fotocamera o ai contatti. Se la tua app è già preparata, il metodo restituisce null.

Solo un'app può essere il servizio VPN attualmente preparato. Chiama sempre VpnService.prepare() perché una persona potrebbe aver impostato un indirizzo come servizio VPN dall'ultima volta che l'app ha chiamato il metodo. Per saperne di più, vedi nella sezione Ciclo di vita dei servizi.

Collega un servizio

Quando il servizio è in esecuzione, puoi stabilire una nuova interfaccia locale connesso a un gateway VPN. Per richiedere l'autorizzazione e connetterti al tuo servizio a gateway VPN, devi completare i passaggi nel seguente ordine:

  1. Chiama il numero VpnService.prepare() per chiedere l'autorizzazione (quando necessaria).
  2. Chiama VpnService.protect() per mantenere il socket del tunnel della tua app all'esterno della VPN di sistema ed evita una connessione circolare.
  3. Chiama DatagramSocket.connect() per connettere il tunnel della tua app al gateway VPN.
  4. Chiama i metodi VpnService.Builder per configurare un nuovo locale nell'interfaccia TUN dispositivo per il traffico VPN.
  5. Chiama VpnService.Builder.establish() in modo che il sistema stabilisce l'interfaccia TUN locale e inizia a instradare il traffico attraverso a riga di comando.

Normalmente un gateway VPN suggerisce le impostazioni per l'interfaccia TUN locale durante le mani. L'app chiama VpnService.Builder metodi per configurare un come mostrato nell'esempio seguente:

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'esempio nella sezione VPN per app mostra una configurazione IPv6 che include altre opzioni. Devi aggiungere i seguenti valori VpnService.Builder prima di poter creare una nuova interfaccia:

addAddress()
Aggiungi almeno un indirizzo IPv4 o IPv6 insieme a una subnet mask che il sistema come indirizzo di interfaccia TUN locale. La tua app in genere riceve l'IP indirizzi IP e subnet mask da un gateway VPN durante l'handshake.
addRoute()
Aggiungi almeno un percorso se vuoi che il sistema invii il traffico tramite la VPN a riga di comando. Le route filtrano in base agli indirizzi di destinazione. Per accettare tutto il traffico, imposta una percorso aperto come 0.0.0.0/0 o ::/0.

Il metodo establish() restituisce un Istanza ParcelFileDescriptor utilizzata dalla tua app per leggere e scrivere da e verso il buffer dell'interfaccia. La establish() restituisce null se la tua app non è preparata o qualcuno revoca il autorizzazione.

Ciclo di vita del servizio

L'app deve monitorare lo stato della VPN selezionata dal sistema e tutte le eventuali e connessioni a Internet. Aggiorna l'interfaccia utente (UI) della tua app per far sì che la persona utilizzi sempre dispositivo a conoscenza di eventuali modifiche.

Avvio di un servizio

Il servizio VPN può essere avviato nei seguenti modi:

  • L'app avvia il servizio, in genere perché una persona ha toccato un pulsante Connetti.
  • Il sistema avvia il servizio perché la VPN sempre attiva è attiva.

L'app avvia il servizio VPN trasmettendo un intent a startService() Per ulteriori informazioni, consulta Avviare un Google Cloud.

Il sistema avvia il servizio in background chiamando onStartCommand() Tuttavia, Android pone limitazioni le app in background versione 8.0 (livello API 26) o successive. Se supporti questi ai livelli API, devi passare il servizio in primo piano chiamando Service.startForeground() Per ulteriori informazioni, consulta Esecuzione di un in primo piano.

Arresto di un servizio

Chi utilizza il dispositivo può interrompere il servizio tramite l'interfaccia utente dell'app. Interrompi anziché chiudere semplicemente la connessione. Il sistema interrompe anche connessione quando la persona che utilizza il dispositivo esegue le seguenti operazioni nella schermata VPN dell'app Impostazioni:

  • disconnette o dimentica l'app VPN
  • disattiva la VPN sempre attiva per una connessione attiva

Il sistema chiama il metodo onRevoke() del tuo servizio, ma questa chiamata potrebbero non verificarsi sul thread principale. Quando il sistema chiama questo metodo, un'interfaccia di rete alternativa sta già instradando il traffico. Puoi smaltire in sicurezza delle seguenti risorse:

VPN sempre attiva

Android può avviare un servizio VPN all'avvio del dispositivo e mantenerlo in esecuzione mentre il dispositivo è acceso. Questa funzionalità è chiamata VPN sempre attiva ed è disponibile in Android 7.0 (livello API 24) o versioni successive. Anche se Android mantiene il servizio del ciclo di vita, è il tuo servizio VPN responsabile del gateway VPN connessione. La VPN sempre attiva può anche bloccare le connessioni che non utilizzano la VPN.

Esperienza utente

In Android 8.0 o versioni successive, il sistema mostra le seguenti finestre di dialogo per Persona che usa il dispositivo per rilevare la VPN sempre attiva:

  • Quando le connessioni VPN sempre attive si disconnettono o non riescono a connettersi, le persone vedono un notifica non ignorabile. Se tocchi la notifica, viene visualizzata una finestra di dialogo spiega di più. La notifica scompare quando la VPN si riconnette o se qualcuno disattiva l'opzione VPN sempre attiva.
  • La VPN sempre attiva consente a chi usa un dispositivo di bloccare qualsiasi rete connessioni che non usano la VPN. Quando attivi questa opzione, la sezione Impostazioni l'app avvisa gli utenti che non hanno una connessione a internet prima che la VPN si connette. L'app Impostazioni chiede alla persona che utilizza il dispositivo di continuare annulla.

Poiché il sistema (e non l'utente) avvia e interrompe la connessione sempre attiva, devi adattare il comportamento e l'interfaccia utente dell'app:

  1. Disattiva le UI che scollegano la connessione perché il sistema e le Impostazioni controllare la connessione tra le app.
  2. Salva qualsiasi configurazione tra l'avvio di un'app e la configurazione di una connessione con impostazioni più recenti. Poiché il sistema avvia l'app on demand, l'utente dal dispositivo potrebbe non voler configurare una connessione.

Puoi anche utilizzare le configurazioni gestite per configurare un connessione. Le configurazioni gestite aiutano un amministratore IT a configurare la VPN da remoto.

Rilevamento sempre attivo

Android non include API per verificare se il sistema ha avviato la tua VPN completamente gestito di Google Cloud. Tuttavia, quando l'app segnala qualsiasi istanza di servizio che viene avviata, puoi presumere il sistema ha avviato i servizi non segnalati per la VPN sempre attiva. Ecco un esempio:

  1. Crea un'istanza Intent per avviare il servizio VPN.
  2. Per segnalare il servizio VPN, inserisci un extra nell'intent.
  3. Nel metodo onStartCommand() del servizio, cerca la macro negli extra dell'argomento intent.

Connessioni bloccate

Chi utilizza il dispositivo (o un amministratore IT) può forzare l'uso della VPN in tutto il traffico. Il sistema blocca tutto il traffico di rete che non utilizza la VPN. Le persone che utilizzano dispositivo può trovare l'opzione Blocca connessioni senza VPN nelle opzioni VPN in Impostazioni.

Disattiva l'opzione Sempre attiva

Se al momento la tua app non supporta la VPN sempre attiva, puoi disattivarla (su Android 8.1 o versioni successive) impostando la SERVICE_META_DATA_SUPPORTS_ALWAYS_ON metadati di servizio in false. Il seguente esempio di file manifest dell'app mostra come aggiungere l'elemento dei metadati:

<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>

Se per la tua app viene disattivata la VPN sempre attiva, il sistema disattiva la UI delle opzioni in Impostazioni.

VPN per app

Le app VPN possono filtrare le app installate che possono inviare traffico tramite Connessione VPN. Puoi creare un elenco di elementi consentiti, oppure un elenco di elementi non consentiti, ma non entrambi. Se non crei elenchi consentiti o non consentiti, il sistema invia tutto il traffico di rete tramite la VPN.

L'app VPN deve impostare gli elenchi prima di stabilire la connessione. Se cambiare gli elenchi, stabilire una nuova connessione VPN. Un'app deve essere installata sul dispositivo quando la aggiungi a un elenco.

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();

App consentite

Per aggiungere un'app all'elenco delle app autorizzate, chiama VpnService.Builder.addAllowedApplication() Se l'elenco include una o più app, solo quelle nell'elenco utilizzeranno la VPN. Tutte le altre app (non presenti nell'elenco) utilizzano le reti di sistema come se fossero la VPN non è in esecuzione. Se l'elenco di app consentite è vuoto, tutte le app usano la VPN.

App non autorizzate

Per aggiungere un'app all'elenco delle app non consentite, chiama VpnService.Builder.addDisallowedApplication() Le app non consentite usano il networking di sistema come se la VPN non fosse in esecuzione, tutti gli altri usano la VPN.

Ignora VPN

La tua VPN può consentire alle app di bypassare la VPN e selezionare la propria rete. A bypassare la VPN, chiama VpnService.Builder.allowBypass() quando la creazione di un'interfaccia VPN. Non puoi modificare questo valore dopo aver avviato servizio VPN. Se un'app non vincola il proprio processo o un socket a una specifica rete, il traffico di rete dell'app continua attraverso la VPN.

Le app che si collegano a una rete specifica non dispongono di una connessione quando qualcuno blocca il traffico che non passa attraverso la VPN. Per inviare il traffico attraverso una specifica di rete, metodi di chiamata delle app, ConnectivityManager.bindProcessToNetwork() oppure Network.bindSocket() prima di collegare la presa.

Codice di esempio

Il progetto open source Android include un'app di esempio chiamata ToyVPN. Questa app mostra come configurare e connettere un servizio VPN.