兩個內核的版本現況與血緣
原版 Clash(Dreamacro/clash)在 2023 年底封存,最後一個正式版本是 v1.18.0,之後不再有新提交。同期還有一個閉源的 Clash Premium 內核,提供過 TUN、rule-provider 與 script 能力,但它不開源,也隨原版一同停止更新。Clash.Meta 是社群在原版內核基礎上重寫的分支,2024 年改名為 mihomo,儲存庫為 MetaCubeX/mihomo,目前仍在持續更新。
設定檔層面兩者是向上相容的:port、socks-port、mixed-port、allow-lan、mode、log-level、external-controller、proxies、proxy-groups、rules 這些欄位兩邊都認。差異集中在四塊:入站協定、規則類型、DNS 解析鏈路、TUN 實作。以下逐塊對照,並列出搬移時必須改寫的欄位。
| 能力 | 原版 Clash v1.18.0 | mihomo |
|---|---|---|
| 入站方式 | port、socks-port、redir-port 三個頂層開關 | 頂層開關 + listeners 段宣告多個入站 |
| 代理協定 | ss、vmess、trojan、snell、socks5、http | 上述全部 + vless、hysteria2、tuic、wireguard、ssh、anytls |
| 規則類型 | 網域、IP、連接埠、GEOIP、MATCH | 上述全部 + GEOSITE、IP-ASN、正規表達式、邏輯組合、SUB-RULE |
| 規則集 | 不支援,規則只能寫死在設定檔裡 | rule-providers,支援 mrs 二進位格式 |
| DNS | nameserver + fallback + fallback-filter | nameserver-policy、分流 DNS、DoQ、fake-ip 白名單模式 |
| TUN | 不支援 | system / gvisor / mixed 三種堆疊 |
| 維護狀態 | 2023 年底封存 | 持續更新 |
協定支援:哪些 proxy type 只有 mihomo 認
原版 Clash 的 proxies 段只認六個 type:ss、vmess、trojan、snell、socks5、http。遇到清單外的 type,內核在解析階段就報 unsupported proxy type 並退出,不會跳過這個節點繼續執行——這是換內核後最常見的第一類錯誤。
mihomo 在這份清單上補了 vless(含 XTLS Vision 與 REALITY)、hysteria2、tuic v5、wireguard、ssh、anytls,並把 Shadowsocks 的加密方式擴到 2022 系列:2022-blake3-aes-128-gcm、2022-blake3-aes-256-gcm、2022-blake3-chacha20-poly1305。以下三個節點的欄位組合,原版內核一條都解析不了。
proxies:
- name: vless-vision
type: vless
server: edge.example.com
port: 443
uuid: 8f2c1d40-3a7e-4b91-9c2d-5e6f7a8b9c0d
network: tcp
tls: true
udp: true
flow: xtls-rprx-vision
servername: www.example.com
client-fingerprint: chrome
reality-opts:
public-key: uM7Kd2QpX1sVbN4tRzY8wLcE3aHfJgOiPqSvTnBm5kU
short-id: 6ba85179e30d4fc2
- name: hy2-edge
type: hysteria2
server: edge.example.com
port: 8443
password: 9f2c7d1a4b6e
sni: www.example.com
skip-cert-verify: false
up: "30 Mbps"
down: "200 Mbps"
- name: tuic-edge
type: tuic
server: edge.example.com
port: 10443
uuid: 8f2c1d40-3a7e-4b91-9c2d-5e6f7a8b9c0d
password: 9f2c7d1a4b6e
congestion-controller: bbr
udp-relay-mode: native
alpn: [h3]
判斷一份訂閱能不能繼續餵給原版內核,只看兩處:proxies 裡出現過的 type,以及 ss 節點的 cipher。type 落在 ss、vmess、trojan、snell 之內,cipher 又是 aes-128-gcm 這類舊值時,兩邊都能跑;一旦出現 reality-opts、congestion-controller 或 2022-blake3- 開頭的加密方式,就必須換 mihomo。
規則語法與比對順序
比對模型兩邊一致:rules 由上而下逐條比對,命中第一條就停止,由 MATCH 作為最後備援。差異在可用類型、比對成本,以及規則集的載入方式。
| 規則類型 | 原版 Clash | mihomo | 說明 |
|---|---|---|---|
| DOMAIN / DOMAIN-SUFFIX / DOMAIN-KEYWORD | 支援 | 支援 | 走網域索引,單條成本極低 |
| DOMAIN-REGEX / DOMAIN-WILDCARD | 不支援 | 支援 | 逐條正規表達式比對,放頂部會拖慢首包 |
| IP-CIDR / IP-CIDR6 / SRC-IP-CIDR | 支援 | 支援 | 網域連線會觸發解析,建議加上 no-resolve |
| GEOIP | 支援 | 支援 | 相依 GeoIP 資料檔 |
| GEOSITE | 不支援 | 支援 | 相依 geosite 資料檔 |
| IP-ASN / IP-SUFFIX | 不支援 | 支援 | 依 ASN 或 IP 後綴段分流 |
| PROCESS-NAME | 僅閉源 Premium | 支援 | 桌面端按行程名稱分流 |
| PROCESS-PATH / PROCESS-NAME-REGEX | 不支援 | 支援 | 按執行檔路徑比對 |
| RULE-SET | 僅閉源 Premium | 支援 | 可加 format: mrs |
| SUB-RULE / AND / OR / NOT | 不支援 | 支援 | 多條件組合,注意括號與逗號 |
| IN-TYPE / IN-USER / IN-PORT / NETWORK | 不支援 | 支援 | 按入站來源與傳輸層協定比對 |
| MATCH | 支援 | 支援 | 必須放在最後一條 |
規則集的差異比規則類型更容易被忽略。原版 Clash 不支援 rule-providers,規則只能寫死在 config.yaml 裡;mihomo 的 rule-providers 支援 behavior 取 domain、ipcidr、classical,format 取 yaml、text、mrs,其中 mrs 是二進位格式,只能搭配 domain 或 ipcidr。mrs 在載入時按網域前綴建立索引,不需要把整份 YAML 解析成物件,規則條數上萬時差距最明顯。
rule-providers:
reject-list:
type: http
behavior: domain
format: mrs
url: "https://rules.example.com/reject.mrs"
path: ./ruleset/reject.mrs
interval: 86400
rules:
- DOMAIN-SUFFIX,example.org,直連
- GEOSITE,category-ads-all,REJECT
- RULE-SET,reject-list,REJECT
- IP-CIDR,198.18.0.0/16,直連,no-resolve
- AND,((NETWORK,udp),(DST-PORT,443)),節點選擇
- MATCH,節點選擇
寫 rules 段時,有三個順序問題最容易踩:
- 具體網域要放在 GEOSITE 之前。GEOSITE 命中範圍大,如果寫在 DOMAIN-SUFFIX,example.org 前面,後面那條規則永遠不會執行。
- IP-CIDR 放在網域規則之前時,網域連線必須先解析出 IP 才能比對,既多一次 DNS 查詢,也會把解析結果交給上游解析器。加上 no-resolve 可以讓網域連線直接跳過這條。
- MATCH 指向的策略組裡要留至少一個可用節點。規則集更新後出現未涵蓋的網域時,全部流量都會落到 MATCH,組內為空的表現就是整台機器斷網。
GEOSITE 與 GEOIP 相依資料檔。原版 Clash 首次啟動會去下載 Country.mmdb;mihomo 增加了 geodata-mode、geox-url、geo-auto-update 與 geo-update-interval,可以把資料來源換成自建位址並按小時級週期自動更新,不必手動替換檔案。
DNS 與 fake-ip 的實作差異
原版 Clash 的 dns 段只有 nameserver、fallback、fallback-filter、enhanced-mode、fake-ip-range、fake-ip-filter、hosts 這幾組開關,所有網域走同一條解析鏈路,靠 fallback-filter 的 geoip 與 ipcidr 判斷結果是否可信。以下是舊設定裡最常見的寫法:
# 原版 Clash 的寫法,mihomo 仍能解析,但不建議繼續沿用
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- 223.5.5.5
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
ipcidr:
- 240.0.0.0/4
mihomo 把解析拆成多條鏈路:default-nameserver 只用來解析 DNS 伺服器本身的網域,必須填 IP;proxy-server-nameserver 負責解析代理伺服器位址;direct-nameserver 處理直連流量;nameserver-policy 按網域或規則集指定上游。這個拆分解決的是同一個問題——代理伺服器的網域用哪條鏈路解析,直接決定節點能不能連上。
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter-mode: blacklist
fake-ip-filter:
- "*.lan"
- "+.stun.*.*"
default-nameserver:
- 223.5.5.5
- 1.1.1.1
proxy-server-nameserver:
- https://223.5.5.5/dns-query
nameserver:
- https://1.1.1.1/dns-query
- quic://dns.adguard-dns.com:784
nameserver-policy:
"geosite:cn":
- 223.5.5.5
"rule-set:reject-list":
- rcode://refused
respect-rules: true
cache-algorithm: arc
兩處行為差異值得單獨記下:fake-ip-filter 在原版 Clash 裡只有黑名單語意,mihomo 增加了 fake-ip-filter-mode: whitelist,可以反過來寫成只對清單內網域分配假 IP;nameserver-policy 的鍵支援 geosite: 與 rule-set: 前綴,不必再維護一長串 fallback-filter.domain。另外 respect-rules: true 會讓 DNS 查詢本身也走 rules 分流,開啟前必須先把 proxy-server-nameserver 設好,否則解析請求可能繞回自身形成無窮迴圈。
TUN 實作與三種網路堆疊
原版開源 Clash 完全沒有 TUN,TUN 只存在於閉源的 Premium 內核裡,且可調參數很少。mihomo 則把 TUN 納入設定的一級選項,欄位從裝置名稱、MTU 一路涵蓋到 Android 的按套件名稱放行。
tun:
enable: true
stack: mixed
device: mihomo
mtu: 9000
auto-route: true
auto-detect-interface: true
strict-route: false
dns-hijack:
- any:53
udp-timeout: 300
endpoint-independent-nat: false
gso: true
gso-max-size: 65536
stack 三個取值的取捨:
- system:資料封包交給系統協定堆疊轉發,吞吐量最高,代價是相依系統的路由與防火牆狀態,多網卡和 IPv6 環境下更容易出現迴圈或流量外洩。
- gvisor:純使用者態實作,跨平台行為一致,不依賴系統轉發,單一連線吞吐低於 system,適合路由表複雜或權限受限的環境。
- mixed:TCP 交給系統堆疊、UDP 交給 gvisor 堆疊,是多數客戶端的預設值,也是從 gvisor 切到 system 之前可以先跑一輪的中間選項。
各平台的相依條件不同:Windows 需要 wintun 驅動和系統服務權限,建立虛擬網卡失敗時日誌裡會出現 configure tun interface;macOS 使用 utun 裝置,首次啟用會要求網路權限;Linux 上 auto-route 會寫入路由表,auto-redirect 用 nftables 把流量重導向進 TUN,不再需要手寫 iptables 規則;Android 客戶端透過 include-package 與 exclude-package 控制哪些應用程式走 TUN。
效能取捨與搬移順序
規則比對的開銷主要看類型和條數。網域類規則走索引,單條成本很低;DOMAIN-REGEX、PROCESS-NAME-REGEX 是逐條正規表達式比對,放在 rules 頂部會拖慢每個新連線的首包。連線側還有幾個開關值得按需開啟:
- tcp-concurrent: true —— 對同一網域的多個解析結果並行握手,縮短首包等待,代價是並行連線數上升。
- unified-delay: true —— 延遲測試統一按完整握手耗時計算,避免不同協定之間的數值無法比較。
- sniffer 段 —— 對 IP 直連的流量還原網域,讓網域規則能命中;override-destination 會把目標位址改寫成還原出的網域,部分內網情境需要關掉。
- find-process-mode: strict —— 行程比對只在新連線建立時查詢一次,比 always 更省 CPU。
mixed-port: 7890
allow-lan: false
mode: rule
log-level: warning
ipv6: false
unified-delay: true
tcp-concurrent: true
find-process-mode: strict
external-controller: 127.0.0.1:9090
profile:
store-selected: true
store-fake-ip: true
sniffer:
enable: true
sniff:
HTTP:
ports: [80, 8080-8880]
override-destination: true
TLS:
ports: [443, 8443]
QUIC:
ports: [443]
從原版 Clash 搬到 mihomo,順序可以固定成六步,每一步都能單獨驗證結果:
-
備份舊設定
把 config.yaml 與 ruleset 目錄整個複製一份,記錄舊內核的版本字串,方便還原時對照。
-
先做語法檢查
用 mihomo -t -f config.yaml -d /etc/mihomo 做一次不啟動的解析,unsupported proxy type 會在這一步浮現,不必等到啟動後看日誌。
-
處理協定段
保留 hysteria2、tuic、vless 節點,逐條核對欄位名稱;ss 節點的 2022-blake3- 加密需要內核版本支援,舊版內核會直接拒絕。
-
改寫 DNS
補上 default-nameserver 與 proxy-server-nameserver,把 fallback 清單搬進 nameserver-policy,fake-ip-range 保持 198.18.0.1/16 即可。
-
最後再開 TUN
先確認驅動與服務就緒,stack 從 mixed 起步,dns-hijack 用 any:53,確認路由與解析都正常後再考慮改成 system。
-
觀察連線與規則命中
開啟 external-controller: 127.0.0.1:9090,在面板裡看連線清單與規則命中,確認沒有流量全部落到 MATCH。
需要留在原版 Clash 的情境也存在:設定檔裡只有 ss、vmess、trojan,規則全寫在 rules 段,沒有 TUN 需求,那麼換內核帶來的效益有限,改動風險反而更高。是否搬移的判斷標準很簡單——上面四塊裡有沒有哪一項用到了 mihomo 獨有的寫法,有就換,沒有就先不動。