Androidアプリがトンネルが上がった瞬間に動かなくなるとき、原因になり得るのは三つの異なる事柄で、どれも似たような失敗を生む。アプリが端末自身のネットワーク状態を読んでローカルに拒否している場合、サーバーが到着元アドレスを分類して拒否している場合、あるいは拒否がVPNとまったく関係ない場合だ。以下の順序は何かを変える前に証拠を集める。出口の変更はもっとも高くつく手順であり、判定がローカルなら役に立つ見込みがもっとも低いからだ。

ステップ 1:アプリがいつ拒否するのかを突き止める

最初の切り分けはタイミングだ。ログバッファを消し、失敗を再現し、アプリが不平を言う前に何をしたのかを見る:

adb logcat -c
# reproduce the failure in the app
adb logcat -d | grep -iE 'vpn|network|connect|http' | tail -60

外向きの要求が試される前にアプリが拒否するなら、それはローカルの判断だ。接続し、何かを送ってからエラーを出すなら、拒否は向こう側から来ている。トンネルを切っても同じように失敗するなら、VPNは最初から変数ではなかった。

そのタイミングは証拠として扱い、確定とはみなさない。アプリはキャッシュした応答を再生することがあり、バックグラウンドの要求は見る前に成功したり失敗したりしている。最後に成功した要求とエラーの時刻を記録しよう。メッセージが出た瞬間だけでは足りない。

ステップ 2:端末自身のネットワーク観を読む

AndroidはVPN状態をネットワーク機能として公開しているので、アプリは商用事業者の一覧がなくてもトンネルが有効だと気づける。接続サービスに現在のネットワークは何かを問い合わせ、その答えにはVPNトランスポートのビットが含まれる:

val cm = context.getSystemService(ConnectivityManager::class.java)
val caps = cm.getNetworkCapabilities(cm.activeNetwork)
val onVpn = caps?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true

この判定はローカルで安価であり、「このアプリはVPNでは動かない」という種類の報告を、遠隔での分類なしにまとめて説明できる。アプリが見える範囲はあくまで自身のネットワーク文脈に依存するので、すべてのアプリが端末上のすべてのプロファイルを調べていると決めつけないこと。

ワークステーションからは、試験用端末で adb shell dumpsys connectivity を使い、VPNネットワークの項目を探すことで同じ状態を確認できる。トンネルを上げた実行と下げた実行を比べ、両方の出力を残しておこう。

ステップ 3:サーバーが実際に何を見ているかを読む

もう一方の観測者はサービスだ。到着する送信元アドレスを見ており、アドレス、その背後のホスティング網、地域、通信事業者、あるいはアカウントと端末に結びついた信号に基づいて動作することがある。どれも一意な身元ではなく、アドレスの共有によって巻き添えの遮断は普通に起きる。制限された一つのアドレスが、同じ翻訳の背後にいる無関係な利用者をまとめて落とすことがある。

アドレスはアプリが使うのと同じ経路で取得しよう。ノートPCのブラウザからではない。端末上でアドレス反響サービスに単純な要求を送れば、遠い側が何を受け取るかが分かる。それを携帯回線経由の要求と比べれば、アドレスがそもそも変わったのかどうかが分かる。

アプリが携帯回線では動き、同じアカウントでトンネル上では失敗するなら、拒否は遠い側かアプリ自身の方針にある。どちらでも失敗するなら、VPNは差の要因ではなく、端点の試験はやめるべきだ。

ステップ 4:証拠を三つの判定のどれかに当てはめる

三つの組み合わせでほとんどすべての報告を覆える。トンネルが有効なのに外向きの試行がまったくない拒否は、ローカルの通信路チェックを指す。外に出てエラー、特定ホストのタイムアウト、地域メッセージで戻る要求は遠い側を指す。トンネルなしの携帯回線で再現する失敗は、アカウント、アプリの版、サービス自身の方針を指し、VPNの変更では動かない。

判定はそれを生んだ証拠と一緒に書き留めよう。この手順の価値は、端末上で走るチェックを直そうとして誰かが四回も出口ノードを変える循環を止めることにある。

主張を正直に保つ効果もある。自前のホスティングは端点とそのインターネット出口を変えるが、AndroidにVPN網が有効だと忘れさせるものではなく、アドレスを分類するサービスに受け入れられる保証もない。ローカルのフィルタは、商用のVPN網でも自分が所有するVPN網でも同じように発動し得る。

ステップ 5:サポートされた道を選び、検証する

製品の文書化された方針と、そのサポート責任者から始めよう。クライアントの版、正確なメッセージ、狭い失敗の時間帯を送る。エラーがあると示すためだけに、完全な通信の取得や資格情報を送ってはいけない。

サービスが直接接続を許し、端末の方針も許すなら、アプリ単位の除外がサポートされた仕組みであり、トンネルを隠すのではなく、そのアプリを意図的にトンネルから外す。アプリの通信は自前の経路で出ていくことになり、これは誰かが引き受けるべき方針の判断だ。VPNなしで遮断する構成では、除外されたアプリが単に接続を失うことがあるので、動くと約束する前にその組み合わせを試そう。

変更のあとは必ず最初のステップのタイミング試験を繰り返し、アプリが動くことと、他のすべてのアプリが今もトンネルを使っていることを確認する。そのうえで以前の構成に戻し、失敗が再現するかを確かめよう。再現できない修正は、また出会う偶然にすぎない。

関連記事