スマートフォンには飛行機のアイコンが表示され、VPNクライアントは二分間Connectingのままで、プロファイルは正しい。一時間前には同じ建物で動作していた。壊れているものは何もない。VPNは別のネットワークに運ばれる接続であり、機内モードはその運び手のネットワークを外しただけだ。クライアントは上り回線がないまま、そうするから再試行を続ける。

わかりにくいのは、飛行機の記号がWi-Fiが利用できるかどうかを教えず、Connectingもクライアントが認証中なのか単に待機中なのかを教えないことだ。この二つの読みを分ければ、診断は一分で終わる。

飛行機の記号は無線の報告ではない

対応するAndroid端末では、機内モードでもWi-FiとBluetoothを有効のままにでき、端末は前回の選択を覚えている。GoogleのPixelの機内モードに関するガイドは、まさにその挙動を説明している。つまりアイコンは、セルラーが切れているというだけを意味しうる。

グリフではなく実際の状態を確認する。adb shell settings get global airplane_mode_onはモード自体について0か1を返し、adb shell dumpsys connectivityは端末が現在持つネットワークを検証状態とともに一覧する。この二つの出力を合わせれば、アイコンには答えられない問いに答えられる。

Wi-Fiが切れている、またはオンでも何にも関連付けられていないなら、VPNエンドポイントへの経路は存在せず、何度再接続しても作られない。まず除外すべきはこのケースだ。正しい修正がVPNアプリの外にある唯一のケースだからである。

Connectingが実際に意味するもの

クライアントは保存済みのプロファイルを保持し、その名前を表示し、何にも接触していないのにスピナーを回せる。構成はローカルだ。トンネルの確立には到達可能なサーバー、完了したハンドシェイク、ルーティングするインターフェースが必要だ。最後の部分だけが動作するネットワークを要するので、無線が切れていても最初の二つは成功に見える。

つまりスピナーは少なくとも三つの異なる状況と整合する。上り回線がまったくない場合、エンドポイントに届かない上り回線、そして届くが認証に失敗する上り回線だ。画面上は同一に見え、ログではまったく違う。だからこれらの場合に最初に役立つ成果物はログであり、もう一度の再試行ではない。

Android自身のVPNドキュメントも、接続の確立と、常時接続・ブロックという別個のポリシーとの間に同じ線を引いている。この分離があるからこそ、端末はオフラインなのに保護されているように見え、しかもトンネルを持たないことがある。

見分ける価値のある四つの状態

以下の四つの状態は、画面がどれも同じように描画するので名前を付ける価値がある。

StateWhat you will seeWhat to do
Airplane mode, Wi-Fi offNo networks in dumpsys, VPN retries foreverTurn Wi-Fi on, or accept that the tunnel cannot exist
Wi-Fi on, not associatedInterface exists, no default networkJoin the access point
Associated, not validatedNetwork listed, captive-portal flag setComplete the portal sign-in, then reconnect
Validated, tunnel downInternet works, VPN fails or blocksDebug the tunnel, not the radio

三行目がホテルや空港で多くの人を捕まえる。関連付けは入場許可ではない。端末を通していないポータルはWi-Fiパスワードを快く受け取り、そのうえでVPNエンドポイントへのトラフィックを渡すのを拒む。トンネルを切ったまま先にブラウザーでサインインするのが、通常は唯一の通り道だ。

ブロックが事態を悪く見せる理由

常時接続VPNとVPNなしの接続をブロックの両方が有効なら、トンネルが上がっていない間は対象のアプリがすべてブロックされる。これは機能が働いているのであって、二つ目の故障ではない。症状は一つのアプリの失敗からすべての失敗に変わり、はるかに大きな問題のように読めてしまう。

人々が読み違える順序もこれで説明できる。機内モードがオン、上り回線なし、アプリはブロック、VPNはconnectingと表示する。ブロックはポリシーが仕事をしていただけだ。上り回線を試すためにポリシーを切ると、おそらく望んでいた保護を外すことになり、何も学べない。

代わりに範囲を確認する。どのアプリが対象で、どれが除外され、プロファイルがユーザー単位か端末全体か。Wi-Fiが現れたらVPNアプリを起動するタスクはトリガーであって、それが動く前にパケットが出ていないことの保証ではない。

推測を終わらせる診断順序

下から上へ進める。モードを確認し、ネットワークが存在することを確認し、検証済みであることを確認し、ローカルサブネットの外の何かに到達できることを確認し、そのうえでクライアントを見る。adb shell ping -c 3 1.1.1.1は粗いテストだが、欠けている経路と、トンネルが不機嫌なまま存在する経路を切り分ける。

ネットワークが一覧にあるのにpingが失敗するなら、問題はVPNより上流にあり、クライアントの設定では直らない。pingが成功してもトンネルが確立しないなら、その瞬間のクライアントのログを取る。エラーはタイムアウトと認証拒否を区別し、この二つに共通点はない。

最後に意図した状態へ戻す。それが通常の設定なら機内モードでWi-Fiを許可し、ポータルを完了し、ブロックポリシーを再び有効にしてから一度だけ再接続し、トンネルが自力で上がることを確認する。手動の再試行の後でしか動かない構成は、次の起動でもまた失敗するからだ。

関連記事