Sieć VPN

Android udostępnia deweloperom interfejsy API do tworzenia wirtualnej sieci prywatnej (VPN) i rozwiązania. Z tego przewodnika dowiesz się, jak tworzyć i testować własne własnego klienta VPN dla urządzeń z Androidem.

Omówienie

Sieci VPN umożliwiają bezpieczny dostęp urządzeniom, które nie są fizycznie połączone z siecią

Android ma wbudowanego klienta VPN (PPTP i L2TP/IPSec), który czasami o starszej wersji VPN. W Androidzie 4.0 (poziom API 14) wprowadziliśmy interfejsy API, mogą dostarczać własne rozwiązania VPN. Przygotowujesz rozwiązanie VPN w pakiecie w aplikację, którą użytkownicy instalują na urządzeniu. Deweloperzy zwykle tworzą sieć VPN aplikacji z jednego z tych powodów:

  • aby zapewnić protokoły VPN, których nie obsługuje wbudowany klient;
  • aby umożliwić innym skorzystanie z usługi VPN bez skomplikowanej konfiguracji;

W pozostałej części tego przewodnika znajdziesz informacje o tworzeniu aplikacji VPN (w tym zawsze włączone i na aplikację) oraz nie obejmuje z wbudowanym klientem VPN.

Interfejs użytkownika

Android ma interfejs użytkownika, który pomaga skonfigurować, uruchomić zatrzymać usługę VPN. Interfejs systemu sprawia też, że osoba korzystająca z urządzenia aktywne połączenie VPN. Android przedstawia te komponenty interfejsu dla: Połączenia VPN:

  • Zanim aplikacja VPN zostanie aktywowana po raz pierwszy, system wyświetli okno z prośbą o połączenie. Okno z prośbą o wykonanie potwierdzić, że ufa sieci VPN, i zaakceptować prośbę.
  • Na ekranie ustawień VPN (Ustawienia > Sieć i internet > VPN) widać, jaka jest sieć VPN w których użytkownik zaakceptował prośby o połączenie. Przycisk konfiguracji opcje systemowe lub zapomnisz VPN.
  • W obszarze Szybkich ustawień wyświetla się panel informacyjny, gdy połączenie jest aktywne aktywne. Po kliknięciu etykiety wyświetli się okno z dodatkowymi informacjami i linkiem. otwórz Ustawienia.
  • Pasek stanu zawiera ikonę VPN (klucza), która wskazuje, że połączenie jest aktywne.

Aplikacja musi również mieć interfejs, aby użytkownik urządzenia mógł skonfigurować opcje usługi. Twoje rozwiązanie może na przykład wymagać: rejestrować ustawienia uwierzytelniania konta. Aplikacje powinny wyświetlać taki interfejs użytkownika:

  • Sterowanie ręczne rozpoczynanie i zatrzymywanie połączenia. Stały VPN może się łączyć w razie potrzeby, ale umożliwiać użytkownikom skonfigurowanie połączenia w pierwszej kolejności podczas korzystania z sieci VPN.
  • Powiadomienie, którego nie można zamknąć, gdy usługa jest aktywna. Takie powiadomienie może wyświetlać stan połączenia ani podawać dodatkowych informacji, np. statystyk sieci. Kliknięcie powiadomienia powoduje wyświetlenie aplikacji na pierwszym planie. Usuń powiadomienie, gdy usługa stanie się nieaktywna.

Usługa VPN

Aplikacja łączy sieć systemową użytkownika (lub środowisko profilu) do bramy VPN. Każdy użytkownik (lub profil służbowy) może uruchomić inną aplikację VPN. Tworzysz usługę VPN, której system używa do uruchamiania zatrzymać VPN i śledzić stan połączenia. Twoja usługa VPN dziedziczy z: VpnService

Usługa działa również jako kontener dla połączeń z bramą VPN oraz lokalnych interfejsów urządzeń. Wywołanie instancji usługi VpnService.Builder, aby stworzyć nowy interfejs lokalny.

Rysunek 1. Jak VpnService łączy Androida połączenie sieciowe z bramą VPN
Diagram architektury blokowej pokazujący, jak VpnService tworzy lokalną jednostkę TUN
         za pomocą interfejsu sieci
systemowej.

