VPN

Android는 개발자가 가상 사설망 (VPN)을 만들 수 있는 API를 제공합니다. 솔루션을 제공합니다 이 가이드를 읽고 나면 자체 VPN 클라이언트가 될 것입니다.

개요

VPN을 사용하면 네트워크에 물리적으로 연결되어 있지 않은 장치는 네트워크에 속합니다.

Android에는 내장 VPN 클라이언트 (PPTP 및 L2TP/IPSec)가 포함되어 있으며, 레거시 VPN입니다 Android 4.0 (API 레벨 14)에는 개발자는 자체 VPN 솔루션을 제공할 수 있습니다. 사용자가 VPN 솔루션 패키징 사용자가 기기에 설치하는 앱에 직접 연결할 수 있습니다. 개발자는 일반적으로 앱이 다음 중 한 가지 이유로 발생할 수 있습니다.

  • 내장 클라이언트에서 지원하지 않는 VPN 프로토콜을 제공하기 위해
  • 사용자가 복잡한 구성 없이 VPN 서비스에 연결할 수 있도록 지원하기 위해

이 가이드의 나머지 부분에서는 VPN 앱( 상시 사용 설정앱별 VPN)을 지원하며, 기본 제공 VPN 클라이언트가 될 수 있습니다

사용자 환경

Android는 다른 사람이 구성을 하고 시작하고 실행하는 데 도움이 되는 중지하도록 할 수 있습니다 또한 시스템 UI는 기기 사용자가 활성 VPN 연결을 인식하는 경우 Android는 다음과 같은 UI 구성요소를 보여줍니다. VPN 연결:

  • VPN 앱이 처음 활성화되기 전에 시스템에는 연결 요청 대화상자 대화상자에서는 기기 사용자에게 VPN을 신뢰하고 요청을 수락하는지 확인합니다.
  • VPN 설정 화면 (설정 > 네트워크 및 인터넷 > VPN)에는 VPN이 표시됩니다. 사용자가 연결 요청을 수락한 앱이 여기에 해당합니다. 이 버튼을 사용하여 VPN을 잊어버릴 수도 있습니다.
  • 인터넷에 연결되면 빠른 설정 트레이에 정보 패널이 활성화됨. 라벨을 탭하면 추가 정보와 링크가 있는 대화상자가 표시됩니다. 설정으로 이동합니다
  • 상태 표시줄에는 활성 연결을 나타내는 VPN(키) 아이콘이 있습니다.

또한 앱은 기기 사용자가 다음 작업을 할 수 있도록 UI를 제공해야 합니다. 서비스 옵션을 구성할 수 있습니다 예를 들어 솔루션은 계정 인증 설정을 캡처합니다 이때 앱에 다음 UI가 표시되어야 합니다.

  • 연결을 수동으로 시작하고 중지할 수 있는 컨트롤: 연결 유지 VPN 필요한 경우 연결할 수 있지만 사용자가 먼저 연결을 구성하도록 할 수 있습니다. 시간을 절약할 수 있습니다.
  • 서비스가 활성 상태일 때 닫을 수 없는 알림: 알림을 통해 연결 상태를 표시하거나 네트워크 통계와 같은 추가 정보를 제공합니다. 알림을 탭하면 앱이 포그라운드로 전환됩니다. 이 알림을 보냅니다.

VPN 서비스

앱은 사용자 (또는 직장)를 위해 시스템 네트워킹을 프로필)을 VPN 게이트웨이에 연결합니다. 각 사용자 (또는 직장 프로필)는 여러 VPN 앱이 연결되어 있습니다 시스템에서 VPN을 시작하고 이를 시작하기 위해 사용하는 VPN을 중지하고 연결 상태를 추적하세요. VPN 서비스가 VpnService

또한 서비스는 VPN 게이트웨이 연결을 위한 컨테이너 역할을 하며 로컬 기기 인터페이스를 사용해야 합니다 서비스 인스턴스 호출 VpnService.Builder 메서드를 사용하여 새 로컬 인터페이스를 설정합니다.

<ph type="x-smartling-placeholder">
</ph>
그림 1. VpnService에서 Android를 연결하는 방법 온프레미스 VPN 게이트웨이의
<ph type="x-smartling-placeholder">VpnService가 로컬 TUN을 생성하는 방식을 보여주는 블록 아키텍처 다이어그램
         시스템 네트워킹의 인터페이스입니다</ph>

