[Android Development Insights] Build Your VPN App: Insights on Developing with Android VpnManager

Introduction

In this article,
we will share insights on developing your own researched Android VPN application,
whether you are a beginner or an experienced developer,
these notes will provide practical guidance,
and we hope they will be helpful to you.

Preliminary Considerations
Thinking about how to implement it, so I first researched the native VPN encryption connection methods
  • Here are the VPN connection encryption methods available in the native Android AOSP source code:
    • PPTP
    • L2TP/IPSec PSK
    • IPSec Xauth Psk
    • IPSec IKEv2 PSK
    • L2TP/IPSec RSA
    • IPSec Xauth RSA
    • IPSec Hybrid RSA
    • IPSec IKEv2 RSA
If there is a requirement to implement VPN connection encryption mode functionality, then:
  • The official native methods provided are: VpnManager, VpnService After my research, I found:
    • If using VpnManager, it only provides some VPN connection modes and is available only in higher versions (API 30 and above)
    • If using VpnService, it only provides basic settings and does not open the connection mode interface for upper-layer use
  • VpnManager requires API 30 to use and only opens some protocols
    • Additionally, I saw on the Google issue tracker website,
      other developers have similar issues and asked the official if they could open the lower-layer connection modes for upper-layer use,
      the official personnel replied that it might be opened in the future: Click here to view
      indicating that others have similar needs, but currently, the official has no development plans
  • Previously mentioned that the official only supports some encryption methods, others have to be implemented by yourself or integrated with third-party libraries!
    This picture lists the three encryption methods supported by the official: IPSec IKEv2 PSK, IPSec IKEv2 RSA, IPSec User Pass.
    vpn_limit.png
Reference for VPN Implementation Ideas
  • If using the officially provided methods to implement, you can:
    • 'Connection Type': Set the PlatformVpnProfile through the VpnManager (API level 30 and above) method provisionVpnProfile
      • The official defines a new class PlatformVpnProfile
        • If you look at it with AOSP, the official provides this class for you to set some connection protocols Finally, when it reaches the lower-layer Service, it will help you convert it into the VpnProfile class used in the Service
        • That is, VpnManager’s line 335: provisionVpnProfile(@NonNull PlatformVpnProfile profile) Finally, it uses toVpnProfile() to help you convert PlatformVpnProfile to VpnProfile
  • Among them, Ikev2VpnProfile.Builder can set Ikev2 related connection settings. This class actually implements PlatformVpnProfile allowing you to set the open protocol mode.

  • 'VPN related settings': Through VpnService, add VpnService.Builder() when creating a local tunnel.
    • Official VpnService architecture diagram
      • This method sets the tunnel during connection, and the official only provides the method as shown in the example below for developers to use.
      • Although AOSP provides related protocol connections, it is not yet open for upper-layer use. Therefore, if you need to connect using related protocols, you need to develop it yourself.
      • Example:
        /***  Android level 14 up ***/
        val builder = VpnService.Builder()
        val localTunnel = builder
                        .setSession('VPN name')  
                        .addAddress('server', 'prefix length')
                        .addRoute('forwarding route', 'prefix length')
                        .addDnsServer('DNS server')
                        .addSearchDomain('DNS search domain')
                        .establish()
        


Implementing a VPN app through other or third-party solutions
If the methods provided by the official cannot meet the needs, you can consider:
  • AnyConnect: A third-party VPN provider. Currently, third-party vendors’ VPN services are seen.
  • (For reference) There is a solution seen online to set VpnProfile by directly using methods within the framework through reflection: Create VPN profile on Android
    • However, this method has been fixed in Android 9.0 and above, so it is speculated that some earlier phones may use this method (if the target device is before this, it can still be considered).
    • Fix announcement
  • (For reference) Third-party openVpn provides Android open source.
    • Documentation mentions support for SSL/TLS protocol (only supports this protocol).
    • Method to add openVpn to Android project: Click here
    • ics-openvpn FAQ also mentions issues with Samsung 5.0 phones.


Other Knowledge Points
  • When opening a custom VpnService through an app, in Android 8.0 and above, service operation adds background execution limits

  • Tracking android-10.0.0_r1 VpnService.java in aosp its line:176~179 uses IConnectivityManager.aidl, but currently, there is no trace of the implementation of aidl at the framework level, so it is speculated that it might be placed in something like a binder. To understand how it is implemented, further research into the underlying code is needed.

  • Tracking VpnService.Java in Android 12 aosp, its line:178~181 uses aidl changed to IVpnManager.aidl, there is another file in the source code called VpnManagerService.Java

    In line:293 the provisionVpnProfile(VpnProfile profile,...) this method requires providing a variable VpnProfile

    Looking into VpnProfile’s line:97 reveals its default connection scheme is: public int type = TYPE_PPTP

    And the connection modes that can be set in VpnProfile are:
    vpn_aosp_type.png
    However, these connection modes are currently only supported within aosp
    And because they are not open, they cannot be directly used in the app
    In summary
    Firstly, non-developers can only modify it from the phone settings
    Secondly, developers can only implement it by working from aosp

You might also enjoy