Aby połączyć urządzenie z bramą VPN, aplikacja przesyła te dane:

  • Odczytuje wychodzące pakiety IP z deskryptora plików interfejsu lokalnego, szyfruje i wysyła je do bramy sieci VPN.
  • Zapisuje pakiety przychodzące (odebrane i odszyfrowane z bramy VPN) w deskryptora pliku interfejsu lokalnego.
.

Każdy użytkownik lub profil może mieć tylko 1 aktywną usługę. Uruchomienie nowej usługi, automatycznie zatrzymuje istniejącą usługę.

Dodaj usługę

Aby dodać usługę VPN do swojej aplikacji, utwórz usługę na Androida dziedziczoną z VpnService Zadeklarowanie usługi VPN w aplikacji plik manifestu z tymi dodatkami:

  • Chroń usługę za pomocą BIND_VPN_SERVICE , dzięki czemu tylko system może utworzyć powiązanie z Twoją usługą.
  • Zareklamuj usługę za pomocą filtra intencji "android.net.VpnService", aby system może znaleźć Twoją usługę.

Ten przykład pokazuje, jak zadeklarować usługę w pliku manifestu aplikacji:

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

Po zadeklarowaniu usługi przez aplikację system może się automatycznie uruchomić i w razie potrzeby zatrzymuje działanie usługi VPN w aplikacji. Na przykład elementy sterujące systemem z usługi, gdy masz zawsze włączoną sieć VPN.

Przygotowywanie usługi

Aby przygotować aplikację, aby stała się aktualną usługą VPN użytkownika, wywołaj VpnService.prepare() Jeśli użytkownik urządzenia nie aplikacji, która otrzymała już uprawnienia do działania, metoda zwraca intencję związaną z aktywnością. Za pomocą tej intencji rozpoczynasz aktywność systemową, która prosi o uprawnienia. system wyświetla okno podobne do innych okien uprawnień, dostęp do aparatu lub kontaktów. Jeśli aplikacja jest już przygotowana, metoda zwraca null

Aktualnie gotową usługą VPN może być tylko 1 aplikacja. Zawsze dzwoń VpnService.prepare(), ponieważ ktoś mógł ustawić inne wartości aplikacji jako usługi VPN od czasu ostatniego wywołania tej metody przez aplikację. Więcej informacji: sekcji Cykl życia usługi.

Połącz usługę

Po uruchomieniu usługi możesz ustanowić nowy interfejs lokalny, połączone z bramą VPN. Aby poprosić o odpowiednie uprawnienia i połączyć się z usługą bramy VPN, musisz wykonać te czynności w tej kolejności:

  1. Zadzwoń pod numer VpnService.prepare(), aby poprosić o zgodę (gdy ).
  2. Wywołaj VpnService.protect(), aby zachować gniazdo tunelu aplikacji poza systemową siecią VPN i unikaj połączenia okrężnego.
  3. Zadzwoń pod numer DatagramSocket.connect(), aby połączyć tunel aplikacji i połączenia z bramą VPN.
  4. Wywołaj metody VpnService.Builder, aby skonfigurować nowy obiekt lokalny Interfejs TUN w na potrzeby ruchu w sieci VPN.
  5. Wywołaj metodę VpnService.Builder.establish(), aby system tworzy lokalny interfejs TUN i rozpoczyna kierowanie ruchu przez za pomocą prostego interfejsu online.

Brama VPN zwykle sugeruje ustawienia dla lokalnego interfejsu TUN podczas uzgadnianie połączenia. Aplikacja wywołuje metody VpnService.Builder, aby skonfigurować zgodnie z poniższym przykładem:

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

Przykład w sekcji Sieć VPN dla poszczególnych aplikacji pokazuje konfigurację IPv6 zawierającą więcej opcji. Musisz dodać te wartości parametru VpnService.Builder przed utworzeniem nowego interfejsu:

addAddress()
Dodaj co najmniej 1 adres IPv4 lub IPv6 wraz z maską podsieci określoną przez system jest ustawiany jako lokalny adres interfejsu TUN. Twoja aplikacja zwykle otrzymuje adres IP adresów i masek podsieci z bramy VPN podczas uzgadniania połączenia.
addRoute()
Dodaj co najmniej jedną trasę, jeśli chcesz, by system kierował ruch przez VPN za pomocą prostego interfejsu online. Trasy są filtrowane według adresów docelowych. Aby akceptować cały ruch, ustaw parametr otwarta trasa, np. 0.0.0.0/0 lub ::/0.