앱은 다음 데이터를 전송하여 기기를 VPN 게이트웨이에 연결합니다.

  • 로컬 인터페이스의 파일 설명자에서 발신 IP 패킷을 읽고, VPN 게이트웨이로 보냅니다
  • 수신 패킷 (VPN 게이트웨이에서 수신 및 복호화)을 파일 설명자입니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.

사용자 또는 프로필당 하나의 활성 서비스만 가능합니다. 새로운 서비스를 시작할 때 자동으로 기존 서비스를 중지합니다

서비스 추가

앱에 VPN 서비스를 추가하려면 다음에서 상속받는 Android 서비스를 만듭니다. VpnService 앱에서 VPN 서비스 선언 매니페스트 파일에 다음과 같은 추가 사항이 추가됩니다.

  • BIND_VPN_SERVICE를 사용하여 서비스 보호 권한을 부여할 수 있습니다.
  • 다음과 같이 "android.net.VpnService" 인텐트 필터로 서비스를 알립니다. 시스템이 서비스를 찾을 수 있습니다

다음은 앱 manifest 파일에서 서비스를 선언하는 방법을 보여주는 예입니다.

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

이제 앱에서 서비스를 선언하므로 시스템이 자동으로 필요한 경우 앱의 VPN 서비스를 중지할 수 있습니다. 예를 들어 시스템 제어는 상시 사용 설정 VPN을 실행할 때 서비스에 대한 연결을 설정하지 않아도 됩니다.

서비스 준비

앱이 사용자의 현재 VPN 서비스가 되도록 준비하려면 다음을 호출합니다. VpnService.prepare() 기기를 사용하는 사람이 이미 앱에 권한을 부여받은 경우 메서드는 활동 인텐트를 반환합니다. 이 인텐트를 사용하여 권한을 요청하는 시스템 활동을 시작합니다. 이 시스템은 다음과 같이 다른 권한 대화상자와 유사한 대화상자를 표시합니다. 카메라 또는 연락처 액세스 권한을 설정할 수 있습니다 앱이 이미 준비되었으면 메서드가 다음을 반환합니다. null

하나의 앱만 현재 준비된 VPN 서비스가 될 수 있습니다. 항상 전화 사용자가 다른 설정을 설정했을 수 있으므로 VpnService.prepare() 앱이 마지막으로 메서드를 호출한 후 VPN 서비스로 사용할 것인지를 보여줍니다. 자세한 내용은 서비스 수명 주기 섹션을 참조하세요.

서비스 연결

