接続トラブルシューティング · Clash 技術ブログ

Mihomo MASQUE 転送停止:ip-stack を確認

MASQUE のダウンロードが途中で止まるのに、新しい接続は通る場合は?Mihomo のバージョンと with_gvisor を確認し、対象ノードだけ ip-stack を切り替えて同じリクエストで比較します。元に戻す方法も残し、報告を修正済みと扱いません。

  • MASQUE
  • Mihomo
  • ip-stack
  • gvisor
  • 単一接続の停止
目次

MASQUE ノードに接続でき、ファイルのダウンロードも始まったのに、途中で転送が止まる。一方、新しく開いた Web ページにはアクセスできる。この状態は、プロキシ接続全体の切断とは異なります。まず、止まったのが一つのリクエストか、すべての接続かを分け、そのうえで実際の Mihomo のバージョンと対象アウトバウンドの IP スタックを確認します。

ダウンロードが止まったとき、トンネルは動いている?

Mihomo #3325 は Linux/ImmortalWrt ユーザーからの報告です。単一の TCP ダウンロードで受信が途中で止まっても、同じ MASQUE トンネル上の新しい接続は正常に使えています。対象は alpha-bc76c13 と、自分でビルドした alpha-94b13ae です。報告者の比較テストでは、gvisor に変えると同じ停止が発生しませんでした。

今回の確認時点では、この報告は未解決のままで、メンテナーによる結論やリリース済みの修正はありません。ここで紹介するのは元に戻せる切り分け方法です。すべての MASQUE、すべてのプラットフォーム、または v1.19.32 に確認済みの不具合があるとは扱いません。切り替えれば必ず直るという保証もありません。

同じノードで既存接続と新規接続を比べる

確認できた状態次の操作
一つのダウンロードが止まり、新しいリクエストは通る停止時刻、受信済みの量、実際のアウトバウンドを記録してから、IP スタックの一項目だけを変えて比較します。
既存・新規の両方が失敗する、または MASQUE に接続できないまず設定、ノード、接続自体のエラーを調べます。単一接続の停止という報告だけでは、通信全体が使えない理由は説明できません。
短いテストでは一時的に正常だった観察結果は残します。ただし、長時間の接続でだけ発生する問題は除外できず、すぐに転送量を増やす必要もありません。

実際のコアと with_gvisor のビルド対応を確認する

まず、現在使えている設定を独立したファイルとして保存します。対象ノード名、ip-stack の元の内容全体、実際のコアバージョン、ダウンロードツールのリクエスト情報を記録してください。GUI クライアントとコアのバージョンは別です。コマンドラインにある別の Mihomo も、アプリが実行しているコアとは限りません。

以下の mihomo は、実際に動いているコアの実行ファイルを指します。クライアントやルータープラグインに組み込まれている場合は、その実際のパスで実行してください。コマンド検索パスにある別のプログラムだけで判断せず、バージョン出力の Use tags に with_gvisor が含まれるかを確認します。

実行中のコアのバージョンとビルドタグを表示する
mihomo -v

バージョンを固定して確認した v1.19.32 と、報告で使われた 94b13ae のソースコードは、どちらも MASQUE の ip-stack フィールドに対応しています。この実装では空の値を auto とし、auto は mips を選びます。gvisor を使うには with_gvisor を含めてビルドする必要があります。ここでの mips はアウトバウンドの IP スタックの選択肢で、コアをインストールするときの CPU アーキテクチャではありません。

今回の比較は、ユーザー空間の IP スタックを使う MASQUE 設定だけが対象です。network が h3-l4proxy の場合はこのスタックを経由しないため、ip-stack.mode で同じ比較はできません。この記事の手順に合わせるために network を切り替えないでください。

このビルド機能がない場合、確認したソースコードでは gVisor IP stack requires the with_gvisor build tag というエラーになります。このエラーが出たら再読み込みを繰り返さず、テストの変更を元に戻してください。古い版や別のブランチは、このフィールドを認識しない、または無視する場合があります。設定チェックに通ることだけでは、そのフィールドが実際に使われたとは判断できません。

一部の言語のドキュメントには、以前の auto の説明が残っている場合があります。そのため、この記事ではバージョンを指定したソースコードで意味を確認しています。v1.19.32 がこの設定に対応していても、この正式版で報告の不具合が実証されたという意味ではありません。この比較のために、むやみに Alpha コアを入れないでください。

対象の MASQUE ノードだけ ip-stack を切り替える

変更する場所は、既存の type: masque アウトバウンドノードの内部です。ip-stack は type、server などと同じ階層に置きます。TUN インバウンドの stack とは別の設定なので、tun.stack に gvisor を指定しても、ここで行うアウトバウンドの比較にはなりません。

