一、YAML 结构与配置读取顺序
Clash 配置文件本质上是一棵由键、值、列表和映射组成的数据树。顶层通常包含端口、运行模式、日志级别、DNS、代理节点、策略组与规则等部分。内核启动时先解析 YAML 语法,再校验字段类型,随后初始化监听端口、DNS 模块和出站代理,最后装载规则。只要前面的语法解析失败,后面的节点与规则就不会进入运行状态,因此排错时应先确认文件能被完整解析,再讨论某条规则是否命中。
YAML 依靠缩进表达层级,建议统一使用两个空格,不要混用制表符。冒号后通常要留一个空格;列表项以连字符开头;包含冒号、井号、花括号或特殊空格的文本适合放在引号内。井号在未被引号包裹时表示注释,后面的内容不会参与解析。布尔值应使用 true 或 false,端口等数字不要误写成带引号的文本。不同客户端可能在保存时重新排序字段,但只要层级和类型不变,顺序通常不影响顶层字段的含义。
最小结构如何扩展
一份便于理解的配置可以从监听端口、模式、节点、策略组和规则五部分开始。下面的示例只展示结构关系:节点先在 proxies 中定义,策略组再引用节点名称,规则最后把流量交给策略组。引用名称必须逐字一致,包括大小写、空格与符号。若规则指向一个不存在的策略组,内核通常会在校验阶段报告目标缺失。
mixed-port: 7890
mode: rule
log-level: info
allow-lan: false
proxies:
- name: "example-node"
type: socks5
server: 192.0.2.10
port: 1080
proxy-groups:
- name: "手动选择"
type: select
proxies:
- example-node
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,手动选择
- MATCH,DIRECT
示例中的地址属于文档用途,实际连接需要使用订阅提供的服务器信息。手工编写节点时,先确认协议类型和必填字段,再添加协议专属参数。订阅生成的配置往往更长,因为它还会包含 DNS、嗅探、规则集和多个策略组;阅读时不必从第一行硬看到最后一行,可以先找顶层键,再沿着“规则目标 → 策略组 → 节点”的引用链向前追踪。
锚点、别名与重复键
YAML 支持锚点和别名,用于复用一组参数,但并非所有客户端的可视化编辑器都能完整保留这类写法。配置经过订阅转换、图形界面保存或远程覆写后,锚点可能被展开成普通字段。如果配置需要频繁跨客户端迁移,直接写明字段通常更稳妥。另一个常见问题是重复键:同一映射层级里出现两个 mode 或两个 dns 时,解析器可能采用后者,也可能直接拒绝。不要依赖覆盖行为,应在合并前消除重复顶层键。
文件编码建议使用 UTF-8。策略组和节点名称可以使用中文,但外部脚本处理配置时,英文短名更方便匹配。换行格式一般不影响解析,不过从网页或聊天工具复制配置时,容易混入全角冒号、弯引号和不可见空格。看到“映射值不允许出现在此处”一类错误时,优先回到报错行及其上一行检查缩进、冒号和引号闭合,而不是立即删除整段配置。
二、通用字段、监听端口与运行模式
通用字段决定内核怎样接收本机或局域网流量,以及如何输出运行信息。最常见的入口是 mixed-port,它在同一端口接受 HTTP 和 SOCKS 代理请求,便于浏览器、终端和系统代理共同使用。也可以分别配置 port 与 socks-port,但这会增加端口管理成本。客户端界面中显示的“系统代理端口”通常就来自这些字段,修改文件后还要确认图形客户端没有用自身设置再次覆盖。
allow-lan 控制其他设备能否通过当前设备的代理端口接入。设为 false 时适合单机使用;设为 true 后,还应配合 bind-address 限定监听范围,并检查操作系统防火墙。允许局域网连接不等于自动完成身份验证,也不等于路由器会把流量转发到该端口。若只是手机与电脑各自运行客户端,没有必要开启局域网监听。
| 字段 | 常见值 | 用途与注意点 |
|---|---|---|
mixed-port | 1024—65535 范围内未占用端口 | 同时接受 HTTP 与 SOCKS 连接;修改后同步检查系统代理设置。 |
mode | rule、global、direct | 决定流量按规则、统一代理或直接连接处理。 |
log-level | info、warning、error、debug | 日常使用保留 info;排错时短时启用 debug,完成后恢复。 |
ipv6 | true 或 false | 控制内核相关模块是否处理 IPv6;还受系统网络与 DNS 配置影响。 |
external-controller | 回环地址与端口 | 为图形界面或控制面板提供控制接口,不应随意暴露到公共网络。 |
规则、全局与直连模式
rule 是日常使用最常见的模式。内核从上到下匹配 rules,命中后把连接交给对应策略组或出站。global 会绕过逐条规则判断,把流量统一交给全局策略;适合临时验证某个节点是否可用,但不适合作为判断规则正确性的依据。direct 则让流量直接连接,可用于快速区分问题来自代理链路还是本地网络。模式切换只改变路由决策,不会自动修复 DNS、证书、权限或系统代理未开启等问题。
图形客户端里的“规则、全局、直连”按钮通常会通过控制接口改变运行态,而不一定改写原始 YAML。重启后采用哪个模式,取决于客户端是否持久化运行态以及配置中的 mode。排查“重启后模式变回去”时,应同时检查配置文件、客户端设置和订阅更新行为。订阅每次更新都可能替换原文件,直接在订阅文件里修改通用字段,往往会在下次更新时丢失,更适合使用客户端提供的覆写功能。
系统代理与 TUN 的边界
监听端口只代表内核准备好接受代理请求,并不会自动让所有应用把流量送进去。系统代理是操作系统公布的一组代理地址,只有读取这项设置的应用会使用;TUN 模式则通过虚拟网络接口接管更广的 IP 流量。两者可以使用同一份规则与策略组,但流量入口不同。有关接管层级、兼容性与排错差异,可阅读TUN 模式和系统代理的工作机制对比。
mixed-port: 7890
allow-lan: false
bind-address: "*"
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
上例把控制接口限制在回环地址,适合本机图形客户端调用。即使 allow-lan 为 false,也建议明确理解每个监听地址的用途。端口冲突时,先关闭重复运行的客户端或调整端口,再确认系统代理仍指向新端口。只改 YAML 而不更新系统代理,会出现内核运行正常、浏览器却无法连接的表象。
三、DNS 配置与域名解析路径
DNS 是 Clash 配置中最容易被误判的一部分。访问一个域名时,应用可能先自行解析,也可能把域名交给代理协议;系统 DNS、浏览器安全 DNS、Clash DNS 模块和远端代理都可能参与。配置里的 dns.enable 只控制内核 DNS 模块是否启用,不能保证所有应用都把查询发送给它。使用系统代理时,部分应用仍会使用自身解析路径;使用 TUN 时,通常更容易统一接管,但还取决于 DNS 劫持和系统权限。
nameserver 是主要解析服务器列表,default-nameserver 用于解析 DNS 服务器自身的域名,避免出现“先解析解析器地址”的循环依赖。若 nameserver 直接写 IP,依赖较少;若写加密 DNS 的域名,就应为 default-nameserver 提供可直接访问的基础解析地址。fallback 和相关过滤字段适合更复杂的解析分流,不应在不了解来源时机械叠加,多条解析路径反而会让结果难以预测。
redir-host 与 fake-ip
enhanced-mode 常见值是 redir-host 与 fake-ip。redir-host 保留真实解析结果,理解直观,但在透明代理场景中,内核可能较难从纯 IP 流量还原域名。fake-ip 会为域名返回保留地址池中的临时地址,内核据此建立域名与连接的映射,再按域名规则处理。它不是把目标真正连接到该临时地址,而是利用映射完成路由。fake-ip 对规则匹配和透明接管通常更友好,但少数局域网服务、设备发现、游戏平台或依赖真实 IP 的应用需要加入过滤列表。
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 1.1.1.1
- 8.8.8.8
nameserver:
- https://1.1.1.1/dns-query
- https://dns.google/dns-query
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
- "+.stun.*.*"
- "+.stun.*.*.*"
示例展示字段关系,不代表所有网络环境都应使用相同解析服务。公司、校园或家庭网络可能依赖本地 DNS 解析内部域名,此时应保留局域网解析路径,或为内部域名设置专门的 nameserver-policy。fake-ip-range 应使用约定的保留地址段,不要与家庭局域网、VPN 或容器网络正在使用的网段重叠。若出现局域网设备打不开、打印机发现异常或游戏登录失败,可先查看该域名是否应进入 fake-ip-filter,而不是直接关闭整个 DNS 模块。
按域名选择解析器
nameserver-policy 可以让特定域名使用指定解析器。例如内部域名交给路由器,本地域名交给局域网 DNS,其余域名走主要 nameserver。它解决的是“由谁解析”,规则中的 DOMAIN-SUFFIX 则解决“连接从哪里出去”,两者属于不同阶段。解析器选择正确,不代表后续连接一定走对应策略;反过来,代理规则正确,也不能修复一个已经返回错误地址的 DNS 结果。
dns:
enable: true
enhanced-mode: fake-ip
default-nameserver:
- 1.1.1.1
nameserver:
- https://1.1.1.1/dns-query
nameserver-policy:
"+.home.arpa":
- 192.168.1.1
"+.internal.example":
- 192.168.1.1
排查 DNS 时可以分三层观察:先确认系统或应用把查询送到哪里,再看 Clash 日志中是否出现域名与规则匹配,最后检查目标连接走了哪个策略。若浏览器启用了独立的安全 DNS,它可能绕过系统设置;若规则只写 IP-CIDR,而连接日志中保留的是域名,则命中顺序也可能与预期不同。不要同时改动 DNS 模式、规则和节点,逐项改变更容易找到真正原因。
IPv6 与解析结果
dns.ipv6 控制 DNS 模块是否返回 AAAA 结果,顶层 ipv6 则影响内核对 IPv6 的整体处理。设备网络支持 IPv6、解析器返回 IPv6 地址、代理节点也具备对应能力时,连接才可能顺利完成。若本地只有不稳定的 IPv6 路径,应用可能优先尝试 AAAA 地址并等待超时,看起来像代理速度变慢。可以在确认网络条件后决定是否启用,而不是把开关当作固定答案。
四、代理节点字段与协议参数
proxies 是静态节点列表,每一项至少包含名称、协议类型、服务器地址和端口,其他字段由协议决定。订阅通常已经生成完整节点,手工维护时不要凭名称猜协议参数。相同的服务器可能开放多个协议入口,它们的认证方式、传输层和 TLS 设置并不互通。内核校验通过只说明字段形态可接受,并不代表远端服务一定可达。
name 是配置内部的引用键,也是客户端代理页显示的文本。策略组引用节点时必须使用该名称。名称重复会造成选择和覆写困难,应在导入阶段保持唯一。server 可以是域名或 IP;使用域名时会涉及 DNS 解析。port 必须是整数。诸如 udp、skip-cert-verify、servername 等字段只在协议和传输条件需要时使用,不应把某个节点的参数整段复制到不同协议。
SOCKS 与 HTTP 上游代理
SOCKS5 和 HTTP 节点常用于连接已有的上游代理。它们的字段相对简单,可以作为理解节点结构的起点。若上游要求认证,填写用户名与密码;不要求时省略。是否支持 UDP 取决于协议、内核和上游服务三方能力。文档示例中的地址仅用于说明格式。
proxies:
- name: "office-socks"
type: socks5
server: 192.0.2.20
port: 1080
username: "example-user"
password: "your-password"
udp: false
- name: "upstream-http"
type: http
server: 192.0.2.30
port: 8080
username: "example-user"
password: "your-password"
tls: false
密码等敏感字段不适合放进公开仓库或截图。配置需要在多台设备间同步时,应使用受控的私有渠道,并确认客户端日志不会输出完整认证信息。节点连不上时,先验证服务器和端口的网络可达性,再检查认证和传输参数;如果一开始就修改策略组或规则,会把节点问题和路由问题混在一起。
TLS、SNI 与证书验证
使用 TLS 的协议通常需要正确的服务器名称。servername 或同类 SNI 字段告诉远端在握手中使用哪个主机名,它可能与 server 不同。通过 IP 连接但证书签发给域名时,缺少正确 SNI 会导致握手失败。skip-cert-verify 会跳过证书验证,不应作为处理所有 TLS 错误的通用开关;更合适的做法是核对系统时间、服务器名称、证书链和中间网络。订阅提供者明确给出该字段时,再结合实际环境判断。
WebSocket、gRPC 等传输层还会包含路径、主机头或服务名。YAML 层级必须放在协议要求的位置,例如 ws-opts 下的 path 与 headers。字段放错层级时,有些解析器会忽略未知键,结果是配置能加载但握手参数缺失。遇到这种情况,应对照内核日志和协议字段说明,不要只看客户端是否出现该节点名称。
proxies:
- name: "example-tls-node"
type: trojan
server: edge.example.net
port: 443
password: "your-password"
sni: edge.example.net
udp: true
skip-cert-verify: false
network: ws
ws-opts:
path: /gateway
headers:
Host: edge.example.net
节点提供器与静态节点的区别
静态 proxies 把节点直接写进主配置,便于单文件阅读;proxy-providers 则从本地文件或远程资源装载节点集合,适合订阅更新和多来源组合。策略组引用 provider 时使用 use,引用静态节点时使用 proxies。两者可以同时存在,但要留意重名节点、更新间隔和缓存文件路径。客户端自带的订阅管理通常已经处理这些细节,普通用户不必为了“看起来简洁”而主动改成 provider。
在 Windows、macOS、Android、iOS 和 Linux 图形客户端中,节点参数通常由订阅维护。首推的 Clash Plus 以及 Clash Verge Rev、FlClash、Clash Nyanpasu、Clash Meta for Android、ClashX Meta 等客户端,对配置展示方式可能不同,但底层引用关系相近。需要比较平台与客户端定位,可前往横向评测,不要根据界面名称推断某个协议字段一定被支持。
五、策略组类型与组合设计
策略组位于规则和节点之间。规则不必直接写某个节点名称,而是把流量交给“手动选择”“自动选择”或“应用分流”等策略组,再由组决定实际出站。这样更新节点列表时不必重写规则,也能在客户端界面中快速切换。设计策略组的关键不是数量,而是让每一层职责清楚:顶层负责用户选择,中间层负责自动测试或故障切换,底层才是节点与 DIRECT。
select 是最直观的类型,按用户选择使用某个节点或子策略组。它不会自动挑选速度更快的节点。url-test 会按设定地址定期测试候选节点,并选择测试结果较合适者;测试只反映到指定目标的连接表现,不等同于所有网站的实际体验。fallback 侧重可用性,在当前候选不可用时切到下一项。load-balance 会按策略把连接分配给多个节点,可能影响登录会话、出口地址一致性和风控判断,不适合作为默认组随意启用。
| 组类型 | 选择方式 | 适合场景 | 主要边界 |
|---|---|---|---|
select | 用户手动选择 | 总入口、地区选择、临时切换 | 不会自动判断节点质量 |
url-test | 周期测试后选择 | 同类节点的自动选择 | 测试目标与实际业务可能不同 |
fallback | 不可用时顺序切换 | 强调连接连续性的场景 | 切换后出口可能变化 |
load-balance | 多节点分配连接 | 明确理解会话影响的高级场景 | 不保证单一出口地址 |
两层策略组的常见结构
一个实用结构是顶层“代理选择”使用 select,组内放“自动选择”、若干地区组和 DIRECT;“自动选择”再使用 url-test 引用具体节点。规则统一指向顶层组,用户需要稳定手动控制时直接选节点,需要省心时选自动组。不要让两个策略组互相引用,否则会形成循环。也不要把每条规则都指向不同节点,这会让订阅更新后的维护成本迅速上升。
proxy-groups:
- name: "代理选择"
type: select
proxies:
- 自动选择
- 手动节点
- DIRECT
- name: "自动选择"
type: url-test
proxies:
- node-a
- node-b
url: "https://www.gstatic.com/generate_204"
interval: 300
tolerance: 50
- name: "手动节点"
type: select
proxies:
- node-a
- node-b
interval 表示测试间隔,过短会增加请求和设备耗电,过长则无法及时反映网络变化。tolerance 用于减少结果接近时的频繁切换。测试地址应稳定、响应体小,并能代表希望验证的连接路径。客户端界面展示的测试结果只是一项参考,节点拥塞、目标站点线路和无线网络变化都会影响实际访问。
使用 filter 管理 provider 节点
当节点来自 proxy-providers 时,可以通过 use 引用整个 provider,并用 filter 按名称筛选。过滤通常使用正则表达式,名称中地区写法不统一时,表达式需要兼容简称、英文和符号。过滤结果为空会让策略组失去候选项,因此修改后必须校验。比起写一个过于宽泛的表达式,更适合先观察实际节点名称,再逐步增加匹配分支。
proxy-groups:
- name: "地区选择"
type: select
use:
- primary-subscription
filter: "(?i)Hong Kong|HK|香港"
- name: "可用性优先"
type: fallback
use:
- primary-subscription
url: "https://www.gstatic.com/generate_204"
interval: 600
策略组名称本身也是规则目标,因此改名属于结构性变更。把“代理”改成“代理选择”后,应同步搜索 rules、rule-providers 的行为目标以及其他策略组中的引用。客户端可能记住上次选择;当旧节点消失或组内容变化时,运行态选择可能回落到第一项。配置发布给多台设备时,第一项应是可解释、可用的默认策略,而不是偶然排在最前的单个节点。
DIRECT 与 REJECT 的位置
DIRECT 表示直接连接,适合局域网、受信任的本地服务或明确希望走本地出口的目标。REJECT 表示拒绝连接,可用于阻止已确认的域名或地址。它们既可以直接作为规则目标,也能放入 select 组供用户临时选择。将 DIRECT 放进总策略组会提高灵活性,但也意味着用户可能让原本应代理的规则临时直连;是否保留取决于使用场景。
六、规则语法、匹配顺序与自定义规则
rules 是有顺序的列表。连接到来后,内核通常从第一条开始判断,首个匹配结果立即生效,后面的规则不再检查。因此“规则内容正确但没有效果”经常不是语法错误,而是前面已有更宽泛的规则先命中。精确域名、特定进程或局域网地址通常放在前面,范围较大的域名后缀、IP 段和地区规则放在后面,最终用 MATCH 处理剩余流量。
一条基础规则由规则类型、匹配内容和目标策略组成,以英文逗号分隔。例如 DOMAIN,api.example.com,代理选择 只匹配完整域名;DOMAIN-SUFFIX,example.com,代理选择 可覆盖根域名及其子域名;DOMAIN-KEYWORD,example,代理选择 范围更宽,任何包含关键字的域名都可能命中,应谨慎使用。规则目标可以是策略组、节点、DIRECT 或 REJECT。
域名、IP 与进程规则
DOMAIN 类规则在内核掌握域名时最清晰。IP-CIDR 用于 IPv4 网段,IP-CIDR6 用于 IPv6 网段,网段使用 CIDR 前缀表示。IP 规则可能触发域名解析;如果只希望使用已有目标 IP 而不额外解析,可按内核支持方式增加 no-resolve。GEOIP 根据 IP 所属地区匹配,结果依赖对应数据库。PROCESS-NAME 和 PROCESS-PATH 依赖操作系统提供进程信息,在不同平台、权限和 TUN 实现下表现可能不同,不适合作为唯一的跨平台规则方案。
rules:
- DOMAIN,api.example.com,代理选择
- DOMAIN-SUFFIX,example.org,代理选择
- DOMAIN-KEYWORD,streaming,媒体服务
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- PROCESS-NAME,example-app.exe,代理选择
- GEOIP,CN,DIRECT
- MATCH,漏网之鱼
上例只是展示顺序与格式。局域网网段应结合实际网络调整;进程名也应以系统任务信息为准。MATCH 应位于末尾,它会匹配此前没有处理的连接。如果 MATCH 放在中间,后面的规则永远没有机会执行。配置中出现多个 MATCH 没有实际意义,应保留一个明确的最终出口。
自定义规则如何插入
订阅配置更新时,直接追加到原文件的规则通常会被覆盖。更稳妥的方法是使用客户端的覆写、扩展脚本或规则前置功能,把自定义规则插入订阅规则之前。前置适合精确例外,例如让某个内部域名始终直连;后置只适合在订阅末尾 MATCH 之前仍有机会执行的规则。如果订阅已经以 MATCH 收尾,把新规则简单追加到文件末端不会生效。
设计自定义规则时先回答三个问题:匹配对象是域名还是 IP;目标是已有策略组还是新组;它应覆盖哪些现有规则。若只处理一个主机,优先用 DOMAIN;处理一个站点的所有子域名,用 DOMAIN-SUFFIX;只有名称结构不稳定时再考虑 DOMAIN-KEYWORD。过宽的关键字可能误伤无关域名,尤其是短词、品牌缩写或常见单词。
rules:
- DOMAIN,printer.home.arpa,DIRECT
- DOMAIN-SUFFIX,internal.example,DIRECT
- DOMAIN-SUFFIX,docs.example.net,代理选择
- RULE-SET,private-network,DIRECT
- RULE-SET,service-list,代理选择
- MATCH,代理选择
规则命中日志的阅读方式
日志通常能显示目标域名或 IP、命中的规则类型、选中的策略组以及最终节点。排查时先发起一次可重复的访问,再按时间定位对应连接。看到规则目标正确但最终节点不符,应检查策略组当前选择;看到 MATCH 命中,则向前检查预期规则是否加载、域名是否一致、规则集是否更新成功;看到 IP 规则而没有域名信息,则检查 DNS 与嗅探路径。
浏览器一次打开页面会产生多个连接,包括主站、图片、脚本和第三方接口,不能只看第一条日志就判断整页路由。更适合选择一个明确域名进行测试,或在开发者工具中确认失败请求的主机名。应用也可能缓存 DNS 或保持已有连接,修改规则后应新建连接,必要时重启应用,而不是假设所有旧会话会立即切换策略。
规则的可维护性
规则应按用途分段并写简短注释,例如局域网、个人例外、业务分流、公共规则集和最终匹配。注释说明“为什么存在”比重复字段含义更有价值。长期不用的例外应及时删除,否则未来很难判断它是否仍然必要。规则目标尽量引用稳定的策略组名,不直接绑定频繁变化的节点名称。这样订阅新增或删除节点时,路由层无需同步调整。
七、规则集、节点提供器与外部资源
当规则数量较多时,把所有内容塞进 rules 会使主配置难以维护。rule-providers 允许从本地文件或远程地址加载规则集合,主规则只需用 RULE-SET 引用。它解决的是规则内容的组织和更新问题,不会自动决定策略目标;同一个规则集可以在主配置中指向不同策略组。与之相似,proxy-providers 管理节点来源,策略组通过 use 引用。
规则提供器常见行为包括 domain、ipcidr 和 classical。domain 适合纯域名规则,ipcidr 适合地址段,classical 可以容纳较完整的规则表达。behavior 必须与文件内容匹配;把 DOMAIN-SUFFIX 形式的经典规则当成纯 domain 数据读取,可能导致解析失败或内容无法命中。format 则描述文件格式,例如 yaml、text 或 mrs,实际支持范围应以所用内核为准。
远程规则集的完整定义
rule-providers:
private-network:
type: http
behavior: ipcidr
format: yaml
path: ./ruleset/private-network.yaml
url: "https://rules.example.net/private-network.yaml"
interval: 86400
service-list:
type: http
behavior: classical
format: yaml
path: ./ruleset/service-list.yaml
url: "https://rules.example.net/service-list.yaml"
interval: 86400
rules:
- RULE-SET,private-network,DIRECT
- RULE-SET,service-list,代理选择
- MATCH,代理选择
type: http 表示从远程获取,path 是本地缓存位置,interval 是更新间隔。首次加载需要网络访问;远程更新失败时,内核通常会尝试继续使用已有缓存,但首次下载失败且没有缓存就无法得到规则内容。路径所在目录需要可写权限,桌面客户端还可能把相对路径解释为其配置工作目录,而不是用户当前打开终端的位置。
远程地址应来自可信、持续维护的来源。规则更新会改变流量路径,影响范围可能比单个节点更大。使用第三方规则集前,应了解其分类逻辑、更新频率和默认目标,不要仅凭名称判断内容。对于公司内部域名或个人例外,保留少量本地前置规则通常比等待公共列表收录更合适。
规则集文件的内容格式
YAML payload 格式通常以 payload 为顶层键,下面是规则条目。classical 行为的条目可包含 DOMAIN、DOMAIN-SUFFIX 或 IP-CIDR 等前缀;domain 行为通常只保存域名模式;ipcidr 行为则保存网段。不同格式不能随意混用,扩展名也不能替代 format 声明。
payload:
- DOMAIN,api.example.com
- DOMAIN-SUFFIX,example.org
- IP-CIDR,203.0.113.0/24,no-resolve
在主配置中使用 RULE-SET 时,策略目标写在引用处,因此规则集内部通常不再写“代理选择”这类目标。这样同一份列表可以被不同配置复用。若下载到的文件本身已经包含完整三段式规则,就应确认 provider 的 behavior 和内核解析方式是否与之匹配。看到“规则条目参数数量不正确”时,重点检查内容格式,而不是修改主规则的策略组。
节点提供器、健康检查与缓存
proxy-providers:
primary-subscription:
type: http
url: "https://subscription.example.net/profile.yaml"
path: ./providers/primary.yaml
interval: 21600
health-check:
enable: true
url: "https://www.gstatic.com/generate_204"
interval: 600
proxy-groups:
- name: "订阅节点"
type: select
use:
- primary-subscription
proxies:
- DIRECT
provider 返回的内容应符合节点提供器所需结构,而不一定是一份完整 Clash 配置。把完整配置地址直接当节点 provider 使用,可能因顶层结构不同而失败。图形客户端中的“订阅”通常是完整配置订阅,和 proxy-providers 概念不能简单等同。若客户端已经负责更新完整配置,应优先沿用客户端流程,而不是额外嵌套一层 provider。
健康检查会对 provider 中的节点发起测试,便于自动组判断可用性,但频率过高会增加资源占用。移动设备还要考虑电量和后台限制。测试失败不一定表示节点对所有目标都不可用,可能只是测试地址被阻断或当前网络无法访问。判断时应结合实际连接日志,避免仅根据一个测试标记删除节点。
更新失败的分层排查
外部资源失败可分为下载、写入、解析和引用四层。下载层检查 URL、DNS 与当前出站;写入层检查缓存目录权限;解析层核对 format、behavior 与文件内容;引用层确认 RULE-SET 或 use 名称与顶层定义一致。远程规则更新可能也经过当前代理,错误的分流会形成“需要规则才能下载规则”的依赖。可为配置资源域名设置明确路径,或确保首次启动时有可用的基础连接。
八、覆写、合并、校验与故障排查
订阅配置需要定期更新,而个人设置希望长期保留,这正是覆写与合并存在的原因。直接编辑订阅生成的 YAML 最直观,但更新后容易被替换;把自定义内容放在独立覆写层,可以让“上游节点与公共规则”和“本地端口、DNS、个人规则”各自维护。不同客户端对覆写的称呼和能力并不完全相同,可能提供字段覆盖、规则前置、规则后置、脚本处理或 YAML 合并。使用前应先确认它是替换整个字段,还是递归合并映射。
映射适合按键递归合并,列表则最容易产生歧义。对于 dns 这类映射,覆写一个子键可能保留其他子键;对于 rules、proxies 和 proxy-groups 这类列表,有的工具会整体替换,有的支持前置或追加。如果误以为列表会自动拼接,可能导致订阅原规则全部消失;误以为会替换,又可能留下两个同名策略组。不要在不了解客户端语义时一次覆写大量列表。
安全的覆写边界
通用端口、日志级别、局域网开关和少量 DNS 子项通常适合字段覆写。个人域名例外适合规则前置。需要新增策略组时,应同时处理组定义、引用节点来源和规则目标,最好作为一个完整变更验证。节点认证参数通常交给订阅维护,除非明确是在管理自己的静态节点。覆写文件应比主配置更短,只表达与上游不同的部分。
# 本地覆写示意,具体合并语法以客户端为准
mixed-port: 7890
log-level: info
allow-lan: false
dns:
enable: true
ipv6: false
prepend-rules:
- DOMAIN,printer.home.arpa,DIRECT
- DOMAIN-SUFFIX,internal.example,DIRECT
prepend-rules 并不是标准主配置顶层字段,而是部分覆写工具可能采用的表达方式,不能直接复制进所有客户端。真正操作时,应使用客户端明确提供的“规则前置”入口。本例重点是区分主配置字段与覆写指令:前者由内核读取,后者由客户端或转换工具先处理,处理后的最终 YAML 才交给内核。
合并后的检查清单
每次修改后先查看最终生成配置,而不是只看覆写片段。确认顶层没有重复键,监听端口未冲突,DNS 层级完整,节点和策略组名称唯一,所有引用目标存在,策略组没有循环,规则末尾只有一个明确的 MATCH。若使用 providers,还要检查缓存路径、行为类型和引用名称。配置校验通过后,再启动或热重载。
缩进、冒号、引号、列表和字段类型均可解析,没有重复顶层键。
规则目标、策略组成员、provider 名称逐字对应,不存在循环引用。
端口可监听,控制接口范围明确,缓存目录可写,DNS 能完成基础解析。
通过日志确认规则命中、策略选择和最终节点符合预期。
使用内核进行配置校验
直接运行 mihomo 的用户可以使用内核提供的配置测试参数,在启动服务前检查文件。不同安装方式下可执行文件名和配置目录不同,应以实际路径替换示例。图形客户端通常也会在导入或切换配置时执行校验,并在日志页显示错误行。客户端提示信息被截断时,可以打开日志页查找完整原因。
# 在当前目录检查 config.yaml
mihomo -t -f ./config.yaml
# 指定配置工作目录后检查
mihomo -t -d ./clash-profile -f ./clash-profile/config.yaml
校验成功只说明配置结构和已知字段满足要求,不代表远程节点、规则集或 DNS 服务一定可用。启动后还需要观察 provider 更新、端口监听和连接日志。若校验提示某行错误,实际原因可能位于上一行,例如引号未闭合或父级缩进不正确。先查看报错行上下各数行,再逐步缩小范围。
典型故障的处理顺序
“客户端打不开”应先排查权限、端口占用、配置语法和内核文件,可参考启动崩溃与闪退处理步骤。“客户端能启动但所有连接失败”应检查系统代理或 TUN 是否真正启用、端口是否一致、节点是否可用。“部分网站路径不对”则重点看 DNS、规则顺序和策略组当前选择。“订阅更新后自定义内容消失”说明修改落在上游文件中,应迁移到覆写层。
端口占用时不要连续尝试多个随机端口而忘记同步系统代理。先确定占用进程,关闭重复内核,或选择一个明确的新端口并同步所有入口设置。规则不命中时不要立刻增加更宽泛的 DOMAIN-KEYWORD,先从日志取得真实域名。DNS 异常时不要同时更换 nameserver、关闭 fake-ip 和重写规则;一次只改变一个变量,保留能够回退的配置副本。
“热重载成功但行为未变化”可能来自旧连接、应用缓存、客户端运行态选择或覆写未重新执行。新建连接并检查最终配置文件的修改时间与内容,确认内核实际读取的是目标文件。多配置客户端常有当前配置、订阅缓存和运行时生成配置三层,编辑错文件是常见原因。通过客户端配置页确认当前激活项,再从日志查看加载路径,比在磁盘中逐个猜测更可靠。
建立可回退的维护流程
稳定的维护流程应包含四步:保存一份已知可用配置;对单一目标做小幅修改;先校验再加载;通过日志验证实际行为。若修改失败,回退到上一份可用配置,而不是在错误配置上继续叠加补丁。个人规则、DNS 例外和策略组结构可以分别维护说明,记录修改原因和依赖关系,后续清理会更容易。
订阅更新前后可比较顶层字段、策略组名称和规则末尾结构,不必逐行比较所有节点。上游新增节点通常不影响个人规则,但策略组改名、provider 名称变化或规则目标调整会影响覆写。定期删除失效例外与不用的 provider,可以降低未来更新冲突。配置的目标不是字段最多,而是每个字段都有明确作用、每条引用都能追踪、出现问题时能够快速回退。