서비스가 실행되면 VPN 게이트웨이에 연결됩니다 권한을 요청하고 서비스에 연결하려면 다음 순서대로 단계를 완료해야 합니다.

  1. VpnService.prepare()를 호출하여 권한을 요청합니다 (다음 합니다.
  2. VpnService.protect()를 호출하여 앱의 터널 소켓 유지 순환 연결을 피합니다
  3. DatagramSocket.connect()를 호출하여 앱의 터널 연결 연결할 수 있습니다
  4. VpnService.Builder 메서드를 호출하여 새 로컬을 구성합니다. TUN 인터페이스를 장치를 사용할 수 있습니다
  5. VpnService.Builder.establish()를 호출하여 로컬 TUN 인터페이스를 설정하고, ISP를 통해 트래픽을 라우팅하기 인터페이스에 추가되었습니다.

VPN 게이트웨이는 일반적으로 로컬 TUN 인터페이스에 대한 설정을 제안하는 동안 핸드셰이크 앱은 VpnService.Builder 메서드를 호출하여 서비스를 생성할 수 있습니다.

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

자바

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

앱별 VPN 섹션의 예는 다음을 포함한 IPv6 구성을 보여줍니다. 옵션 더보기 다음 VpnService.Builder 값을 추가해야 합니다. 다음 단계를 따르세요.

addAddress()
시스템에서 요청하는 서브넷 마스크와 함께 하나 이상의 IPv4 또는 IPv6 주소를 로컬 TUN 인터페이스 주소로 할당합니다. 앱은 일반적으로 주소와 서브넷 마스크를 구별할 수 있습니다.
addRoute()
시스템에서 VPN을 통해 트래픽을 전송하도록 하려면 경로를 1개 이상 추가하세요. 인터페이스에 추가되었습니다. 목적지 주소별로 필터를 라우팅합니다. 전체 트래픽을 허용하려면 0.0.0.0/0 또는 ::/0 등의 경로 열기

establish() 메서드는 앱이 읽고 쓰는 데 사용하는 ParcelFileDescriptor 인스턴스 통신할 수 있습니다 establish() 메서드가 준비되지 않았거나 누군가가null 권한을 부여했는지 확인합니다.

서비스 수명 주기

앱은 시스템에서 선택한 VPN 및 활성 상태의 모든 활성 상태를 추적해야 합니다. 연결을 설정할 수 있습니다 사용자가 앱을 계속 사용할 수 있도록 인식하게 됩니다.

서비스 시작

VPN 서비스는 다음과 같은 방법으로 시작될 수 있습니다.

  • 일반적으로 사용자가 연결 버튼을 탭하여 앱이 서비스를 시작합니다.
  • 연결 유지 VPN이 켜지므로 시스템이 서비스를 시작합니다.

앱은 인텐트를 전달하여 VPN 서비스를 startService() 자세한 내용은 서비스를 사용합니다.

시스템은 다음을 호출하여 백그라운드에서 서비스를 시작합니다. onStartCommand() 하지만 Android는 버전 8.0 (API 수준 26) 이상의 백그라운드 앱 이 기능을 지원하는 경우 API 레벨을 지원하려면 다음을 호출하여 서비스를 포그라운드로 전환해야 합니다. Service.startForeground() 자세한 내용은 컴퓨터에서 서비스가 포그라운드에서 실행되지 않도록 하세요.

서비스 중지

기기 사용자는 앱의 UI를 사용하여 서비스를 중지할 수 있습니다. 중지 서비스를 사용 중지할 수도 있습니다. 또한 시스템에서 활성 기기 사용자가 VPN 화면에서 다음을 수행할 때 다음 단계를 따르세요.

  • VPN 앱 연결 해제 또는 삭제
  • 활성 연결을 위한 연결 유지 VPN 끄기

시스템에서 서비스의 onRevoke() 메서드를 호출하지만 이 호출은 기본 스레드에서 발생하지 않을 수 있습니다. 시스템이 이 메서드를 호출할 때 대체 네트워크 인터페이스가 이미 트래픽을 라우팅하고 있습니다. 안전하게 폐기할 수 있습니다. 다음 리소스를 참고하세요.

연결 유지 VPN

Android는 기기가 부팅될 때 VPN 서비스를 시작하고 전원이 켜져 있는지 확인하세요. 이 기능을 연결 유지 VPN이라고 하며 다음 지역에서 사용할 수 있습니다. Android 7.0 (API 수준 24) 이상 Android가 서비스를 유지관리하고 VPN 게이트웨이를 담당하는 것은 VPN 서비스입니다 연결 또한 연결 유지 VPN은 VPN을 사용하지 않는 연결을 차단할 수 있습니다.

사용자 환경

Android 8.0 이상에서는 시스템에 다음 대화상자가 표시되어 연결 유지 VPN을 알고 있는 기기 사용자:

  • 연결 유지 VPN 연결이 해제되거나 연결할 수 없는 경우, 사람들에게 다음과 같이 표시됩니다. 닫을 수 없는 알림입니다. 알림을 탭하면 더 자세히 설명합니다. VPN이 다시 연결되거나 누군가에게 연결되면 알림이 사라집니다. 연결 유지 VPN 옵션을 사용 중지합니다.
  • 상시 사용 설정 VPN을 통해 기기 사용자가 모든 네트워크를 차단할 수 있습니다. VPN을 사용하지 않는 연결을 차단합니다. 이 옵션을 사용 설정하면 설정 앱에서 VPN을 사용하기 전에는 인터넷에 연결되어 있지 않다고 경고함 연결됩니다. 설정 앱에서 기기 사용자에게 계속하거나 취소합니다.

시스템 (사람이 아님)이 연결 유지 연결을 시작하고 중단하기 때문에 앱의 동작과 사용자 인터페이스를 조정해야 합니다.

  1. 시스템 및 설정으로 인해 연결을 끊는 모든 UI를 사용 중지합니다. 앱에서 연결을 제어합니다.
  2. 각 앱 시작 사이에 구성을 저장하고 최신 설정을 유지합니다. 시스템이 요청 시 앱을 시작하기 때문에 연결을 구성하는 것을 원하지 않을 수도 있습니다.

또한 관리 구성을 사용하여 연결 IT 관리자는 관리 구성을 사용하여 VPN을 원격으로 구성할 수 있습니다.

연결 유지 감지

Android에는 시스템에서 VPN을 시작했는지 확인하는 API가 포함되어 있지 않습니다. 있습니다. 그러나 앱이 시작하는 서비스 인스턴스에 플래그를 지정하면 상시 사용 설정 VPN에 대해 시스템이 플래그 지정되지 않은 서비스를 시작했다는 것을 의미합니다. 예를 들면 다음과 같습니다.

  1. VPN 서비스를 시작하기 위한 Intent 인스턴스를 생성합니다.
  2. 인텐트에 엑스트라를 추가하여 VPN 서비스에 플래그를 지정합니다.
  3. 서비스의 onStartCommand() 메서드에서 intent 인수의 extras에 플래그를 지정합니다.

차단된 연결

기기 사용자(또는 IT 관리자)는 전체 트래픽이 VPN을 사용하도록 할 수 있습니다. 시스템은 VPN을 사용하지 않는 네트워크 트래픽을 차단합니다. 사용자 기기의 VPN 옵션에서 VPN 없는 연결 차단 스위치를 찾을 수 있습니다. '설정' 패널을 클릭합니다.

연결 유지 선택 해제

앱에서 현재 연결 유지 VPN을 지원할 수 없는 경우 선택 해제할 수 있습니다 (Android 8.1 이상)에서 SERVICE_META_DATA_SUPPORTS_ALWAYS_ON 드림 서비스 메타데이터를 false에 전송합니다. 다음 앱 매니페스트 예에서는 메타데이터 요소:

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

앱에서 연결 유지 VPN을 선택 해제하면 시스템이 옵션 UI를 사용 중지합니다. 제어 기능을 사용할 수 있습니다.

앱별 VPN

VPN 앱은 설치된 앱 중에 SSL을 통해 트래픽을 전송할 수 있는 앱을 필터링할 수 있습니다. VPN 연결 허용 목록 또는 허용되지 않는 목록을 만들 수 있습니다. 둘 다일 수는 없습니다 허용 목록 또는 허용되지 않는 목록을 만들지 않으면 시스템에서 VPN을 통해 모든 네트워크 트래픽을 허용합니다

VPN 앱에서 연결을 설정하기 전에 먼저 목록을 설정해야 합니다. 만약 새 VPN 연결을 설정해야 한다는 것을 의미합니다. 앱은 다음과 같아야 합니다. 기기에 설치된 앱만 명시합니다.

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

자바

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

허용된 앱

허용 목록에 앱을 추가하려면 다음을 호출합니다. VpnService.Builder.addAllowedApplication() 만약 목록에 앱이 하나 이상 포함된 경우 목록에 있는 앱만 VPN을 사용합니다. 목록에 없는 다른 모든 앱은 확인할 수 있습니다 허용 목록이 비어 있으면 모든 앱이 VPN을 사용합니다.

허용되지 않는 앱

허용되지 않는 목록에 앱을 추가하려면 VpnService.Builder.addDisallowedApplication() 허용되지 않는 앱은 VPN이 실행되지 않는 것처럼 시스템 네트워킹을 사용합니다. VPN을 사용하는 것을 볼 수 있습니다.

VPN 우회

VPN에서는 앱이 VPN을 우회하고 자체 네트워크를 선택하도록 허용할 수 있습니다. 받는사람 VPN을 우회할 수 없습니다. 다음의 경우 VpnService.Builder.allowBypass()를 호출합니다. VPN 인터페이스를 설정하는 것입니다 시작 후에는 이 값을 변경할 수 없습니다. VPN 서비스. 앱이 프로세스나 소켓을 특정 앱의 네트워크 트래픽은 VPN을 통해 계속됩니다.

특정 네트워크에 바인딩되는 앱은 누군가가 VPN을 통과하지 않는 트래픽을 차단합니다. 특정 웹 서버를 통해 트래픽을 네트워크, 앱은 다음과 같은 메서드를 호출합니다. ConnectivityManager.bindProcessToNetwork() 또는 Network.bindSocket()로 설정합니다.

샘플 코드

Android 오픈소스 프로젝트에는 ToyVPN이라는 샘플 앱이 포함되어 있습니다. 이 앱은 VPN 서비스를 설정하고 연결하는 방법을 보여줍니다.