Metoda establish() zwraca błąd ParcelFileDescriptor instancja używana przez aplikację do odczytu i zapisu do i z bufora interfejsu. establish() zwraca null, jeśli aplikacja nie jest przygotowana lub ktoś anuluje uprawnienia.

Cykl życia usługi

Aplikacja powinna śledzić stan wybranej przez system sieci VPN i wszystkich aktywnych połączeń. Zaktualizuj interfejs aplikacji, aby zachować użytkownika urządzenie wiedzą o wszelkich zmianach.

Uruchamianie usługi

Usługę VPN można uruchomić na kilka sposobów:

  • Aplikacja uruchamia usługę – zwykle dlatego, że ktoś kliknął przycisk połączenia.
  • System uruchamia usługę, ponieważ zawsze włączona sieć VPN jest włączona.

Aplikacja uruchamia usługę VPN, przekazując intencję do startService() Więcej informacji znajdziesz w sekcji Rozpoczynanie usługi.

System uruchamia usługę w tle, wywołując onStartCommand() Android nakłada jednak ograniczenia aplikacje działające w tle w wersji 8.0 (poziom interfejsu API 26) lub nowszego. Jeśli je obsługujesz API, musisz przenieść usługę na pierwszy plan, wywołując Service.startForeground() Więcej informacji znajdziesz w sekcji Uruchamianie usługi na pierwszym planie.

Zatrzymywanie usługi

Osoba używająca urządzenia może zatrzymać usługę, korzystając z interfejsu aplikacji. Zatrzymaj usługi zamiast tylko zamknięcia połączenia. System zatrzymuje też aktywną połączenia, gdy osoba używająca urządzenia wykona te czynności na ekranie VPN w aplikacji Ustawienia:

  • odłącza lub zapomina aplikację VPN
  • wyłącza stały VPN, aby połączenie było aktywne;

System wywołuje metodę onRevoke() usługi, ale to wywołanie może nie mieć miejsca w wątku głównym. Po wywołaniu tej metody przez system alternatywny interfejs sieci kieruje już ruch. Możesz bezpiecznie wyrzucić urządzenie do utylizacji z tych materiałów:

Stały VPN

Android może uruchomić usługę VPN po włączeniu urządzenia i nie przerywać działania urządzenie jest włączone. Ta funkcja nazywa się stały VPN i jest dostępna Androida 7.0 (poziom interfejsu API 24) lub nowszego. Android utrzymuje usługę, cykl życia, to Twoja usługa VPN odpowiada za bramę sieci VPN połączenia. Zawsze włączona sieć VPN może też blokować połączenia, które nie korzystają z tej sieci.

Interfejs użytkownika

W Androidzie 8.0 lub nowszym system wyświetla te okna, osoba używająca urządzenia wie o stałej sieci VPN:

  • Gdy połączenia ze stałą siecią VPN rozłączają się lub nie mogą się połączyć, użytkownicy widzą komunikat powiadomienia, którego nie można zamknąć. Po dotknięciu powiadomienia wyświetli się okno, i dowiedz się więcej. Powiadomienie znika po ponownym połączeniu z siecią VPN lub po ponownym połączeniu z siecią VPN wyłącza opcję stałego VPN.
  • Zawsze włączona sieć VPN umożliwia osobie korzystającej z urządzenia blokowanie dowolnej sieci które nie korzystają z sieci VPN. Gdy włączysz tę opcję, sekcja Ustawienia ostrzega użytkowników, że nie mają połączenia z internetem przed VPN nawiązuje połączenie. aplikacja Ustawienia poprosi osobę korzystającą z urządzenia o kontynuowanie; anuluj.

System (a nie osoba) uruchamia i zatrzymuje stałe połączenie, musisz dostosować działanie aplikacji i jej interfejs:

  1. Wyłącz wszystkie UI, które rozłączają połączenie, ponieważ system i ustawienia kontrolować połączenie przez aplikację.
  2. Zapisz konfigurację po każdym uruchomieniu aplikacji i skonfiguruj połączenie za pomocą najnowsze ustawienia. System uruchamia aplikację na żądanie, użytkownik nie zawsze będzie chciał skonfigurować połączenie.

