Android の SSH SOCKS プロキシ:アプリの半分しか接続しない理由
ssh -D が作るのは SOCKS リスナーであり、端末全体のトンネルではありません。アプリからアダプター、SSH へと経路をたどり、DNS とライフサイクルの隙間を確認します。
SSH でログインし、-D 1080 を追加するとコマンドは成功します。電話の上には SOCKS リスナーができたのに、アプリの半分は今もモバイルデータで外に出ています。これは壊れたトンネルではなく正常な結果です。ssh -D が作るのはプロキシの端点であり、Android のアプリは何かに強制されない限りプロキシを使いません。経路を順にたどれば、仕事のどの部分が実際どこにあるのかが見えます。
トラフィックが始まる場所から始める
トンネルを使うべきアプリを一つ選び、独自のプロキシ設定があるか確認します。SOCKS 欄のあるブラウザーは簡単な例です。127.0.0.1:1080 を指定し、設定があればリモート DNS を有効にすれば、リクエストは通ります。チャットクライアント、地図アプリ、そうした欄のないゲームはリスナーを使う手段がなく、SSH コマンドに何を書いてもそれは変わりません。
他の何かに関わる前に、SOCKS を直接話すクライアントで、電話自身のシェルからリスナーが動くことを証明します。
ssh -N -D 1080 [email protected]
curl --socks5-hostname 127.0.0.1:1080 https://ifconfig.me
返ってくるアドレスは電話のものではなく、SSH サーバーのものでなければなりません。そうならプロキシ側は半分完成で、残りは網羅性の話です。そうでなければ先に SSH 側を直します。鍵認証、サーバーが宛先に届く能力、そして SSH サーバー自身の出口です。
Android が必要とする部分を足す
プロキシ設定のないアプリには、パケットを捕まえてプロキシ接続に変える何かが必要です。root のない端末ではそれが VPN サービスアダプター です。仮想インターフェースを引き受け、選んだトラフィックをローカルの SOCKS リスナーへ転送するアプリです。経路はアプリ、アダプター、SOCKS リスナー、SSH 接続、宛先となります。
アダプターを入れ、VPN の許可を与え、捕まえるアプリや経路を選びます。ステータスバーの鍵アイコンが表すのはそのアダプターであり、別の商用 VPN ではありません。Android はユーザープロファイルごとに有効な VPN サービス接続を一つしか許さないので、二つ目の VPN アプリを起動しても経路に層は増えません。同じ役割を奪い合うだけです。
ここが、成功したテストに騙されやすい段階でもあります。アダプターがすでにプロキシへ向けたブラウザーだけを捕まえる設定なら、すべて動いて、他は何も覆われていません。端末がトンネルされたと結論する前に、捕捉リストを読んでください。
SSH の通信を捕捉の外に置く
SSH 接続そのものを、それが維持する SOCKS トンネルへ戻してはいけません。アダプターが SSH アプリの通信を捕まえると、トンネルはトンネルを待つ接続に依存し、結果はアダプターが始まった途端に止まるか失敗するループです。
統合実装は自身の通信ソケットを保護します。別々のアプリでは、対応している除外が必要です。SSH アプリを捕捉の外に置くか、アドレスで SSH の端点を除外します。どちらにも代償があります。ターミナルアプリ全体を除外すると、無関係な通信もトンネルから外れ、アドレスの除外はサーバーのアドレスが変わったときや、次回の接続で名前が別に解決されたときに壊れます。
除外は外側から確認します。アダプターを再接続し、SSH セッションが生き残ること、プロキシ経由のリクエストが今もサーバーのアドレスを報告することを確かめます。アダプターが始まるまで動き、その後固まるセッションが、そのループです。
DNS と UDP を経路の終わりまで追う
OpenSSH の動的転送が運ぶのは TCP 接続です。UDP アソシエートでも ICMP の転送でもなく、アダプターは UDP パケットを受け取ることで UDP 転送をでっち上げることはできません。QUIC や WebRTC のメディアを含め、UDP を要求するものはアプリ次第で失敗するか TCP に戻ります。
DNS には独自の判断が必要です。名前をローカルで解決するアプリは、接続の前に通常のリゾルバーへ問い合わせを送るので、トンネルが運ぶのは接続であって名前解決ではありません。リモート DNS の選択肢を持つプロキシ対応クライアントはそれを避けますが、それのない捕捉されたアプリは避けられません。アダプターが変えたと決めつけず、どのリゾルバーが答えたかを確認します。
SOCKS リスナーはループバックに束縛したままにし、初回使用時に SSH サーバーのホスト鍵を検証し、最終的なサイトには通常の HTTPS 検証をそのまま残します。SSH が守るのは電話からサーバーまでの区間であり、サーバーがその後に何をするかを暗号化するものではありません。
二つの寿命を確認して決める
アダプターと SSH セッションの寿命は別です。アダプターが捕捉を続けたまま SSH が落ちると、アプリは明示的なエラーもなく固まることがあります。パケットは今も、動く出口を失った仮想インターフェースへ入っているからです。アダプターが止まれば、アプリは端末の VPN ポリシー次第で直接出るか遮断されます。
両方向を意図的に試します。アダプターを動かしたまま SSH セッションを切り、次に SSH を上げたままアダプターを止めます。それぞれの場合に電話がとる振る舞いが、設定手順が何と言っていても、実際に配備しているポリシーです。
予測できる失敗の仕方を持つ端末全体の網羅が必要なら、本物の IP VPN か、この経路のために設計され保守されているアダプターが正直な答えです。無関係な捕捉アプリの隣で走らせたままのシェルセッションは、保守された端末トンネルではありません。片方が終わったときに何が起きるかの合意がない、二つの部品です。