先看返回内容:订阅地址不等于配置格式

导入 Clash 订阅失败,先别急着换客户端。同一个 HTTPS 地址,可能返回可直接运行的 YAML 配置,也可能返回一串 Base64 文本,甚至是登录页面。地址以什么后缀结尾并不可靠:没有 .yaml 后缀的接口也可以返回 YAML,带这个后缀的地址也可能因为鉴权失效而返回错误信息。

把订阅分成三层更容易判断:订阅地址是获取入口,Base64 是文本编码,YAML 或 URI 才描述具体数据。其中 YAML 还要继续区分完整配置与只含节点的数据。把节点列表当完整配置导入,是常见的报错来源。

看到的内容 通常代表什么 下一步
proxies:、proxy-groups:、rules: 可能是完整 Clash 配置 检查节点、分组引用与内核兼容性
只有 proxies: 和节点条目 节点集合或 provider 数据 通过节点提供器接入,或合并到完整配置
多行 ss://、trojan:// 等链接 URI 节点列表 使用支持节点导入的界面,或转换格式
连续字母、数字及少量符号 可能是 Base64 编码内容 本地解码,再确认解码后的格式
<html>、登录提示、JSON 错误 网页或接口错误响应 检查订阅有效期、鉴权和访问限制

YAML 配置:节点、策略组和规则各管一层

YAML 是数据序列化格式,并非 Clash 专属。能被 YAML 解析器读取,只说明语法成立;客户端还会检查字段、节点协议和引用关系。对于基于 mihomo 的客户端,实际支持范围由正在运行的内核决定,不能只看界面名称里有没有 Clash。

一份最小示例的结构

下面展示本地入口、一个 Shadowsocks 节点、一个选择组和规则之间的关系。node.example.invalid 是保留的示例域名,密码也是演示值,不能用于实际连接。端口 7890 是这里明确设置的本地混合代理端口,不代表每个客户端都使用它。

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

proxies:
  - name: "Demo SS"
    type: ss
    server: node.example.invalid
    port: 443
    cipher: aes-128-gcm
    password: "demo-pass"

proxy-groups:
  - name: "手动选择"
    type: select
    proxies:
      - "Demo SS"
      - DIRECT

rules:
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,手动选择
  • proxies:保存服务器地址、协议、端口及认证信息。
  • proxy-groups:组织节点或其他策略,供用户选择或执行自动策略。
  • rules:从上到下匹配流量;上例末尾的 MATCH 接住剩余连接。
  • mixed-port:提供 HTTP 和 SOCKS 代理入口。客户端的覆盖设置可能改写这个值,应以运行配置为准。

这个示例用于解释结构,没有展开 DNS、TUN 和局域网访问策略。它不是通用的网络优化方案,也不能据此判断 DNS 请求实际走向。导入真实配置前,应保留服务提供方要求的传输层和认证字段。

YAML 最容易出错的三个位置

  1. 缩进:使用空格,不要使用 Tab。上例列表项缩进 2 个空格,节点属性缩进 4 个空格。
  2. 字符串:包含特殊符号的密码、节点名建议加引号。未被引号保护的 # 在特定位置会开始注释,导致内容被截断。
  3. 引用:节点名、策略组名要完全一致。把 Demo SS 改成 Demo-SS 后,组内引用也必须同步修改。

Base64 节点串:先解码,再谈导入

常说的“Base64 订阅”,通常是把多条 URI 链接用换行分隔,再将整段文本编码成 Base64。解码后得到的仍是节点列表,不会凭空出现规则、策略组或 DNS 配置。也有服务编码其他内容,所以最终判断依据始终是解码结果。

标准 Base64 常见字符有 +、/,结尾可能有 =;URL 安全变体则使用 - 和 _。部分接口省略末尾补位。不要因为没有等号就断定它不是 Base64,也不要把整个 HTTPS 订阅地址拿去解码。

本地查看解码结果

电脑已安装 Python 3 时,可以把订阅返回的编码正文保存为 subscription.txt,在该文件所在目录执行以下命令。脚本只读取本地文件,把结果写入 decoded.txt,不会上传内容。输出文件同样含有敏感凭据,用完应妥善清理。

