Clash 多裝置設定同步:訂閱連結、代管設定與手動匯出三種方案
手機、電腦與平板如何讓設定保持一致?本文比較訂閱連結自動同步、自架設定代管與手動匯出匯入三種方案的適用情境、維護成本與衝突處理方式。
先釐清要同步的是哪幾類資料
多裝置之間「設定對不上」,多數時候不是客戶端的問題,而是把幾類性質不同的資料混在一起管理了。它們存放的位置、更新方式、能否自動同步都不一樣,先分清楚再談方案。
| 資料 | 存放位置 | 能否自動同步 |
|---|---|---|
| 訂閱連結 | 各客戶端的設定儲存區 | 否,每台裝置各填一次 |
設定本體 config.yaml | 客戶端設定目錄或代管 URL | 是,抓取訂閱時整份取代 |
| 節點與規則集 providers | ./providers、./ruleset 快取 | 是,依 interval 定時抓取 |
| 目前選取的節點、運作模式 | 客戶端運作狀態 | 否,各裝置獨立 |
真正需要統一的是設定本體和 providers 快取:前者決定連接埠、DNS、TUN 與規則,後者決定節點清單。至於目前選取的是哪個節點、mode 停在 rule 還是 global,本來就該依裝置分別設定,不必強求一致。
一個常見誤判:訂閱相同不等於設定相同
訂閱只決定節點來源。mixed-port、dns、tun、rules 這些欄位由各客戶端在本機維護,換訂閱不會同步連接埠,也不會同步本機規則。所以「三台裝置填了同一個連結」和「三台裝置行為一致」是兩件事,後者要靠下面的方案來保證。
方案一:訂閱連結自動同步
三台裝置填同一個訂閱位址,客戶端依固定間隔自動抓取。桌面、Android、iOS 都支援,是涵蓋面最廣的做法,也是維護成本最低的一種。
「訂閱」→「新增」,貼上訂閱位址後儲存,先不要急著開代理。
在訂閱卡片上按右鍵 →「編輯」,把自動更新間隔從預設的 1440 分鐘改成 360~720 分鐘。
在訂閱卡片上按右鍵 →「更新」,確認能抓出完整節點清單,而不是只剩一個設定名稱。
「設定」→「系統代理」視需要開啟;TUN 模式在「設定」→「TUN 模式」另外打開,行動端由客戶端的 VPN 服務接管,不需要額外設定。
Android 端在「設定檔」清單裡長按設定檔可看到更新入口,iOS 端在設定檔詳細頁面下拉重新整理。
rules、mixed-port、dns 區段,更新後這些欄位會被訂閱裡的值覆蓋。把自建規則直接寫進訂閱設定,是「更新一次就丟一次」最常見的原因。
連接埠被改寫之後的表現
訂閱把 mixed-port 從 7890 改成 7891 之後,系統代理和瀏覽器外掛裡寫死的 7890 仍然指向舊連接埠,表現是客戶端顯示已連線、但網頁全部打不開。核對辦法是打開 external-controller 面板(預設監聽 127.0.0.1:9090)看實際生效的連接埠。
# 查看目前生效的連接埠、模式與 DNS 設定
curl -s http://127.0.0.1:9090/configs
不方便用命令列的人,直接看桌面客戶端「設定」頁顯示的連接埠,和瀏覽器外掛裡的值對一下即可。
適用範圍
- 適合:裝置數 1~3 台,規則完全跟隨訂閱,不想額外維護檔案。
- 不適合:有自建規則、需要依裝置區分連接埠、訂閱結構經常調整。
方案二:自架設定代管,一份 YAML 管所有裝置
把設定本體放到一個能直連下載的位址(私有物件儲存、自架 nginx、私有儲存庫的 raw 連結都可以),各裝置把這個位址當作訂閱匯入。之後改規則只改這一份檔案,各端下次抓取時自動生效。
把節點來源和規則解耦
不要把節點直接寫進 proxies,用 proxy-providers 讓內核自己去抓節點;連接埠、DNS、規則這些屬於你自己的部分,全部寫在 base config 裡。
mixed-port: 7890
allow-lan: false
mode: rule
log-level: warning
external-controller: 127.0.0.1:9090
unified-delay: true
tcp-concurrent: true
proxy-providers:
airport-a:
type: http
url: "https://sub.example.com/api/v1/client/subscribe?token=9f2c1a7b4e"
interval: 3600
path: ./providers/airport-a.yaml
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 300
timeout: 3000
rule-providers:
reject:
type: http
behavior: domain
format: mrs
url: "https://example.com/rules/reject.mrs"
path: ./ruleset/reject.mrs
interval: 86400
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- https://223.5.5.5/dns-query
fallback:
- https://1.1.1.1/dns-query
兩個 interval 的單位都是秒:3600 表示一小時抓一次節點,86400 表示一天抓一次規則集。節點變動頻繁就把前者調到 1800,規則集沒必要更頻繁。
format: mrs 需要 mihomo 1.18.0 以上,舊版本改用 format: yaml 搭配 behavior: domain。另外,代管位址必須能直連下載,放在需要代理才能存取的地方,首次啟動會抓不到設定,表現是節點清單為空。
上線前先在本機跑一次語法檢查
# 只做設定檢查,不啟動代理
mihomo -t -d /etc/mihomo -f config.yaml
檢查通過再上傳到代管位址。各裝置匯入代管 URL 之後,節點由 providers 定時抓取,改規則只需要各端重新抓一次設定,不用逐台修改。
欄位與內核版本的對應關係
| 欄位 | 適用版本 | 用途 |
|---|---|---|
format: mrs | mihomo 1.18.0 起 | 規則集二進位格式,體積更小、載入更快 |
tcp-concurrent | mihomo 1.16 起 | 並行建立連線,減少握手等待 |
unified-delay | mihomo 1.16 起 | 統一各協定的延遲測量基準 |
geodata-mode | mihomo 1.16 起 | 選擇內建 GEO 資料的使用方式 |
方案三:手動匯出匯入
只在離線裝置、路由器或臨時除錯時值得用。做法是匯出設定本體,連 providers/、ruleset/ 快取目錄一起複製過去,少了快取目錄會白跑一趟。
桌面客戶端在「設定」裡點「開啟設定目錄」;mihomo 命令列版通常在 /etc/mihomo/config.yaml 或 ~/.config/mihomo/config.yaml。
只複製 config.yaml 時,首次啟動會因為 providers 快取缺失而顯示節點清單為空。
例如 config-20260830.yaml,避免客戶端裡堆了好幾份同名設定互相覆蓋。
iOS 端先用「檔案」App 或雲端硬碟把 YAML 存到本機,再在客戶端裡選擇「匯入設定」。
看「代理」頁的節點數量和「規則」頁的筆數,和來源裝置一致才算匯入成功。
以下幾種情況基本上只能走手動這條路:
- 目標裝置連不到代管位址,例如內網或離線環境。
- 只想臨時驗證一條規則或一組 DNS 設定,不想動代管檔案。
- 路由器等嵌入式環境,只能透過 USB 隨身碟或 SCP 放檔案。
衝突處理:把修改分層
三種方案混用時,衝突基本上來自同一個原因——同一個欄位被兩處修改。解決辦法是把修改分層:訂閱或代管檔案只放共用部分,裝置差異放在合併層。
合併層只寫差異
# Merge 設定:不複製整份 config.yaml,只寫要改的部分
prepend-rules:
- DOMAIN-SUFFIX,intranet.example.com,DIRECT
prepend-proxy-groups:
- name: 手動選擇
type: select
proxies: [自動選擇, DIRECT]
規則用 prepend-rules 插到最前面,匹配優先順序高於訂閱自帶的規則;代理群組用 prepend-proxy-groups 放到清單最上方,方便在介面上直接選。訂閱更新時,合併層的內容不會被覆蓋,這是它比「直接改訂閱設定」可靠的地方。
一致性檢查清單
| 檢查項目 | 位置 | 預期結果 |
|---|---|---|
| 生效連接埠 | 「設定」→「連接埠」,或 GET /configs | 各裝置同為 7890 |
| 節點數量 | 「代理」頁 | 同一個 provider 抓取的節點數一致 |
| 規則筆數 | 「規則」頁 | 與代管檔案裡的 rules 筆數一致 |
| provider 更新時間 | GET /providers/proxies | 落在 interval 之內 |
| 運作模式 | 系統匣選單或首頁 | 平時保持 rule,需要診斷時才切 global |
# 查看 provider 最近一次抓取時間與節點數量
curl -s http://127.0.0.1:9090/providers/proxies
一條經驗法則:同一個欄位只允許一個地方定義。連接埠、DNS、TUN 寫在 base config;節點來源寫在 proxy-providers;裝置差異寫在合併層;選取節點和運作模式交給各裝置自己。做到這一點,三台裝置之間的差異就只剩「目前選了哪個節點」。
區域網路裡的兩個注意事項
external-controller預設只監聽127.0.0.1,要讓其他裝置存取面板,需要明確改成0.0.0.0:9090並設定secret。- 多台裝置同時開
allow-lan不會互相衝突,但其他裝置要指向正確的裝置 IP,連接埠保持 7890 即可。
三種方案怎麼選
| 方案 | 適用情境 | 維護成本 | 衝突處理 |
|---|---|---|---|
| 訂閱連結自動同步 | 1~3 台裝置,規則跟隨訂閱 | 低 | 各自覆蓋,本機修改會遺失 |
| 自架設定代管 | 3 台以上,有自建規則 | 中 | 合併層分層,衝突可預期 |
| 手動匯出匯入 | 離線裝置、路由器、臨時除錯 | 高 | 完整覆蓋,需人工檢查 |
最常見的組合是:主要裝置用代管 URL 加合併層,手機和備用機直接填訂閱連結,路由器這類不方便連網更新的裝置手動放檔案。三套並存時,只要確保同一個欄位只有一個定義處,就不會互相打架。
常見問題
手機和電腦填了同一個訂閱,節點數量卻不一樣
&flag=clash 這類參數,結果就會不同。訂閱更新後本機規則不見了,該怎麼保留
prepend-rules;不支援合併鏈的客戶端,改用自架代管 URL,把規則寫進 base config 的 rules 區段。同一份設定在 macOS 上正常,Android 上啟動就報錯
tun、redir-port、tproxy-port 屬於桌面和 Linux 側的寫法,Android 由客戶端自己的 VPN 服務接管;external-controller 寫成 0.0.0.0:9090 又沒設定 secret 時,部分客戶端會直接拒絕啟動。把這些欄位從 base config 移出,放進各端的合併層即可。多台裝置同時開 TUN 模式會衝突嗎
allow-lan,注意讓其他裝置指向正確的裝置 IP;面板連接埠預設只監聽本機,跨裝置存取要明確開放並設定 secret。