先区分订阅地址、节点列表与完整配置
Clash 客户端里的“订阅”不是一种固定文件格式。用户拿到的通常只是一个 HTTPS 地址,客户端访问该地址后,服务器可能返回完整 Clash YAML、只包含节点的代理提供者文件,也可能返回经过 Base64 编码的通用节点列表。链接外观看起来相似,响应内容却可能完全不同。
完整 Clash 配置不仅包含节点,还可能包含监听端口、运行模式、代理组、规则集、DNS、TUN 与流量嗅探设置。通用 Base64 订阅通常只负责传递若干节点 URI,例如 ss://、trojan://、vmess:// 或 vless://。节点列表本身没有说明“国外网站走哪个组”“局域网地址是否直连”以及“最终未命中流量如何处理”。
第三类常见内容是 Mihomo 或 Clash 的代理提供者文件。它也是 YAML,但顶层通常只有 proxies:,用于被主配置中的 proxy-providers 引用。它不一定能作为完整配置直接启动。把这三类内容分清,才能判断应该直接导入、作为 provider 使用,还是先转换格式。
| 内容类型 | 常见开头或字段 | 包含规则与代理组 | 典型用途 |
|---|---|---|---|
| 完整 Clash YAML | mixed-port:、proxies:、proxy-groups: |
通常包含 | 作为客户端主配置导入 |
| 代理提供者 YAML | 顶层以 proxies: 为主 |
通常不包含 | 由 proxy-providers 定时加载 |
| Base64 节点订阅 | 长段字母、数字、加号、斜杠或 URL 安全字符 | 不包含 | 供兼容客户端读取,或转换成 Clash 配置 |
| 单节点 URI | ss://、trojan://、vmess:// |
不包含 | 手动导入单个节点 |
Clash YAML 配置里有什么
YAML 是可读的结构化文本。缩进表示层级,列表项通常以连字符开头。Clash 与 Mihomo 读取配置时会解析字段名称、数据类型和缩进关系,因此两个空格、布尔值、引号和冒号都可能影响结果。节点名称中含有冒号、井号或方括号时,使用引号通常更稳妥。
下面是一份缩减后的结构示例。端口 7890、控制端口 9090 都是常见示例值,不是所有客户端的固定默认值;实际监听值应以客户端“设置”或运行日志为准。
mixed-port: 7890
allow-lan: false
mode: rule
external-controller: 127.0.0.1:9090
proxies:
- name: "Tokyo-01"
type: ss
server: edge.example.net
port: 443
cipher: aes-128-gcm
password: demo-password
proxy-groups:
- name: "节点选择"
type: select
proxies:
- "Tokyo-01"
- DIRECT
rules:
- DOMAIN-SUFFIX,example.org,节点选择
- GEOIP,LAN,DIRECT
- MATCH,节点选择
proxies 定义可用节点,proxy-groups 把节点组织成手动选择、延迟测试或故障转移组,rules 按顺序决定连接去向。规则从上到下匹配,通常由 MATCH 处理前面没有命中的连接。只有节点而没有代理组与规则时,客户端可以通过额外模板补齐,但这已经是客户端或转换器执行的二次处理。
完整配置与 provider 文件的边界
代理提供者文件的职责更窄。主配置负责声明下载地址、刷新周期和健康检查,远端文件只交付节点。下面的 interval: 86400 表示每 86400 秒,也就是每 24 小时更新一次;健康检查每 600 秒访问一次测试地址。
proxy-providers:
airport-main:
type: http
url: "https://sub.example.net/clash-provider.yaml"
path: ./providers/airport-main.yaml
interval: 86400
health-check:
enable: true
interval: 600
url: "https://www.gstatic.com/generate_204"
如果把只有 proxies: 的 provider 文件直接当成主配置,客户端可能提示缺少代理组,也可能导入后看不到预期的分流入口。反过来,把含有 DNS、TUN 和规则的完整配置塞进 provider 路径,也不符合 provider 的数据结构。
Base64 订阅到底编码了什么
Base64 是文本编码,不是加密。它把原始节点 URI 转换成由有限字符组成的文本,方便通过接口传输。解码之后通常是一行一个节点,每一行仍需由客户端按对应协议解析。Base64 内容可能采用标准字符集,也可能使用 URL 安全变体,以连字符和下划线替代加号和斜杠。
ss://[email protected]:443#Tokyo-01
trojan://[email protected]:443?security=tls#Singapore-02
vless://[email protected]:443?security=tls&type=ws#Los-Angeles-03
这些 URI 描述服务器、端口、认证信息、传输方式和备注,但没有统一承载 Clash 代理组与规则的能力。转换器要生成可运行配置,就必须额外套用模板。例如把全部节点放入名为“节点选择”的 select 组,再添加 DIRECT 与最终 MATCH 规则。
为什么有时解码后仍然看不懂
- 外层 Base64 解码后可能得到多行 URI,其中某一条
vmess://后面仍是独立的 Base64 JSON。 - 服务器可能先使用 gzip 压缩响应。浏览器和
curl --compressed通常会自动处理,直接复制原始字节则可能显示乱码。 - 返回内容可能是错误页面。登录失效、访问频率限制或令牌过期时,服务器可能返回 HTML,而不是订阅。
- 订阅可能使用 URL 安全 Base64,末尾省略填充字符
=,部分严格解码工具会因此报错。 - 节点协议或扩展参数超出旧版 Clash 内核支持范围,格式可以成功解码,客户端仍会拒绝载入。
四步判断手上的订阅格式
第一步:先看客户端给出的错误位置
“下载失败”和“解析失败”不是同一问题。前者通常发生在 DNS、TLS、网络连接、HTTP 状态码或订阅令牌环节;后者说明客户端已经取得响应,但无法按目标格式读取。若日志显示 HTTP 401 或 403,应先更新订阅地址。若显示 yaml: line 18、mapping values are not allowed 或 proxy 2: unsupported type,才应继续检查内容和内核兼容性。
第二步:保存响应,不要只看链接文字
可以在终端把测试订阅保存到文件。真实订阅 URL 通常包含访问令牌,不应粘贴到公开截图、在线论坛或公共命令记录。下面使用的是示例域名与演示令牌。
curl -L --compressed \
'https://sub.example.net/api/v1/client/subscribe?token=demo-token' \
-o subscription.txt
wc -c subscription.txt
head -c 160 subscription.txt
-L 会跟随重定向,--compressed 允许服务器返回压缩内容。文件只有几十字节且以 <html、{"error" 或登录提示开头时,问题通常不在 Clash 格式,而在接口响应。正常订阅可能从数 KB 到数百 KB,不存在统一长度标准。
第三步:检查可见字段
- 出现
proxies:、proxy-groups:和rules:,通常是完整 Clash YAML。 - 只有顶层
proxies:和节点数组,通常是 provider YAML。 - 直接出现多行
ss://、trojan://或vless://,属于明文节点列表。 - 主体是一整段 Base64 字符,解码后再按前三项判断。
- 出现网页标题、验证码、登录表单或 JSON 错误对象,说明服务端没有返回订阅数据。
第四步:确认目标内核
Clash Premium、Clash Meta 与后续 Mihomo 并不是完全相同的配置目标。Mihomo 支持更多协议字段、规则能力、DNS 选项和 TUN 参数。转换时只选择“Clash”这一宽泛目标,可能生成面向旧内核的保守格式,也可能带入旧客户端无法识别的字段。使用 Mihomo 内核的客户端,应优先选择明确标注 Mihomo 或 Clash Meta 的输出目标。
Base64 与 YAML 的互转方法
方法一:使用客户端自带的兼容导入
部分桌面客户端会在订阅导入阶段识别通用 URI 列表,并自动生成本地配置。以采用 Mihomo 内核的客户端为例,通常从“订阅”或“配置”页面添加远程 URL,再由客户端解析响应。具体入口可能显示为「订阅」→「新建订阅」或「配置」→「导入 URL」。导入后应检查配置详情,确认生成了代理组和最终规则,而不是只看“更新成功”提示。
自动兼容适合快速使用,但生成策略由客户端决定。一个客户端可能把全部节点放入手动选择组,另一个可能增加自动延迟测试组。迁移到另一客户端时,组名、规则与 DNS 设置未必一致。
方法二:使用订阅转换服务
转换服务通常接收源订阅、目标格式和模板参数,然后下载源内容、解析节点并输出 Clash 或 Mihomo YAML。常见流程是选择目标为 Mihomo,填入订阅 URL,指定远程配置模板,再生成新的订阅地址。客户端以后访问的是转换后的地址,而不是直接读取原始 Base64。
模板决定最终配置质量。至少应检查以下项目:
- 代理组中是否包含全部需要的节点,是否存在引用了但未定义的组名。
- 规则末尾是否有合理的兜底项,例如
MATCH,节点选择。 - 局域网、常见私有地址和本机地址是否按预期直连。
- DNS 配置是否与当前网络环境匹配,是否误用了不可访问的上游。
- TUN、嗅探和 IPv6 设置是否适配当前操作系统,而不是从模板机械继承。
- 输出目标是否为客户端实际使用的 Mihomo 或对应 Clash 内核。
方法三:本地解码后套用配置模板
只想确认 Base64 内容时,可以本地解码,不必把订阅交给第三方网页。Python 3 的下面这段命令会读取文件、补齐缺失的 Base64 填充并输出到 decoded.txt。它只负责解码,不负责把 URI 转换成 Clash 节点对象。
python3 -c "import base64,pathlib; p=pathlib.Path('subscription.txt').read_text().strip(); p += '=' * (-len(p) % 4); pathlib.Path('decoded.txt').write_bytes(base64.urlsafe_b64decode(p))"
head -n 5 decoded.txt
完整转换还需要逐个解析协议 URI,并正确映射 TLS、WebSocket、gRPC、Reality、UDP 与证书校验等参数。手工复制几个字段容易遗漏传输层设置,因此更适合调试少量节点,不适合作为长期维护方式。节点较多时,应使用持续维护且明确支持目标内核的本地转换工具。
转换后导入 Clash 或 Mihomo
得到 YAML 后,不要立即覆盖当前可用配置。先另存为新配置,再执行语法检查和小范围连接测试。桌面客户端中的典型流程是「配置」→「新建」或「从 URL 导入」→「更新」→「设为当前配置」。不同客户端名称略有差异,但都应保留旧配置,直到新配置完成验证。
先检查 YAML 结构
至少确认 proxies、proxy-groups 和 rules 中的名称能够互相对应。代理组引用一个不存在的节点,或者规则指向一个不存在的组,都会导致启动失败或分流异常。YAML 中不能使用 Tab 代替缩进空格,同一层级建议统一使用两个空格。
再检查监听端口
配置写入 mixed-port: 7890 后,系统代理也应指向本机 127.0.0.1:7890。如果客户端实际使用 HTTP 端口 7890、SOCKS 端口 7891,终端环境变量必须选择对应协议。端口已被其他进程占用时,日志常见信息是 address already in use,此时改格式没有作用。
HTTP_PROXY=http://127.0.0.1:7890
HTTPS_PROXY=http://127.0.0.1:7890
ALL_PROXY=socks5://127.0.0.1:7891
最后验证规则、DNS 与 TUN
- 在代理页手动选择一个可用节点,排除自动策略组选择错误。
- 打开连接页,确认测试请求命中了预期代理组,而不是
DIRECT或REJECT。 - 查看日志中的域名解析结果,确认没有持续出现 DNS 超时。
- 仅在普通系统代理验证通过后再启用 TUN,减少同时排查多个变量。
- 开启 TUN 后确认客户端具备所需系统权限,并检查默认路由与局域网访问是否正常。
TUN 模式解决的是不读取系统代理的应用流量接管问题,不会修复无效节点、错误认证信息或损坏的 YAML。转换后普通代理都无法建立连接时,应先回到节点参数、内核支持与订阅有效期,而不是反复切换 TUN。
高频导入失败与对应处理
| 现象 | 优先判断 | 处理方法 |
|---|---|---|
| 更新订阅后立即提示 YAML 解析错误 | 返回的是 Base64、HTML 或缩进损坏 | 保存响应,检查文件开头;确认目标格式后重新转换 |
| 导入成功但代理页为空 | 导入的是 provider 文件,或代理组没有引用节点 | 检查顶层字段与 proxy-groups 引用 |
| 节点存在但全部超时 | 节点失效、协议字段不兼容、DNS 或网络受限 | 查看单节点错误日志,核对目标内核和传输参数 |
| 转换后规则全部直连 | 模板组名与规则目标不一致 | 检查规则第三段与代理组名称是否完全相同 |
| 订阅更新返回 401 或 403 | 令牌失效、权限限制或请求方式不符 | 重新获取订阅地址,确认账户状态与请求头要求 |
| 旧客户端提示 unsupported proxy type | 输出包含当前内核不支持的协议或字段 | 升级到兼容的 Mihomo 客户端,或选择对应旧内核目标 |
| 转换地址能用一次,之后无法更新 | 临时链接过期、转换端缓存或源令牌变化 | 检查转换服务有效期,重新生成并核对源地址 |
避免重复转换
原始订阅经过转换服务 A 生成 Clash YAML,再把这个结果交给服务 B 转换,容易出现节点备注变化、策略组被重建、规则模板被覆盖和参数丢失。应尽量保持单一转换链:原始订阅直接进入目标转换器,再由客户端读取最终地址。
不要把订阅更新等同于配置覆盖
有些客户端允许用户在远程配置基础上添加本地覆写,例如修改端口、DNS 或规则。远程更新后,本地覆写是否保留取决于客户端实现。修改前应区分“编辑下载后的缓存文件”“编辑远程配置副本”和“添加持久化覆写”三种操作,否则下次更新可能恢复原始内容。
格式选择的实用结论
如果订阅提供方可以直接输出 Mihomo 或 Clash YAML,应优先使用与当前内核匹配的原生格式。它能完整表达节点参数,并可携带代理组和规则。只有通用 Base64 时,再通过客户端兼容层或可信转换工具生成 YAML。
如果需要自己维护规则,较稳定的结构是把节点放在 provider 文件中,由本地主配置负责代理组、规则、DNS 和 TUN。这样节点更新不会直接覆盖规则逻辑,主配置也不必随每次订阅刷新而重新生成。provider 更新周期可以设为 86400 秒,健康检查周期按节点数量和网络条件设置为 300 至 600 秒。
排查时始终把问题拆成四层:订阅地址能否访问、响应属于哪种格式、目标内核能否解析、运行后的规则与网络是否正确。格式转换只处理第二层和部分第三层,不能替代节点有效性、端口监听、DNS 与系统代理检查。