python3 - <<'PY'
from pathlib import Path
import base64
import binascii

raw = Path("subscription.txt").read_text(encoding="utf-8-sig")
encoded = "".join(raw.split())
encoded += "=" * (-len(encoded) % 4)

try:
    decoded = base64.b64decode(
        encoded, altchars=b"-_", validate=True
    ).decode("utf-8")
except (binascii.Error, UnicodeDecodeError, ValueError) as error:
    raise SystemExit("解码失败:请检查输入是否为 Base64 文本") from error

Path("decoded.txt").write_text(decoded, encoding="utf-8")
print("已写入 decoded.txt,请在本地查看")
PY

这段命令使用类 Unix shell 的 here-document 写法,适用于 macOS、Linux 等环境;Windows 可将中间的 Python 代码保存为脚本后运行。解码失败时,先检查是否误存了网页内容、是否复制不完整,以及是否把文件外层的引号也复制进去了。

URI 链接:一条链接描述一个节点

URI 通常以协议名开头,例如 ss://、vmess://、vless:// 或 trojan://。它们并不共用同一种内部编码。常见 VMess 分享链接把 JSON 编码后放入链接,其他协议则可能使用用户信息、主机、端口和查询参数组合描述连接。

Shadowsocks 示例:只编码认证部分

ss://[email protected]:443#Demo%20SS

这条示例中,YWVzLTEyOC1nY206ZGVtby1wYXNz 解码后是 aes-128-gcm:demo-pass;node.example.invalid:443 是服务器和端口;#Demo%20SS 是经过百分号编码的显示名称。它对应前文的演示节点,但没有携带策略组与分流规则。

  • 百分号编码与 Base64 不同:%20 表示空格,应按 URI 组件解码,不要当作 Base64 处理。
  • 名称不等于参数:链接末尾的备注通常只影响显示;查询参数里的传输设置可能直接影响能否连接。
  • IPv6 地址注意方括号:在 URI 的主机位置通常需要用 [IPv6地址]:端口 的结构,不能简单按每个冒号切割。
  • SS 分享格式存在变体:认证信息编码、旧式整体编码、插件参数的兼容情况不同,转换器需要识别具体形式。

不要手工套用“找到冒号就拆开”的处理办法。密码可能含特殊字符,IPv6 自带冒号,WebSocket 路径也可能包含查询参数。可靠的转换需要按协议解析,而不是把所有链接用同一套字符串替换规则处理。

格式互转:哪些能保留,哪些会丢失

格式转换的核心是字段映射,不是简单改扩展名。只有源格式携带了某项数据,而且目标格式与目标内核都支持,转换器才有机会完整保留它。先确定目标是“节点列表”“provider 数据”还是“完整配置”,再选择转换方式。

转换方向 实际操作 主要限制
Base64 → URI 列表 解码外层文本 不增加规则和策略组
URI 列表 → Base64 按行整理后整体编码 只改变包装,不提高兼容性
URI 列表 → Clash YAML 解析节点,再补充分组和规则 模板决定分流行为,协议字段可能无法完整映射
完整 YAML → URI 列表 导出能映射成链接的节点 通常丢失规则、DNS、TUN 和策略组
完整 YAML → provider 文件 抽取节点,按 provider 格式输出 主配置仍需定义如何引用这些节点

转换后逐项核对这些字段

  1. 基础连接:服务器、端口、密码或 UUID、协议类型。端口必须保留原值,不能把所有节点都改成 443。
  2. 加密与 TLS:Shadowsocks 的加密方法、TLS 开关、SNI、ALPN,以及证书验证设置。不要为了通过测试而随意开启跳过证书验证。
  3. 传输层:WebSocket 的路径和 Host、gRPC 的 service name 等。相同地址与密码,传输层不同也可能无法连接。
  4. 协议扩展:Reality 公钥与 short ID、VLESS flow 等字段需同时得到转换器和内核支持。
  5. 命名与引用:重复节点名要明确处理,重命名后更新策略组引用,避免只改节点列表而留下失效名称。

原版 Clash 与 mihomo 的能力范围并不相同。目标内核不支持的协议,不能靠“转换为 Clash 格式”变成受支持协议。遇到新协议时,核对当前内核版本和对应字段文档,比反复切换订阅转换模板更有效。

