TAP か TUN か。Android の OpenVPN クライアントとブリッジ構成のサーバー
TAP はイーサネットフレームを運び、TUN は IP パケットを運びます。Android アプリが受け取るのは後者だけです。両者を比べ、次にサーバー側を直します。
ノート PC で動くプロファイルがスマートフォンでは失敗する。明らかな対処はクライアント設定の一語を書き換えることだ。その一語では解決しない、両端が同じ種類のトラフィックを話していないからだ。
TAP はイーサネットフレームを運ぶ。TUN は IP パケットを運ぶ。Android の VPN アプリに渡されるのは IP インターフェースであり、設定が何と言おうと、二つの構成のうち片方だけが可能になる。
比較は短いが、スマートフォン側で直せるのか、サービスを変える必要があるのかを決める。
ペイロードが異なる二種類のトンネル
TAP インターフェースはイーサネットアダプターのように振る舞う。フレームを運ぶため、ARP、ブロードキャスト、IP より下で LAN が運ぶものすべてを含む。これがブリッジを可能にする——トンネルがブロードキャストドメインを広げ、クライアントはスイッチにつながっているかのように振る舞う。
TUN インターフェースは自分宛ての IP パケットを運ぶ。交渉すべきリンク層も、ARP も、ブロードキャストもない。何がトンネルに入るかはルーティングが決め、サーバー側の設定はブリッジではなくサブネットを使う。
両端はどちらを行うのかで合意していなければならないが、片側で dev tap を dev tun に変えてもサービスは変換されない。ルーティングされたトンネルを期待するクライアントと、いまだにフレームを送るサーバーが生まれ、ハンドシェイクは成功しても使えるものは何も通らない。
Android がアプリに実際に渡すもの
プラットフォームの VpnService API は、アドレス、ルート、MTU で構成される IP パケット用の仮想インターフェースをアプリに渡す。その API にイーサネットアダプターはなく、アプリがそれをでっち上げる方法もない。
だからこそ OpenVPN Connect は、Android では TAP ブリッジではなくルーティングされた TUN 接続の対応を文書化している。Android の FAQ はこの境界についてのクライアント側の表明であり、プラットフォームの API と一致する。
root 権限のネットワークツール、独自ファームウェア、明示的な変換層を実装した製品は別の構成だ。普通のケースはこちらを前提に計画すべきだ——ファイルを取り込んで通常のユーザーとして動くアプリで、IP インターフェースがあり、その下には何もない。
それでも試すとどう見えるか
接続はたいてい確立する。だからこそ失敗は紛らわしい——クライアントは接続済みと報告し、サーバーログにはピアが現れ、どのアプリケーションも動かない。
スマートフォンに割り当てられたアドレス宛てのトラフィックは届かない、サーバーが、スマートフォンが決して持たなかった MAC アドレスへフレームをブリッジしているからだ。ブロードキャストに依存する探索は空のままになる。LAN がブリッジ越しの DHCP に頼っている場合、スマートフォンはその方法でリースを取得できず、ブリッジされたサブネット内で手動で割り当てたアドレスでも、欠けているインターフェースは作られない。
一部のクライアントはもっと早く、プロファイルの取り込み時に、実装できない種類のデバイスを見て失敗する。どちらの挙動も意味は同じで、ルートを足しても、DNS を変えても、トンネルのアドレス範囲を広げても直らない。
サーバー側が変えるべきこと
修正は VPN サービスを運用する側の仕事であり、通常は移行ではなく追加になる。ルーティングされたデバイス、独自のクライアントサブネット、アドレスを割り当ててスマートフォンに必要なルートを配るサーバー側設定を備えた二つ目の OpenVPN インスタンスを動かす。既存のブリッジ構成のインスタンスは、イーサネットを本当に必要とする機器へのサービスを続ける。
実運用で効かせるには二つの点がある。LAN には新しいクライアントサブネット用の戻りルートが必要で、VPN ホストを指していなければ応答は決して戻らない。そしてトンネルホストのファイアウォールは、トンネルインターフェースと LAN の間を転送しなければならない——ホスト自身からのテストが成功すると最も見落とされる手順がこれだ。
運用側がサービスを追加できない場合、代替はブリッジに参加できる機器、つまりスマートフォンの代わりに動くノート PC かルーターだ。これは独自の管理コストを伴う回避策であり、Android の設定ではない。
トンネルではなくアプリケーションから判断する
スマートフォンが実際に何に到達する必要があるかを尋ね、それを対応づける。名前やアドレスで到達するファイル共有やイントラネットサイトは IP の要件であり、DNS が名前を解決しルートが存在すれば、ルーティングされたトンネルで満たせる。ローカルのブロードキャストドメインを巡回する探索ツールは IP の要件ではなく、どれだけルーティングを足しても埋まらない。
| Requirement | Tunnel that satisfies it |
|---|---|
| File server or intranet by hostname | Routed TUN, with working DNS |
| Broadcast or ARP-based discovery | Ethernet bridging, so not an ordinary Android client |
| Multicast delivery | Bridging or an explicit multicast relay |
| One application to one address | Routed TUN, narrowest possible route |
その表は送るべき依頼でもある。アプリケーション、それが使うアドレスや名前、探索に依存するかどうかを示す。運用側はその説明に基づいて動けるが、つながらないスマートフォンについて誰も動くことはできない。
最後に、すべてのクライアントに LAN アダプターの真似をさせるのではなく、必要とする機器のために TAP サービスを残すことだ。目的が明確な二つのサービスは、全員にとって中途半端に動く一つより支えやすい。