Android VpnServiceの和訳
先日ルート化せずにパケットキャプチャが可能なtPacketCaptureをリリースしました。
tPacketCaptureは、Android4.0で追加されたVPNに関する機能を利用しています。しかしながらこのVPNに関する技術的な説明は、VpnServiceクラスに書いてあるのみです。
少しでも参考になればと思い、和訳+αとしてVpnServiceについての解説をします。
和訳の前に、VpnServiceを使うことで実現できできそうな機能を考えてみます。
そもそも、VPN(Virtual Private Network)自体はICS以前のAndroidでも利用可能でした。
しかし、システムの設定として利用するVPNでは、アプリケーションごとに合わせたカスタマイズができませんでした。
そこでICSから、VpnServiceクラスが提供され、VPNを利用するアプリケーションを作成できるようになりました。
特に企業向けアプリケーションで利用することを想定しているようです。
VpnServiceを利用すれば、パケットを全て監視することが可能になります。
そのため、以下の様な機能も作れます。
- 通信先IPによって、VPNサーバを利用するか自動で切り替える(VPN経由でアクセスできないサーバへは直接接続する)
- 通信先IPによるフィルタ機能の実現(マルウェアの通信を完全にシャットアウト)
その他にもいろいろ発展しそうです。
以下、リファレンスの和訳になります。
Android Developers VpnService:
http://developer.android.com/intl/ja/reference/android/net/VpnService.html
VpnServiceは、独自にVPN機能を拡張したり、構築するときに利用できるベースクラスです。
一般的に、VpnServiceが、Vertual Networkインタフェースの作成、アドレス設定、ルーティング設定、そしてディスクリプタの返却を実施します。
ディスクリプタから読み出すことにより、インタフェースに送られた送信パケットを取り扱えます。
ディスクリプタに書き込むことにより、インタフェースが受信したかのように、パケットを追加することができます。
インタフェースはInternet Protocol(IP)上で動作していますので、全てのパケットはIPヘッダーで始まっています。
トンネルを通して遠隔サーバとパケットを交換し処理を行うことで、アプリケーションはVPN接続を実現できます。
アプリケーションにパケットを渡すことで、セキュリティ的な危険が出てきます。
VPNアプリケーションは簡単にネットワークを切断することができます。
加えて、2つのVPNアプリケーションが存在する場合、お互いに干渉するでしょう。
システム側ではこれらの問題に対応する為、いくつかの動作を行います。
ポイントを以下に示します。
- VPN接続を行うためには、ユーザの操作が必要です(図1)
- 一度に1つのVPN接続しか存在できません。新しい接続が作られるときには、古い接続が無効にされます
- VPN接続を行っている間は、システムがノーティフィケーションを表示します(図2)
- 現在のVPN接続の情報を提供するダイアログを、システムが提供します。切断のボタンもついています(図3)
- ファイルディスクリプタが閉じられた時でも、ネットワークは自動的に再接続されます。これは、VPNアプリケーションがシステムにkillされた場合も同様になります
このVpnServiceクラスには、2つの主要なメソッドがあります。
prepare(Context) と establish()です。
前者は、ユーザの操作を取り扱ったり、他のアプリケーションによって生成され
たVPN接続を停止します。
後者は、VpnService.Builderにパラメータを渡すことで、VPNインタフェースを
生成します。
アプリケーションは、必ずprepare(Context)を呼ばなければなりません。
このことにより、本クラスの他のメソッドを使用することを許可でき、また、い
つでも許可を無効にすることができます。
VPN接続を生成するための一般的な手順を以下に示します。
- 接続のボタンをユーザが押した時、prepare(Context)が呼ばれ返されたintentで起動します
- アプリケーションの準備ができた時点でServiceが開始されます
- 遠隔サーバに呈してトンネルが生成され、VPN接続のためにネットワークパラメータをやり取りします
- これらのパラメータをVpnService.Builderに渡し、establish()を呼び出すことでVPNインタフェースが生成されます
- トンネルと返されたファイルディスクリプタの間で、処理やパケットの交換を実施してください
- onRevoke()が呼び出された時、ファイルディスクリプタはcloseされ、トンネルは直ぐに切断されます
このクラスを継承したServiceはパーミッションとintent-filterを必要とします。
BIND_VPN_SERVICE パーミッションによりServiceは保護されなければならないし、intent-filterはSERVICE_INTERFACEアクションに一致しなければいけません。
AndroidManifest.xmlに記載するVPNサービスの定義例を以下に示します。
<service android:name=".ExampleVpnService"android:permission="android.permission.BIND_VPN_SERVICE"><intent-filter><action android:name="android.net.VpnService"/></intent-filter></service>
このVpnServiceは4.0リリース直後のエミュレータだと動作しませんでしたが、最新のエミュレータでは動作させる事が可能です。
ブログ内の関連する記事
- tPacketCaptureのスレがxdaにできました。
- 非root端末で動くパケットキャプチャアプリtPacketCaptureを高速化(当社比3倍)しました
- 世界初!!非root端末でパケットキャプチャが行えるtPacketCaptureを公開しました
コメント
コメントを投稿