导入路径:完整配置与节点提供器分开处理

完整 YAML:按配置导入并启用

客户端界面通常把完整配置放在“配置”或“Profiles”页面。不同客户端的菜单名称并不统一,操作时确认选择的是“从 URL 导入配置”或“导入本地配置”,而不是“添加单个节点”。导入完成后还要启用该配置,再检查运行日志。文件出现在列表里,不代表已经成为当前配置。

只有节点:使用 provider 或受控合并

mihomo 的代理提供器可以把节点来源与主配置分开管理。为便于跨客户端迁移,优先使用明确含 proxies: 的 YAML provider 文件;其他输入形式是否可用,要按所用内核版本核实。下面示例引用一个本地节点文件,并通过 use 将节点接入策略组。

proxy-providers:
  local-nodes:
    type: file
    path: ./providers/nodes.yaml

proxy-groups:
  - name: "订阅节点"
    type: select
    use:
      - local-nodes

rules:
  - MATCH,订阅节点

./providers/nodes.yaml 应包含类似前文的 proxies: 节点集合。相对路径的解析位置受内核工作目录与客户端管理方式影响,不一定是下载文件所在目录。该片段需要合并到主配置中,不要与已有配置重复声明同名顶层键或同名策略组。

远程 HTTP provider 还涉及更新地址、缓存路径和更新间隔。若设置 interval: 86400,单位是秒,即每 24 小时更新一次。远程节点列表更新与主配置更新是两条流程:前者更新节点,后者可能覆盖规则、DNS 等整份设置。

导入失败排查:按响应、语法、内核、运行顺序检查

  1. 检查返回内容。下载到本地后查看开头几行。HTTP 200 只代表请求成功返回,不保证正文就是配置;401、403 则优先检查鉴权与访问限制。某些服务根据 User-Agent 返回不同格式,浏览器与客户端看到的内容可能不同。
  2. 检查外层编码。如果是 Base64,先解码一次并查看结果。不要反复盲目解码,也不要把订阅地址、网页正文和编码节点串混在一起处理。
  3. 检查 YAML 语法。“mapping”“indentation”等错误通常与缩进、冒号、引号有关。记录报错行号,并检查前后几行;在线 YAML 检查器不适合直接粘贴含凭据的真实配置。
  4. 检查字段支持。“unsupported proxy type”通常指向协议与内核能力不匹配。先确认客户端实际启动的是哪个内核,再查看该内核的版本与支持列表。
  5. 检查名称引用。“proxy not found”一类错误要查节点名、策略组名、provider 名称是否一致。完整配置里只有节点、没有可用策略,也可能导致预期分流无法生效。
  6. 检查运行状态。配置加载成功后,再确认本地代理端口、系统代理或 TUN 是否按需启用。导入成功、代理入口启用、节点能够连接,是三个不同检查点。

转换后出现“节点能测速,网页打不开”,也不应立即归因于编码。测速仅覆盖指定测试请求;真实访问还受 DNS、路由规则、UDP 支持和应用代理设置影响。先查看失败连接命中了哪个策略、选中了哪个节点,再定位具体环节。

格式选型结论:优先拿到目标客户端原生可用的数据

  • 需要直接导入并使用:优先选择服务提供方明确标注适用于当前内核的完整 Clash 或 mihomo 配置,再核对分流与 DNS 设置。
  • 已有自己的规则:优先使用 provider 节点数据,保持主配置独立,减少订阅更新覆盖本地设置的机会。
  • 在不同客户端间迁移节点:URI 列表便于传递单节点,但要逐项复核协议扩展,不要期待它携带原来的全部策略。
  • 收到 Base64 文本:先本地解码识别内容。编码只是外壳,真正决定导入方式的是内部数据结构。

确实需要转换时,优先使用本地运行的工具或自己控制的服务。远程转换服务会接触订阅凭据或节点信息,输出还可能引入额外规则与配置。保存原始输入、转换结果和一份可用备份,按“结构检查 → 字段对照 → 启用测试”的顺序处理,出问题才有清晰的回退点。