[Android開発の考え方] 自分のVPNアプリを作成する:Android VpnManager開発の考え方と心得
この投稿では、
自分で研究したAndroid VPNアプリの開発の考え方を共有します。
初心者でも経験豊富な開発者でも、
これらのノートは実用的なガイドを提供します。
皆さんの役に立てば幸いです。
- ここでは、ネイティブのAndroid AOSPソースコード内にあるVPN接続暗号化方式を見ました:
- PPTP
- L2TP/IPSec PSK
- IPSec Xauth Psk
- IPSec IKEv2 PSK
- L2TP/IPSec RSA
- IPSec Xauth RSA
- IPSec 混合 RSA
- IPSec IKEv2 RSA
- 公式のネイティブ提供方法には:VpnManager、
VpnService
調査の結果:
VpnManager
を使用する場合、一部のVpn接続モードのみが提供されており、高バージョン(API 30以上)でのみ利用可能VpnService
を使用する場合、基本的な設定のみが提供されており、上層で使用するための接続モードのインターフェースは開放されていない
VpnManager
はAPI 30以上で使用可能で、一部のプロトコルのみが開放されている- また、Googleのissue trackerサイトで、
他の開発者が類似の問題を抱えており、公式に下層の接続モードを上層で使用できるように開放してほしい
と質問しているのを見ました。
公式の回答では、将来的に開放される可能性があるとのこと:こちらをクリック
つまり、他にも同様のニーズがあるが、現時点では公式の開発予定はない
- また、Googleのissue trackerサイトで、
- 以前述べたように、公式は一部の暗号化方式のみをサポートしており、その他は自分で実装するか、サードパーティのライブラリを統合する必要があります。
この図は、公式がサポートする3つの暗号化方式を示しています:IPSec IKEv2 PSK、IPSec IKEv2 RSA、IPSec User Pass。
公式提供
の方法を使用する場合、以下のように実装できます:'接続タイプ'
:VpnManager (APIレベル30以上)のprovisionVpnProfileメソッドを使用してPlatformVpnProfile
を設定- 公式は新しいクラスPlatformVpnProfileを定義しています
- AOSPと組み合わせて見ると、公式はこのクラスを提供して
一部の接続プロトコルを設定
できるようにしています 最終的に下層のサービスに到達すると、サービスで使用されるVpnProfileクラスに変換されます - つまり、VpnManagerの
line 335
:provisionVpnProfile(@NonNull PlatformVpnProfile profile) 最終的にはtoVpnProfile()を使用してPlatformVpnProfile
をVpnProfile
に変換します
- AOSPと組み合わせて見ると、公式はこのクラスを提供して
- 公式は新しいクラスPlatformVpnProfileを定義しています
-
そのIkev2VpnProfile.BuilderはIkev2関連の接続設定を行うことができ、このクラスは実際には
PlatformVpnProfile
を実装して、オープンなプロトコルモードを設定するためのものです。 'VPN設定関連'
: VpnServiceを通じて、ローカルトンネルを作成する際にVpnService.Builder()
を追加します。- 公式の VpnServiceアーキテクチャ図
- この方法は接続時のトンネルを設定し、公式には以下の例に示す方法のみが提供されています。
- AOSPには関連するプロトコル接続が提供されていますが、
まだ公開されていません
。 したがって、関連するプロトコルで接続する必要がある場合は、自分で開発する必要があります。 - 例 :
/*** Android level 14 up ***/ val builder = VpnService.Builder() val localTunnel = builder .setSession('VPN名前') .addAddress('サーバー', 'prefix length') .addRoute('転送ルート', 'prefix length') .addDnsServer('DNSサーバー') .addSearchDomain('DNS検索ドメイン') .establish()
- 公式の VpnServiceアーキテクチャ図
- AnyConnect:サードパーティのVPNプロバイダーで、現在サードパーティのVPNサービスが見られます。
- AnyConnect公式ドキュメントには、TLS、DTLS、IPsec IKEv2などのプロトコルが提供されていると記載されています。
- 別のAnyConnectドキュメントには、IPsec IKEv2接続を使用するにはCisco Adaptive Security Appliance 8.4以上が必要と記載されています。
- このオプションを使用する場合、ベンダーと連絡を取る必要があり、開発方法や詳細を知ることができます。
- この表の下部には、各プラットフォームがサポートするトンネリングについて説明する表があります。
- AnyConnect 4.10リリースノートには、Androidバージョンに関する一部の互換性問題についても記載されています:
- 例えば、Android 5.0、6.0の省電力モードはこのサービスと競合します。
- Split DNSはAndroid 4.4またはSamsung 5.x Androidデバイスでは動作しません。
(参考)
ネット上で見つけた方法で、反射フレームワーク内のメソッドを直接使用してVpnProfileを設定する:Create VPN profile on Android- しかし、Android 9.0以上ではこの方法は修正されているため、古いデバイスではこの方法が使用されている可能性があります(対象デバイスがこれ以前の場合、検討できます)。
- 修正アナウンス
(参考)
サードパーティのopenVpnはAndroidのオープンソースを提供しています。- ドキュメントには、
SSL/TLS
プロトコルをサポートしていると記載されています(このプロトコルのみサポート
)。 - openVpnをAndroidプロジェクトに追加する方法:こちら
- ics-openvpn FAQには、Samsung 5.0デバイスの問題についても記載されています。
- ドキュメントには、
-
アプリを通じてカスタムVpnServiceを起動する際、Android 8.0以上ではサービスの動作にバックグラウンド実行制限が追加されました。
-
android-10.0.0_r1 aosp内の VpnService.javaの
line:176~179
では IConnectivityManager.aidlが使用されていますが、現在のところframework層でaidlの実装の痕跡は見つかっていません。 そのため、binderなどに置かれている可能性があり、実装方法を理解するにはさらに低レベルのコードを調査する必要があります。 -
Android 12 aosp内の VpnService.Javaの
line:178~181
ではaidlがIVpnManager.aidlに変更されています。 ソースコード内にはもう一つのファイルとしてVpnManagerService.Javaがあります。その
line:293
のprovisionVpnProfile(VpnProfile profile,...)
このメソッドは変数VpnProfileを提供することを要求します。VpnProfileの
line:97
を確認すると、そのデフォルト接続方式は:public int type = TYPE_PPTP
です。また、VpnProfileで設定可能な接続モードは以下の通りです:
ただし、これらは現在aosp内でのみサポートされています。
公開されていないため、アプリ内で直接使用することはできません。
まとめると、
一般ユーザーは携帯電話の設定から変更するしかありません。
開発者はaospから手をつけるしかありません。