訂閱網址與訂閱格式
訂閱網址是取得設定的入口,格式則是伺服器回傳內容的結構。以 HTTPS 開頭的網址,可能回傳 Clash YAML、經 Base64 編碼的節點清單,也可能回傳登入頁面。不能只憑連結副檔名判斷格式;沒有 .yaml 副檔名的網址,也可能提供完整設定。
實際排查時,先分辨三個層面:HTTP 是否成功、回傳文字採用哪種格式,以及目前核心是否支援其中的協定。將訂閱轉成 YAML,只能解決設定結構的相容問題,不會讓舊核心自動支援新協定,也無法修復已失效的節點憑證。
三種常見格式的結構差異
| 格式 | 辨識線索 | 通常包含 | 無法據此推斷 |
|---|---|---|---|
| URI 節點連結 | ss://、trojan://、vmess:// |
單一節點的位址、驗證資訊與部分傳輸參數 | 不代表包含分流規則、DNS 設定或策略群組 |
| Base64 節點清單 | 解碼後可看到逐行排列的 URI | 多個節點連結組成的編碼文字 | 不代表解碼後就是 Clash YAML |
| Clash YAML | proxies:、proxy-groups:、rules: 等鍵 |
節點、策略群組、規則,以及可選的 DNS、監聽設定 | 不代表所有 Clash 系列核心都支援相同欄位 |
URI:分享單一節點的表示方式
URI 常見結構包含「協定、驗證資訊、伺服器、連接埠、查詢參數、備註」。不同協定採用的欄位規則不盡相同。例如,常見的 vmess:// 分享內容會以 Base64 包裝 JSON;Shadowsocks 的分享方式則可能只編碼驗證資訊。不要用同一套字串拆分函式處理所有協定。
以下是用來說明欄位的虛構 Trojan 連結。example.com 是文件範例網域,密碼為示範文字,無法用來連線代理服務。查詢參數中的 sni 是 TLS 伺服器名稱,井字號後方則是節點備註。
trojan://[email protected]:443?security=tls&type=tcp&sni=example.com#Lab-Trojan
Base64:包裝清單的編碼層
常見訂閱會以換行分隔多個 URI,再將整段文字進行一次 Base64 編碼。正確流程是先解開外層編碼,再逐行交給對應協定的解析器。如果解碼後某一行仍包含 Base64,可能是該協定本身的分享格式,不要再對整份文字盲目重複解碼。
部分來源使用 URL 安全變體,以 -、_ 分別取代 +、/,也可能省略結尾的 =。這些差異屬於編碼處理,並非另一種代理協定。
YAML:完整設定與節點提供器要分開看
完整設定可以包含 proxies、proxy-groups、rules、dns 等設定區段。只含 proxies: 的檔案,常用作節點提供器檔案;它不等於已具備策略群組、規則和監聽設定的用戶端設定。將這類檔案當成完整設定匯入,可能會出現節點存在、規則卻仍直連的情況。
用戶端能否直接匯入
Clash 系列用戶端通常以 YAML 設定為主,但圖形介面的匯入能力取決於用戶端本身。Clash Verge Rev、FlClash 等用戶端的設定匯入功能,與 mihomo 核心讀取設定檔,是不同層面的功能。介面支援掃描 URI、貼上節點或轉換訂閱,不代表核心能直接載入任意 Base64 文字作為設定。
- 來源提供 Clash 或 Mihomo 選項:先選擇目標設定格式,再匯入訂閱 URL。若需要 VLESS、Reality 或其他擴充欄位,請確認目標核心是否支援。
- 只有一個 URI:確認用戶端是否支援匯入單一節點。若不支援,就需要轉成
proxies項目,並補上策略群組與規則。 - 只有 Base64 清單:先辨識解碼後的協定,再決定使用用戶端內建轉換功能,或在本機轉換。修改檔案副檔名並不會完成格式轉換。
- 已有完整 YAML:優先直接匯入,避免先匯出成 URI 再轉回 YAML。中間格式通常無法保留原設定中的規則與 DNS 設定。
不要把「Clash 格式」視為永久不變的相容保證。傳統 Clash、Clash Premium 與 Clash Meta(現多稱為 mihomo)的功能範圍並不相同。遇到 unsupported proxy type 或未知欄位錯誤時,請記下用戶端版本、實際核心版本與協定類型,再查詢相容範圍;只更新介面程式,不一定會更換目前使用的核心。
本機轉換:先解碼,再對應節點欄位
步驟一:確認取得的是訂閱本文
將回應內容儲存為本機檔案,並用文字編輯器檢查開頭。若內容是 <!DOCTYPE html>、登入提示或 JSON 錯誤物件,應先處理請求失敗的問題。HTTP 200 只表示伺服器有回應,不保證回應內容是有效訂閱;401、403 通常與驗證或存取限制有關。
部分服務會根據請求參數或 User-Agent 回傳不同格式。瀏覽器下載到節點清單、用戶端卻取得 YAML,可能是伺服器進行了格式協商。請以服務文件為準,不要隨意加上網路搜尋到的轉換參數。
步驟二:在本機解碼清單
以下 Node.js 指令碼只使用內建模組,僅執行 Base64 解碼,不會轉換協定。將已儲存的編碼本文命名為 subscription.txt,並將指令碼另存為 decode-subscription.cjs。輸入與輸出都留在本機;輸出檔仍含有敏感憑證。
const fs = require('node:fs');
const { TextDecoder } = require('node:util');
const input = fs.readFileSync('subscription.txt', 'utf8').trim();
const compact = input.replace(/\s+/g, '');
if (!compact || !/^[A-Za-z0-9+/_-]+={0,2}$/.test(compact)) {
throw new Error('輸入不是預期的 Base64 清單,請先檢查回應本文');
}
const normalized = compact.replace(/-/g, '+').replace(/_/g, '/');
const bare = normalized.replace(/=+$/, '');
if (bare.length % 4 === 1) {
throw new Error('Base64 長度異常,輸入內容可能不完整');
}
const bytes = Buffer.from(bare, 'base64');
if (bytes.toString('base64').replace(/=+$/, '') !== bare) {
throw new Error('Base64 內容無效或結尾位元異常');
}
const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
fs.writeFileSync('nodes.txt', text, { mode: 0o600 });
console.log('已寫入 nodes.txt;請在本機檢查協定與行數');
node decode-subscription.cjs
如果原始內容已是 URI 清單或 YAML,請勿執行這個步驟。不同作業系統對檔案權限參數的處理方式不一;輸出檔應放在個人目錄,避免存入會自動同步或公開分享的資料夾。解碼後,請確認每個節點各占一行,且沒有混入流量說明等非節點文字。
步驟三:將 URI 欄位轉成 YAML
以先前的 Trojan 範例為例,可以產生以下最精簡的示範設定。此設定將本機混合代理連接埠設為 7890、模式設為 rule,並將所有未預先符合規則的連線交由 出口選擇 處理。這段設定僅用來說明結構,示範伺服器無法用於連線測試。
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
proxies:
- name: "Lab-Trojan"
type: trojan
server: example.com
port: 443
password: "training-only"
sni: example.com
skip-cert-verify: false
proxy-groups:
- name: "出口選擇"
type: select
proxies:
- "Lab-Trojan"
- DIRECT
rules:
- MATCH,出口選擇
server 對應連線位址,port 是整數,password 對應 URI 的驗證資訊,sni 對應 TLS 名稱。範例中的 type=tcp 並未直接照搬成 YAML 的 type: tcp,因為此處的 type 指的是代理協定,應設為 trojan。這正是不能只靠相同欄位名稱替換來完成轉換的原因。
如果實際連結使用 WebSocket、gRPC 或 Reality,還需要依目標核心的語法對應路徑、Host、服務名稱、公鑰與短 ID 等參數。只保留伺服器與密碼,可能會產生語法正確卻無法連線的節點。不清楚欄位用途時,請選擇明確支援該協定及傳輸方式的本機轉換工具,不要直接刪除報錯欄位。
如何保留規則、策略群組與節點欄位
| 來源欄位或設定區段 | 轉換檢查項目 | 遺漏後常見影響 |
|---|---|---|
| 節點名稱 | 名稱不可重複,群組引用必須完全相符 | 策略群組引用失敗或出現歧義 |
| TLS 與傳輸參數 | SNI、憑證驗證、路徑與協定擴充欄位 | 交握失敗、連線遭到關閉 |
proxy-groups |
群組名稱、群組類型、成員與測試設定 | 無法選擇出口,或自動選擇行為改變 |
rules |
原有順序、目標名稱與最後的兜底規則 | 原本應走代理的連線變成直連 |
dns、tun |
由本機設定或用戶端覆寫繼續管理 | 解析方式與流量接管方式改變 |
將 URI 清單轉成 YAML 時,分流規則與策略群組通常是由轉換範本建立,而不是從節點中還原。若範本產生了 DOMAIN-SUFFIX,example.org,DIRECT,那只是範本規則;原始節點連結並未包含這條規則。遷移前後應分別比較節點參數與路由策略,不能只比較節點數量。
從完整 YAML 匯出 URI,則會遺失大量設定脈絡。策略群組的巢狀關係、rule-providers、DNS 策略與 TUN 設定,都沒有通用的單節點 URI 表示方式。再次轉換回來時,也只能依範本重新產生,無法還原原檔的註解、排序或所有功能。
使用節點提供器,減少重複轉換
如果服務提供節點型 YAML,就能將節點更新與本機規則分開管理。以下示範 mihomo 設定中的本機 proxy-providers 用法:先透過外部流程更新 ./providers/lab.yaml,再由策略群組透過 use 引用。該檔案必須是受支援的提供器格式,不能仍是經 Base64 編碼的清單。
proxy-providers:
lab:
type: file
path: ./providers/lab.yaml
proxy-groups:
- name: "出口選擇"
type: select
use:
- lab
rules:
- MATCH,出口選擇
提供器檔案採用以下節點包裝結構,內部項目的欄位與 proxies 中的節點相同。相對路徑會依核心的工作目錄或用戶端管理方式解析,不一定相對於手動開啟的 YAML 所在目錄;找不到檔案時,請查看核心記錄中的實際路徑。
proxies:
- name: "Lab-Trojan"
type: trojan
server: example.com
port: 443
password: "training-only"
sni: example.com
skip-cert-verify: false
若改用 HTTP 提供器,更新網址仍須回傳目標核心可接受的節點內容。更新間隔不等於格式轉換器。也請一併檢查完整設定中的遠端規則與自動更新 URL;不希望被訂閱覆蓋的本機設定,可透過用戶端提供的覆寫或合併機制管理。實際設定位置依用戶端而異。
匯入失敗與轉換後的檢查清單
先判斷錯誤發生在哪個層面
- 顯示 YAML 解析失敗:檢查縮排是否使用空格、冒號後是否缺少空格,以及密碼和備註是否正確加上引號。未加引號且包含
#的文字,可能會被解析成註解。 - 顯示找不到策略:確認規則目標與策略群組名稱。
MATCH,出口選擇必須指向同名群組;節點重新命名後,也要更新相關引用。 - 顯示不支援此協定:確認目前實際載入的核心。將
type改成另一個協定名稱,並不能完成協定轉換。 - 設定載入成功但連線逾時:檢查節點驗證資訊、TLS 與傳輸參數,再確認網路和伺服器狀態。語法有效不代表節點一定能連線。
- 重新啟動後修改消失:通常是訂閱更新重新產生了檔案。請將長期修改放進用戶端覆寫設定,或維護獨立的本機設定。
依序重新測試
- 備份原始設定,並記錄原有節點數、群組名稱與規則模式。不要直接覆寫唯一可用的設定檔。
- 檢查轉換結果是否包含驗證資訊與傳輸參數。比對敏感欄位時請在本機進行,不要將完整截圖傳到公開討論區。
- 若有 mihomo 命令列環境,可執行
mihomo -t -f ./config.yaml檢查設定;測試期間仍可能讀取外部檔案或請求遠端資源,請先檢視設定內容。 - 載入後手動選擇一個節點,確認目前使用規則模式,並查看連線記錄中實際命中的策略。
- 若使用範例連接埠
7890,可透過curl --proxy http://127.0.0.1:7890 https://example.com/測試本機代理入口。測試時須換成實際可用的節點設定,而且這不代表 TUN、UDP 或所有規則都已通過驗證。 - 最後執行一次訂閱更新並重新啟動用戶端,確認節點仍存在、覆寫設定仍生效,且規則目標沒有指向不存在的名稱。
選擇轉換方式時,可依以下優先順序處理:先請服務提供目標 YAML,其次使用用戶端明確支援的本機匯入功能,最後才考慮可檢視的本機轉換。需要長期更新時,分開管理節點來源與本機規則,比反覆將整份設定轉成 URI 再轉回來更容易排查問題。欄位語法可參閱設定大全;用戶端與核心的選擇可參考橫向評測。