訂閱格式比較:Clash YAML、Base64 節點連結與 sing-box 設定轉換
整理常見代理訂閱格式、各客戶端的支援方式,以及本機轉換時的欄位與安全注意事項。
先辨識內容,再選擇匯入方式
訂閱連結是取得內容的網址,不是格式名稱。同一個網址可能依請求參數或客戶端的 User-Agent 回傳不同內容;檔名以 .yaml 結尾,也不代表回應一定是 Clash 設定檔。匯入失敗時,應先在本機檢視實際回應,而不是一再修改副檔名。
這裡要分清楚三個層次:Base64 是編碼方式,ss:// 等 URI 是節點描述方式,而 Clash YAML 與 sing-box JSON 則是各自核心使用的設定結構。解碼後取得節點清單,不代表已經產生包含分流規則、DNS 與監聽埠的完整設定。
| 內容類型 | 本機辨識特徵 | 通常包含哪些內容 |
|---|---|---|
| Clash 完整 YAML | 頂層常見 proxies、proxy-groups、rules | 節點、策略組、規則,也可能包含 DNS 與 TUN 設定 |
| Clash 節點提供者 YAML | 通常以頂層 proxies: 清單為核心 | 供 proxy-providers 引用的節點集合 |
| 節點 URI 清單 | 多行 ss://、vmess://、trojan:// 等連結 | 節點連線參數,通常不包含完整分流策略 |
| Base64 訂閱 | 看起來像連續的英數字元與編碼符號;解碼後再辨識 | 常見內容是節點 URI 清單,實際格式仍以解碼結果為準 |
| sing-box JSON | 頂層常見 inbounds、outbounds、route | 入站、出站、路由與選用的 DNS 設定 |
Clash YAML:完整設定與節點提供者
能解析 YAML,不代表就能直接執行代理
YAML 用來描述資料;mihomo 還會檢查欄位型別、節點參數與引用關係。縮排請使用空格,不要用 Tab。埠號應依欄位要求填入數字;包含特殊字元的名稱、密碼或 URL 可加上引號,避免 # 被當成註解,或冒號改變結構。
以下是用來理解結構的直連範例,不含代理節點。它會監聽本機 127.0.0.1:7890、啟用規則模式,並將流量交由名為「出口選擇」的策略組處理;組內只有 DIRECT,因此執行後仍會直連。此範例不會自動開啟客戶端的系統代理或 TUN。
mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info
proxies: []
proxy-groups:
- name: 出口選擇
type: select
proxies:
- DIRECT
rules:
- MATCH,出口選擇
提供者檔案需要由主設定引用
節點提供者通常只提供 proxies 集合。主設定透過 proxy-providers 定義來源、更新間隔與健康檢查,再由策略組的 use 引用提供者名稱。若直接把提供者檔案當成完整設定匯入,可能會出現「看得到節點,卻沒有預期策略組」的情況。
- 檢查引用:規則中的策略名稱必須存在;策略組引用的節點名稱或提供者名稱也必須相符。
- 檢查名稱是否重複:兩個節點同名會讓選取與引用變得不明確。轉換時若重新命名,相關引用也要一併更新。
- 確認核心:相容 Clash 的設定不代表所有舊版 Clash 核心都支援。部分協定或擴充欄位需要 mihomo,實際支援情況取決於客戶端使用的核心。
Base64:解碼不等於轉換協定
Base64 不會隱藏訂閱憑據,也不會自動補齊欄位。常見的訂閱格式會以換行串接多個節點 URI,再將整段文字編碼一次;部分 URI 本身也包含 Base64 片段。因此,外層解碼成功後,應先辨識每一行使用的協定,不要反覆解碼到「看起來像文字」為止。
使用 Python 3 在本機檢查外層內容
將已取得的編碼內容存成 subscription.txt,再將下方指令碼存成 decode_subscription.py,並執行 python3 decode_subscription.py。指令碼支援常見的標準與 URL-safe 字元集,並會補上結尾填充;它只負責解碼,不會連線到節點、轉換設定,也不會將節點內容輸出到終端機。
from pathlib import Path
import base64
import binascii
source = Path("subscription.txt").read_text(encoding="utf-8-sig")
compact = "".join(source.split())
if not compact:
raise SystemExit("輸入是空的")
compact += "=" * (-len(compact) % 4)
try:
raw = base64.b64decode(compact, altchars=b"-_", validate=True)
text = raw.decode("utf-8")
except (ValueError, binascii.Error, UnicodeDecodeError):
raise SystemExit("無法解碼為 UTF-8 Base64 文字,請先檢查原始回應")
with Path("decoded.txt").open("x", encoding="utf-8") as output:
output.write(text)
print("已寫入 decoded.txt;請在本機檢視內容類型")
使用獨佔寫入模式是為了避免覆寫現有的 decoded.txt。如果檔案已存在,請先確認是否仍需保留。解碼後的檔案仍含有敏感資訊,請勿上傳到公開程式碼儲存庫或貼到群組聊天。
URI 內層仍須依協定解析
ss://有多種表示方式,使用者資訊可能經過 Base64 編碼,也可能附帶外掛參數;不能只依第一個冒號或@拆解。vmess://常見格式是經過編碼的 JSON,但仍須檢查具體欄位,不能把它當成任意通用的節點字串。trojan://、vless://等連結通常會透過查詢參數帶入 TLS、傳輸層與路徑資訊;URL 百分比解碼也必須遵循欄位界線。- 片段中的顯示名稱通常不是連線參數。重新命名節點有助於辨識,但無法修正錯誤的伺服器位址或驗證資訊。
sing-box JSON 與 Clash YAML 的轉換界線
兩者都能描述代理連線,但設定模型並不相同。Clash 通常以節點、策略組與有序規則組織出口;sing-box 則透過帶有 tag 的出站與路由引用來安排流量。把 proxies 改名為 outbounds,不會因此變成有效的 sing-box 設定。
以下是 sing-box 的直連結構範例:HTTP 與 SOCKS 共用 127.0.0.1:7890,最後將流量路由至 direct-out。這是用來對照欄位的獨立範例,不能與上方的 mihomo 範例同時使用相同的監聽位址與埠號。
{
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 7890
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
}
],
"route": {
"final": "direct-out"
}
}
| 轉換項目 | 需要處理的差異 |
|---|---|
| 節點連線 | 逐項對應協定、位址、埠號、驗證資訊、TLS 與傳輸層參數 |
| 策略選擇 | Clash 策略組與 sing-box 選擇類出站的結構和選項並不完全相同 |
| 分流規則 | 規則語法、動作與規則集格式各不相同,不能直接照搬 |
| DNS | 伺服器定義、解析路由、Fake-IP 與引導解析都需要分別重建 |
| 流量接管 | 系統代理由客戶端或系統設定;TUN 則涉及權限、路由與平台差異 |
設定也要記錄版本
sing-box 的 DNS 與路由欄位曾經歷版本變更。例如 1.12.0 引入了新的 DNS 伺服器設定格式,因此舊設定能匯入某個客戶端,不代表更新核心後仍然適用。轉換前請記錄來源客戶端核心版本、目標核心版本與轉換器版本,依照目標版本的文件產生設定,不要只記錄應用程式介面顯示的版本號。
客戶端支援能力:分清匯入器與核心
「客戶端支援某種格式」可能是指內建匯入或轉換功能,不代表底層核心能直接讀取該格式。以 mihomo 為核心的客戶端通常使用 Clash YAML;部分客戶端可以整理節點連結並產生設定,但是否接受整段 Base64、是否保留規則與 DNS,取決於實際使用的匯入方式。以 sing-box 為核心的客戶端主要讀取其 JSON 設定,圖形介面客戶端也可能另外實作訂閱管理功能。
- 先確認入口用途:分清楚「從 URL 匯入設定」、「新增單一節點」、「匯入節點提供者」與「匯入本機檔案」。單一節點的匯入入口通常不會自動建立完整的規則架構。
- 再檢查匯入預覽:確認節點數量、協定類型與策略組名稱。來源檔案有 12 個節點,結果卻只有 9 個時,應先確認遭略過的 3 個節點,不要直接啟用。
- 最後確認實際啟用的設定:訂閱快取、使用者覆寫與客戶端產生的設定可能是三個不同檔案。介面上的修改是否會在下次更新訂閱後保留,需另外確認。
若要重新選擇客戶端,可前往下載中心依作業系統查看下載項目;匯入與首次接管流量的步驟請參閱訂閱匯入指南。不要只憑客戶端名稱推斷它支援所有 Clash 擴充欄位。
本機轉換與驗證:五個步驟逐一排查
1. 儲存來源檔案並記錄目標版本
保留一份不進行編輯的來源檔案,另存轉換結果。記錄取得時間、內容類型與目標核心版本。若訂閱網址含有存取權杖,記錄時只寫用途說明,不要將完整網址放進共用文件。
2. 先轉換節點,再遷移策略
先確認伺服器、埠號、密碼或 UUID、加密方式與傳輸參數,再處理分組與規則。若目標核心無法表達某個協定,應保留失敗記錄,不要悄悄換成其他協定。若只取得節點清單,就必須另外設計 DNS 與分流,不要期待轉換器還原原本不存在的規則。
3. 使用目標核心檢查語法
以下命令假設核心程式位於目前的終端機路徑中。mihomo 的 -t 會檢查設定,sing-box 的 check 會檢查設定是否有效;Windows 可使用對應的 .exe 檔名。檢查通過只代表設定格式可接受,不代表伺服器連得上或驗證成功。
mihomo -t -f converted.yaml
sing-box check -c converted.json
4. 先透過明確指定的代理驗證節點
為了減少系統設定造成的干擾,可以先不啟用 TUN,改用已確認的本機 HTTP 代理埠測試。以下範例要求設定中有 7890 埠,且目前策略已選取要測試的節點;測試網站只是請求目標,不是節點伺服器。
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/
這條命令執行成功,只能證明該次請求透過本機代理入口完成連線。還要在連線面板或記錄中確認最終出站:如果命中 DIRECT,不能據此斷定代理節點運作正常。若失敗,請依序檢查埠號未監聽、DNS 解析失敗、TLS 交握失敗與遠端拒絕驗證等原因。
5. 再驗證系統代理與 TUN
明確指定代理的測試正常後,再開啟系統代理測試瀏覽器;只有確實需要接管不遵循系統代理的應用程式時,才測試 TUN。TUN 的權限、路由或 DNS 接管問題,與訂閱編碼無關。每次只修改一個層面,才能判斷錯誤是來自節點轉換,還是流量接管。
訂閱憑據與轉換結果的保存方式
將訂閱 URL 提供給線上轉換服務,通常代表對方可以取得原始訂閱及其中的節點憑據。只在瀏覽器開啟轉換頁面,無法證明處理過程是在本機進行。若需要離線處理,請使用確認不依賴遠端服務的本機工具,並檢查規則範本、遠端提供者等附加資源是否仍需連網。
- 限制本機介面:轉換服務若只供本機使用,應監聽
127.0.0.1,不要直接暴露在0.0.0.0或公網埠上。 - 限制檔案讀取權限:在 Linux 或 macOS 可使用
chmod 600 subscription.txt decoded.txt converted.yaml限制現有檔案的存取權限;Windows 則透過檔案安全性權限設定。 - 先移除敏感資訊再排錯:分享錯誤資訊時,保留協定、欄位名稱與錯誤位置,並移除訂閱權杖、密碼、UUID 及不宜公開的伺服器資訊。
- 憑據外洩後應更換:Base64 文字也應比照明文設定保護。若訂閱連結已公開,除了刪除貼文,也應前往提供者後台重設連結或相關憑據。
轉換完成的標準不只是「檔案能開啟」,還包括目標核心檢查通過、重要欄位完整保留、策略引用無誤,且實際連線依預期選擇出站。優先使用提供者直接產生的目標格式;確實需要互轉時,保留來源檔案、記錄版本並逐層驗證,能大幅減少訂閱更新後反覆排錯的情況。