Możesz też użyć konfiguracji zarządzanych do skonfigurowania połączenia. Konfiguracje zarządzane pomagają administratorowi IT zdalnie konfigurować sieć VPN.

Wykrywaj zawsze włączone

Android nie zawiera interfejsów API sprawdzających, czy system uruchomił Twoją sieć VPN posprzedażna. Jednak gdy aplikacja oflaguje uruchamiające się instancje usługi, można przyjąć, że system uruchomił nieoznaczone usługi dla stałej sieci VPN. Na przykład:

  1. Aby uruchomić usługę VPN, utwórz instancję Intent.
  2. Oznacz usługę VPN, dodając parametr do intencji.
  3. W metodzie onStartCommand() usługi znajdź flagę w dodatkach argumentu intent.

Zablokowane połączenia

Osoba używająca urządzenia (lub administrator IT) może wymusić korzystanie z VPN przez cały ruch. System blokuje cały ruch w sieci, który nie korzysta z VPN. Osoby korzystające z urządzenie może znaleźć przełącznik Blokuj połączenia bez VPN w opcjach sieci VPN. w Ustawieniach.

Rezygnowanie ze stałego włączenia

Jeśli Twoja aplikacja nie obsługuje obecnie stałego VPN, możesz zrezygnować z tej funkcji (na Androidzie 8.1 lub nowszej), ustawiając SERVICE_META_DATA_SUPPORTS_ALWAYS_ON metadanych usługi false. Ten przykład pliku manifestu aplikacji pokazuje, jak dodać należy dodać element metadanych:

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

Gdy Twoja aplikacja zrezygnuje ze stałego VPN, system wyłączy interfejs opcji. w Ustawieniach.

VPN dla poszczególnych aplikacji

Aplikacje VPN mogą określać, które zainstalowane aplikacje mogą wysyłać ruch przez Połączenie VPN. Możesz utworzyć listę dozwolonych lub niedozwolonych, ale nie w obu przypadkach. Jeśli nie utworzysz list dozwolonych lub niedozwolonych, system wysyła cały ruch w sieci przez VPN.

Aplikacja VPN musi ustawić listy przed nawiązaniem połączenia. Jeśli musisz zmienić listy, nawiązać nowe połączenie VPN. Aplikacja musi być instalowane na urządzeniu po dodaniu do listy.

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

Aplikacje dozwolone

Aby dodać aplikację do listy dozwolonych, wywołaj VpnService.Builder.addAllowedApplication() Jeśli lista zawiera co najmniej 1 aplikację, korzystają z niej tylko aplikacje z listy. Wszystkie inne aplikacje (których nie ma na liście) używają sieci systemowych tak samo jak VPN nie jest uruchomiony. Gdy lista dozwolonych jest pusta, wszystkie aplikacje używają sieci VPN.

Aplikacje niedozwolone

Aby dodać aplikację do listy niedozwolonych, wywołaj VpnService.Builder.addDisallowedApplication() Niedozwolone aplikacje korzystają z sieci systemowej tak, jakby sieć VPN nie była uruchomiona. Pozostałe aplikacje aplikacje używają sieci VPN.

Omijaj VPN

Twoja sieć VPN może zezwalać aplikacjom na omijanie VPN i wybieranie własnej sieci. Do ominąć VPN, zadzwoń pod numer VpnService.Builder.allowBypass(), gdy ustanawiasz interfejs VPN. Nie można zmienić tej wartości po rozpoczęciu Usługa VPN. Jeśli aplikacja nie wiąże swojego procesu lub gniazda z konkretnym ruch sieciowy aplikacji jest kontynuowany przez VPN.

Aplikacje powiązane z konkretną siecią nie mają połączenia, gdy ktoś blokuje ruch, który nie przechodzi przez VPN. Aby kierować ruch przez określoną metod wywoływania przez aplikacje, takich jak ConnectivityManager.bindProcessToNetwork() lub Network.bindSocket().

Kod demonstracyjny

Projekt Android Open Source zawiera przykładową aplikację o nazwie ToyVPN. Ta aplikacja pokazuje, jak skonfigurować i połączyć usługę VPN.