两个内核的版本现状与血缘
原版 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 独有的写法,有就换,没有就先不动。