Android 앱이 시스템 VPN 프로필을 추가할 수 없는 이유
VpnService는 앱이 소유한 터널을 만들지만, 휴대폰의 PPTP, L2TP, IPsec 항목을 추가하거나 편집할 수는 없습니다. 경계를 따라가며 올바른 길을 고르세요.
설정에서 VPN 행을 탭하고, 다른 사람이 설치한 프로필을 보고, 그것을 추가하는 호출을 찾기 시작합니다. 그런 호출은 없습니다. 앱은 VpnService를 통해 자체 터널을 열 수 있지만, 그 목록의 항목은 플랫폼과 그것을 만든 클라이언트의 것입니다. 경계가 어디인지 정확히 아는 것이 숨은 클래스를 쫓는 일주일을 아껴 줍니다.
설정 화면이 보여 주는 것부터 시작하세요
VPN 목록은 시스템이나 제조사 클라이언트가 설치한 프로필의 등록부입니다. PPTP, L2TP/IPsec, IKEv2, 그리고 OEM 앱이나 MDM이 밀어 넣은 행들이 있습니다. 각 행은 서버 주소, 자격 증명, 그리고 여러분의 프로세스 밖에서 사는 프로토콜 구현을 담고 있습니다. 사용자가 거기서 연결을 탭하면 터널을 올리는 것은 플랫폼 클라이언트이지 여러분의 코드가 아닙니다. 그래서 그 행은 재부팅 후에도 남고, 앱을 삭제해도 결코 사라지지 않습니다.
사용자 쪽에서 보면 목록은 API 표면처럼 보입니다. VPN 추가가 인텐트 하나 거리에 있어야 할 곳처럼요. 그렇지 않습니다. 그것을 건드리는 유일한 공개 진입점은 탐색 인텐트이고, 거기에 쓰는 모든 것은 플랫폼이나 권한 있는 구성 요소의 것입니다.
실질적인 결과: 지원 문서가 사용자에게 설정에서 프로필을 추가하라고 한다면, 여러분의 앱은 그 흐름의 일부가 전혀 아닙니다.
VpnService가 실제로 주는 것
VpnService와 VpnService.Builder는 앱이 소유한 하나의 터널을 설명합니다. 주소, 경로, DNS 서버, MTU를 추가하고, addAllowedApplication() 또는 addDisallowedApplication()으로 트래픽 범위를 정하고, 그러면 establish()가 TUN 인터페이스용 ParcelFileDescriptor를 반환합니다. 그 시점부터 앱은 IP 패킷을 읽고 응답을 씁니다. 즉 프로토콜을 구현하거나 내장하는 것은 여러분의 몫입니다. OpenVPN, WireGuard, 자체 전송 방식 등입니다.
그 순서 어디에도 PPTP, L2TP/IPsec, IKEv2는 나오지 않습니다. Builder에는 시스템 L2TP 클라이언트를 쓰라고 말하는 스위치가 없고, 플랫폼이 이미 소유한 프로필을 조종할 수 있는 콜백도 없습니다. 이것이 진짜 경계이며, 권한의 틈이 아니라 설계의 경계입니다.
그래서 앱은 Android에서 충분히 VPN 클라이언트가 될 수 있습니다. 다만 휴대폰과 함께 오는 클라이언트의 관리자가 될 수는 없습니다.
동의 대화상자는 장식이 아닙니다
여러분의 터널은 다른 앱의 트래픽을 가로챌 수 있으므로, 시스템은 사용자가 그것을 명시적으로 승인하도록 요구합니다. prepare()는 여러분이 실행해야 하는 Intent를 반환하고, 승인은 여러분의 패키지에 묶이며, 터널이 켜져 있는 동안 상태 표시줄에는 상시 표시가 나옵니다. 두 번째 VPN이 올라오면 첫 번째는 비활성화됩니다. Android는 한 번에 하나의 활성 VPN만 실행하기 때문입니다.
이 하나만 활성 규칙은 테스트에서 사람들을 넘어뜨립니다. 회사 클라이언트가 연결된 상태에서 자기 터널을 올리고 코드가 망가졌다고 결론짓지만, 실제로는 플랫폼이 다른 클라이언트에서 전환한 것뿐입니다. 승인은 나중에 철회될 수 있고, 승인 액티비티가 없는 기기에서는 prepare()가 null을 돌려줄 수 있으므로 establish()는 여전히 실패를 처리해야 합니다.
숨은 API와 설정 인텐트
오래된 답변은 내장 클라이언트가 쓰는 com.android.internal 클래스와 AIDL 인터페이스를 가리킵니다. 그것들은 SDK에 없고, 릴리스 사이에 예고 없이 바뀌며, 앱 스토어는 그 접근을 위험으로 봅니다. 기기를 루팅해도 안정되지 않습니다. 루트와 숨은 API 접근은 서로 무관한 문제이기 때문입니다.
지원되는 탐색 도우미는 Settings.ACTION_VPN_SETTINGS이며 그 값은 android.net.vpn.SETTINGS입니다. 실행 전에 해석하세요. 일부 OEM 빌드는 그 액티비티를 넣지 않으므로, 해석에 실패하면 문서화된 단계로 대체하세요. 그것은 사용자를 화면으로 데려갈 뿐 아무것도 설정하지 않습니다.
기기 소유자와 MDM 경로는 사람들이 보통 말하는 예외입니다. DevicePolicyManager는 상시 연결 VPN 패키지를 지정할 수 있고, 관리형 구성은 그것을 지원하는 클라이언트에 설정을 미리 넣을 수 있지만, 그것은 여전히 공개 SDK가 PPTP 프로필을 작성하는 것이 아닙니다.
사용자 쪽에서 결정을 따라가 보세요
제품이 트래픽을 실어 날라야 한다면 VpnService와 실제 프로토콜 스택을 계획하고, 승인 흐름과 단일 VPN 규칙에 시간을 배정하세요. 목표가 기존 회사 프로필에 연결하는 것이라면 여러분의 일은 안내입니다. 설정 화면으로의 딥 링크, 항목 문서화를 하고, 터널링은 플랫폼 클라이언트가 하게 두세요. 앱이 개인 엔드포인트에 도달하기만 하면 된다면 자체 터널은 전혀 필요 없습니다.
코드를 쓰기 전에 그 결정을 적어 두세요. 세 갈래 길은 첫 스프린트가 지나면 거의 공통점이 없습니다.
시작 전 마지막 점검: 요구사항은 우리 앱이 연결한다고 말합니까, 기기가 연결한다고 말합니까? 전자는 VpnService이고 후자는 여러분이 만들 수 없는 프로필입니다. 그 문장을 바로잡는 것이 어떤 리팩터링보다 쌉니다.