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.
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.
È 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:
- Chiama il numero
VpnService.prepare()
per chiedere l'autorizzazione (quando necessaria). - Chiama
VpnService.protect()
per mantenere il socket del tunnel della tua app all'esterno della VPN di sistema ed evita una connessione circolare. - Chiama
DatagramSocket.connect()
per connettere il tunnel della tua app al gateway VPN. - Chiama i metodi
VpnService.Builder
per configurare un nuovo locale nell'interfaccia TUN dispositivo per il traffico VPN. - 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:
- Chiudi il socket del tunnel protetto per il gateway VPN chiamando
DatagramSocket.close()
- Chiudi il descrittore del file di particella (non è necessario svuotarlo) richiamando
ParcelFileDescriptor.close()
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:
- Disattiva le UI che scollegano la connessione perché il sistema e le Impostazioni controllare la connessione tra le app.
- 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:
- Crea un'istanza
Intent
per avviare il servizio VPN. - Per segnalare il servizio VPN, inserisci un extra nell'intent.
- Nel metodo
onStartCommand()
del servizio, cerca la macro negli extra dell'argomentointent
.
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.