以下は対象ノードに組み込む一部分であり、完全な設定ではありません。既に ip-stack があれば mode だけを変え、ほかの項目は残してください。元々なかった場合も、そのことを記録しておくと、テスト後に正確に戻せます。

対象の MASQUE ノードに組み込む YAML の一部。ルート階層や TUN の設定ではありません
ip-stack:
  mode: gvisor

元の設定を残し、一つのノードだけで比較する

  1. 失敗したリクエストが実際に通るノードを特定する

    接続記録で、そのリクエストが対象の MASQUE ノードを使っていることを確認します。現在のポリシーグループ名だけで推測しないでください。元のサブスクリプションまたはローカル設定、対象ノードの元の値、既に使えると分かっている予備ノードを保存します。

  2. 保存が維持されるコピーで mode を変更する

    自分で管理するローカル設定のコピーか、クライアントが明示的に対応している永続的な上書きで、このノードの ip-stack.mode だけを gvisor に変えます。リモートのサブスクリプション更新でキャッシュが上書きされる場合があります。確実に保存できなければ、まず設定の管理者に相談し、一時ファイルを直接編集しないでください。

  3. 設定をチェックし、アプリが実際に読み込んだことを確認する

    現在のコアで設定をチェックします。Mihomo を直接実行している場合は、実際のパスで -t と -f を使えます。保存後は最終的な設定の対象ノード、実行中のコア、起動ログを確認し、設定やビルドのエラーがあれば元のコピーに戻します。

  4. 新しいリクエストで比較する

    ノード、ネットワーク、ほかの設定を同じに保ち、同じ対象ファイルへのリクエストを新しく開始します。既に確立された TCP 接続は、IP スタックを切り替えた新しいリクエストとしては扱えません。結果を記録してから、今回の設定を残すか判断します。

比較によって改善したか、どう判断する?

自分にアクセス権のある、インストーラー以外のテストファイルを使い、テスト時間と転送量の上限を先に決めます。元の設定での動作を記録し、同じ条件で再試行してください。報告の巨大なファイルをそのまま使う必要はありません。短いテストで再現しないからといって、ダウンロード量を増やし続けないでください。

再び止まったら、既存の記録を残しながら短いリクエストを新しく送ります。元のダウンロードの受信量が増えず、新しいリクエストは通る場合に、報告の特徴に近いと言えます。速度テストの数値、一度 Web ページが開いたこと、エラーログがないことだけでは、長時間の接続が復旧したとは判断できません。

五つの確認結果を保存する

  • 実際のコアバージョン、Use tags、対象ノードの設定が、同じ実行中のコアのものである。
  • 最終的な設定では対象の ip-stack.mode だけが予定どおり変更され、元の値と独立したバックアップが残っている。
  • 同じ対象ファイルへの新しいリクエストで受信が続く。時間制限による終了、自分でのキャンセル、自然な完了のどれかを記録し、混同しない。
  • 停止中の新規接続との比較、実際のアウトバウンド、短いログがそろい、通常の接続断やポリシーグループの切り替えを単一接続の不具合と取り違えていない。
  • 設定を再読み込みして対象ノードを選び直しても変更が保存され、実際のリクエスト結果が前回と一致する。短いテストの結論は、その観察時間内に限られる。

失敗したら、どう戻して何を報告する?

設定エラー、ビルド機能の不足、通信状態の悪化があれば、対象ノードの ip-stack を元の内容に戻します。元々なければ、今回追加した部分を削除してください。元の設定を再読み込みして確認し、以前から使えていた予備ノードや設定に切り替えます。元に戻すために再インストールやデータ全消去をする必要はありません。

gvisor との比較で今回のリクエストが改善しても、それはこの環境での一時的な結果です。プロジェクトで修正済みとは言えません。両方の設定で失敗する場合や、新しい接続もすべて失敗する場合は、証拠を保存し、実際のエラーに沿って調べてください。同じ IP スタックの問題だと決めつけないでください。

報告には、実際のコアバージョンとビルドタグ、プラットフォーム、実際の mode、機密情報を除いた最小設定、リクエストの停止時刻と受信量、同じトンネル上の新規接続の結果を添えます。private-key、アカウント、サブスクリプションの Token などの機密情報は削除してください。完全な認証情報の公開や、報告のための大容量ファイルの継続転送は必要ありません。

この記事では公式ドキュメントとバージョンを固定したソースコードを確認しました。実際のルーターでこの不具合を再現したわけではなく、報告者の性能測定値も独立には検証していません。原因の確定、修正の公開、既定動作の変更については、今後のメンテナーの結論と明確なバージョン記録を確認してください。

参考資料