連線疑難排解 · Clash 技術部落格

Mihomo MASQUE 下載卡住:ip-stack 排查

MASQUE 下載速度中途歸零,新連線卻正常?先核對 Mihomo 版本與 with_gvisor,僅針對目標節點比較 ip-stack,驗證相同請求並保留還原方法;使用者回報不代表已發布修正。

  • MASQUE
  • Mihomo
  • ip-stack
  • gvisor
  • 單一連線停滯
本文目錄

MASQUE 節點連得上,檔案也開始下載,傳輸卻突然停住;此時開啟新的網頁又能正常瀏覽。這與整條代理連線中斷不同。先分辨停住的是單一請求還是所有連線,再檢查 Mihomo 的實際版本與該出站節點使用的 IP 協定堆疊。

下載卡住時,如何判斷隧道是否仍在運作?

Mihomo #3325 是 Linux/ImmortalWrt 使用者的回報:單一 TCP 下載中途不再接收資料,同一條 MASQUE 隧道上的新連線仍正常。回報涉及 alpha-bc76c13 與自行編譯的 alpha-94b13ae;改用 gvisor 後,回報者在自己的比較測試中未再遇到相同停滯。

截至本次查核,該回報仍未結案,維護者尚未確認原因,也沒有已發布的修正。本文提供可還原的排查方法,並非認定所有 MASQUE、所有平台或 v1.19.32 都有此缺陷,也不保證切換後一定恢復。

比較同一節點上的既有連線與新連線

觀察到的情況下一步
某筆下載停住,新請求仍正常記錄停止時間、已接收資料量與實際出站節點,再針對單一欄位比較 IP 協定堆疊。
既有請求與新請求都失敗,或 MASQUE 無法建立連線先處理設定、節點或連線本身的錯誤;單一連線停滯的回報無法解釋所有斷網情況。
短時間測試暫時正常保留觀察結果,但不能因此排除長連線才會出現的問題,也不必立即擴大測試流量。

確認實際核心與 with_gvisor 編譯支援

先另外備份目前可用的設定,記下目標節點名稱、完整的 ip-stack 原始內容、實際核心版本,以及下載工具的請求資訊。圖形介面用戶端的版本不等於核心版本;命令列中的另一份 Mihomo 也無法代表應用程式正在執行的那一份。

以下 mihomo 代表正在執行的核心執行檔。若核心由用戶端或路由器外掛內嵌,請依實際路徑呼叫;不要只根據命令搜尋路徑中的另一個程式判斷。查看版本輸出中的 Use tags,確認是否包含 with_gvisor。

查看執行中核心的版本與編譯標籤
mihomo -v

固定於 v1.19.32 的原始碼與回報使用的 94b13ae 原始碼,都支援 MASQUE 的 ip-stack 欄位。已查核的實作將空值視為 auto,而 auto 會選擇 mips;gvisor 則要求編譯時包含 with_gvisor。這裡的 mips 是出站 IP 協定堆疊選項,不是安裝核心時選擇的處理器架構。

本次比較僅適用於使用使用者空間 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 不同;將 gvisor 寫入 tun.stack,無法完成本文的出站比較。

以下僅是要併入目標節點的部分內容,並非完整設定。原本已有 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 協定堆疊後的新請求。記錄結果後,再決定是否保留這次設定。

如何判斷比較結果是否改善?

選擇自己有權存取、且不是安裝套件的測試檔案,預先限制測試時間與流量。先記錄原設定下的表現,再以相同條件重試。不必照搬回報中的超大檔案,也不要因為短時間內未重現,就不斷增加下載量。

若再次停住,保留既有紀錄,同時發出一筆新的短請求:舊下載的接收量不再增加、新請求卻正常,才接近回報的特徵。測速數字、單次開啟網頁或沒有錯誤紀錄,都不足以證明長連線已恢復。

保留這五項驗證結果

  • 實際核心版本、Use tags 與目標節點設定,都對應同一份正在執行的核心。
  • 最終設定只有目標 ip-stack.mode 依計畫變更,原始內容與獨立備份仍可使用。
  • 同一目標檔案的新請求能持續接收資料;另須記錄是達到時限、主動取消,還是自然完成,三者不能混為一談。
  • 保留停滯時的新連線比較結果、連線的實際出站節點與簡短紀錄,避免將一般斷網或策略群組切換誤判為單一連線故障。
  • 重新載入設定並再次選取該節點後,設定仍保留,實際請求結果也與上次一致;短時間測試的結論只適用於該觀察時段。

失敗時如何還原並回報?

若出現設定錯誤、編譯支援不足或連線變差,恢復目標節點原有的 ip-stack 內容;原本沒有此項時,移除這次新增的部分。重新載入並驗證原設定,再切回先前已可用的備用節點或設定即可,無須重裝或清除所有資料。

即使 gvisor 比較測試改善了目前請求,也僅代表此環境的暫時結果,仍不能宣稱專案已修正。若兩種設定都失敗,或所有新連線也失敗,應保留證據,依實際錯誤繼續檢查,不能一律歸為相同的 IP 協定堆疊問題。

回報時提供實際核心版本與編譯標籤、平台、實際 mode、最小化且移除敏感資訊的設定、請求停止時間與接收量,以及同一隧道的新連線結果。移除 private-key、帳號、訂閱 Token 及其他敏感資訊;無須公開完整憑證,也不必為了回報持續傳輸大檔案。

本文已查核官方文件與固定版本的原始碼,並未在實際路由器上重現此故障,也未獨立驗證回報者的效能數據。日後是否確認原因、發布修正或調整預設行為,仍須以專案維護者的新結論及明確版本紀錄為準。

參考資料