YAML 结构总览与载入顺序
顶层区块如何协作
一份可以运行的 Clash 或 mihomo 配置通常由通用设置、DNS、代理节点、策略组和规则五部分组成。它们不是彼此孤立的列表,而是一条有引用关系的链路:proxies 定义可建立连接的节点,proxy-groups 把节点或其他策略组组织成可选择的出口,rules 再把不同连接送往某个策略组、DIRECT 或 REJECT。DNS 部分负责把域名解析过程纳入这条链路,通用字段则决定监听端口、运行模式、局域网访问范围和控制接口。
字段位置由缩进决定。顶层键必须从行首开始,子字段通常缩进两个空格,列表项以短横线开头。YAML 不使用制表符表示层级,也不允许同一层级忽而两个空格、忽而四个空格。配置能被文本编辑器正常显示,不代表解析器一定接受;中文标点、全角冒号、不可见制表符和错误缩进都是常见的载入失败原因。字符串里包含冒号、井号、花括号或前后空格时,使用单引号或双引号包裹更稳妥。
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- 1.1.1.1
- 8.8.8.8
proxies:
- name: "示例节点"
type: ss
server: 192.0.2.10
port: 443
cipher: aes-128-gcm
password: "your-password"
proxy-groups:
- name: "节点选择"
type: select
proxies:
- "示例节点"
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,节点选择
- MATCH,DIRECT
映射、列表与标量
阅读配置时可以先区分三种基本数据。映射是键和值的组合,例如 mode: rule;列表是一组以短横线开始的条目,例如 nameserver 下的地址;标量是字符串、数字或布尔值。true 与 false 不需要引号,端口通常写成数字,节点名称则属于字符串。若把布尔值写成带引号的 "false",部分实现会把它当作普通文本,结果可能与预期不同。
YAML 还支持行内数组,例如 proxies: [节点 A, 节点 B, DIRECT]。这种写法适合很短的列表,但在节点较多、名称包含标点或需要频繁维护时,可读性明显下降。系统化配置更适合使用逐行列表。锚点、引用和复杂类型虽然属于 YAML 标准能力,却不一定被所有客户端覆写系统完整保留;面向跨客户端使用时,优先采用普通映射与列表。
从解析到生效的检查顺序
配置载入可分成三层检查。第一层是 YAML 语法,主要看缩进、冒号和列表格式;第二层是字段结构,例如节点是否缺少 server、策略组是否引用了不存在的名称;第三层才是运行时问题,例如远端服务器不可达、DNS 上游超时或系统代理未接管流量。不要在看到“无法连接”后立即改规则。先确认客户端日志里是否出现配置解析错误,再确认目标策略组能够选中节点,最后检查连接和 DNS,排错效率会高得多。
通用字段、监听端口与运行模式
端口字段的职责
port 表示 HTTP 代理端口,socks-port 表示 SOCKS5 代理端口,mixed-port 则在一个端口上同时接受 HTTP 与 SOCKS5 请求。桌面图形客户端通常只需要设置 mixed-port,再由客户端自动写入系统代理。只有某些应用必须分别指定代理类型时,才需要拆成两个端口。多个字段可以同时存在,但端口号不能与系统中其他程序或另一个 Clash 实例冲突。
端口占用的典型表现是内核启动后立即退出,日志中出现 bind、listen 或 address already in use。此时应先关闭残留进程,或者把配置端口改为未被占用的值,再同步修改浏览器、开发工具或系统代理中的端口。只改 YAML 而没有更新手动配置的应用,会造成内核正常运行但应用无法连接。若客户端提供端口设置界面,优先在界面中修改,因为某些客户端会通过覆写层覆盖订阅里的原始端口。
| 字段 | 用途 | 常见使用方式 |
|---|---|---|
mixed-port |
同时接受 HTTP 与 SOCKS5 | 桌面客户端和本机应用的通用入口 |
port |
仅 HTTP 代理 | 明确只支持 HTTP 代理的程序 |
socks-port |
仅 SOCKS5 代理 | 命令行工具、开发环境或特定应用 |
redir-port |
透明代理重定向入口 | 主要用于 Linux 网络规则配合 |
tproxy-port |
TPROXY 透明代理入口 | 需要保留目标信息的 Linux 场景 |
局域网监听与控制接口
allow-lan 控制其他设备能否连接当前设备上的代理端口。设为 false 时适合仅供本机使用;设为 true 后,还要结合 bind-address 和系统防火墙判断实际可访问范围。开放到局域网意味着同一网络中的设备可能尝试连接,因此不要把控制接口和代理端口无条件暴露到不可信网络。需要给手机或测试设备临时提供代理时,应确认当前网络性质,并在使用结束后恢复限制。
external-controller 是客户端界面与内核通信的控制地址,常见形式为 127.0.0.1:9090。本机界面使用时绑定回环地址即可。secret 用于控制接口鉴权,设置后面板请求必须携带对应值。它不是代理节点密码,也不会改变代理协议。若图形客户端自动管理控制接口,不建议在订阅原文里反复修改,否则可能导致界面无法读取内核状态。
mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false
external-controller: "127.0.0.1:9090"
secret: "your-controller-secret"
Rule、Global 与 Direct
mode: rule 按 rules 从上到下匹配,是日常使用最常见的模式。global 跳过规则判断,把流量统一交给全局策略组;它适合短时间验证某个节点是否可用,却不适合作为规则配置是否正确的结论。direct 则让连接直接访问,不经过代理节点,可用于判断问题是否来自代理链路。很多客户端会在界面中切换模式,并以运行时设置覆盖文件中的 mode,因此排查时要同时查看界面状态和实际配置。
log-level 通常可在 silent、error、warning、info、debug 之间选择。日常保持 info 较合适;定位规则命中、DNS 查询或连接握手问题时,可临时改为 debug。调试日志信息量较大,问题确认后应恢复常规级别。ipv6 决定内核是否处理 IPv6 相关能力,但最终效果还受系统网络、DNS 返回和节点支持情况影响。网络本身没有稳定 IPv6 时,关闭该字段可以减少错误路径;具备完整 IPv6 环境时再按实际需求启用。
DNS、Fake-IP 与解析路径
DNS 区块解决什么问题
代理规则经常依赖域名,但应用建立连接时可能只交给系统一个 IP 地址。如果域名解析完全发生在内核之外,规则引擎就可能失去原始域名,只能按 IP 规则处理。dns.enable 启用内核 DNS 模块后,域名查询可以与规则、代理出口和缓存协同工作。它不是简单地把系统 DNS 换成另一个地址,而是让解析过程成为流量处理链的一部分。
nameserver 是主要上游解析器,default-nameserver 主要用于解析加密 DNS 服务器自身的域名,通常应填写可直接访问的 IP 地址,避免形成“先解析解析器域名”的循环依赖。fallback 可提供另一组解析来源,配合过滤条件决定何时采用备用结果。较新的 mihomo 配置还支持 proxy-server-nameserver,专门解析代理服务器域名,避免节点服务器地址的解析路径与普通网站查询相互干扰。
dns:
enable: true
listen: "127.0.0.1:1053"
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: "198.18.0.1/16"
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
- "+.stun.*.*"
default-nameserver:
- 1.1.1.1
- 8.8.8.8
nameserver:
- "https://1.1.1.1/dns-query"
- "https://8.8.8.8/dns-query"
proxy-server-nameserver:
- 1.1.1.1
Fake-IP 的工作过程
enhanced-mode: fake-ip 启用后,内核会向应用返回保留地址段中的映射地址,并记录这个地址对应的原始域名。当应用随后连接该地址时,内核能够还原域名并继续执行域名规则。这样即使应用只发起 IP 连接,DOMAIN、DOMAIN-SUFFIX 和 GeoSite 类规则仍有机会准确命中。默认保留范围通常位于 198.18.0.0/16,该地址用于基准测试网络,不应被当作公网目标访问。
Fake-IP 不表示网站真实解析到了保留地址,也不应拿保留地址直接测试公网连通性。它依赖流量仍经过当前内核;如果某个应用绕过系统代理和 TUN,拿到映射地址后却直接向网络发送连接,访问就会失败。因此,“解析结果看起来是 198.18 开头”本身不是故障证据,需要结合应用流量是否被接管判断。
fake-ip-filter 用于排除不适合映射的域名。局域网设备发现、打印机、游戏联机、STUN、时间同步和某些需要真实地址的服务可能要求返回真实解析结果。过滤规则不宜从网络上复制一份过大的列表后直接长期使用,因为过宽的排除范围会削弱域名还原能力。更稳妥的方法是从最小配置开始,遇到明确兼容问题后添加对应域名,并记录添加原因。
Redir-Host 与 DNS 泄漏排查
redir-host 会返回真实 IP,再尝试通过嗅探、映射或已有解析信息关联域名。它对少数不兼容 Fake-IP 的环境更直观,但域名规则的稳定性更依赖请求路径。两种模式没有脱离环境的绝对优劣。桌面端使用 TUN、需要完整域名规则时通常先尝试 Fake-IP;路由器、特殊局域网服务或明确出现映射兼容问题时,再评估 Redir-Host。
排查 DNS 应按请求路径逐层确认:系统请求是否进入内核监听端口,内核使用了哪个上游,上游连接走直连还是代理,返回结果是否被缓存,最终连接命中了哪条规则。仅更换 nameserver 往往不能解决所有问题。浏览器可能启用独立的安全 DNS,系统也可能缓存旧结果;修改配置后应重新载入内核,并在必要时清理系统和浏览器缓存。
如果检测结果显示 DNS 出口与预期不一致,先确认浏览器独立 DNS 设置,再检查 nameserver-policy、备用解析器和规则模式。详细操作可参考Clash DNS 泄漏检测与防泄漏配置实操。不要把“解析器所在地”和“连接出口”混为一谈:DNS 查询由哪个上游回答、网站连接由哪个节点发出,是两条相关但不完全相同的路径。
代理节点字段与协议差异
节点定义的公共骨架
proxies 下的每一项代表一个可用出口。所有节点至少需要唯一的 name、协议 type、服务器 server 和端口 port,其余字段随协议变化。节点名称不仅用于界面显示,还会被策略组按字符串引用,因此改名后必须同步更新所有 proxy-groups。名称区分大小写,前后多出的空格也可能导致引用失败。
server 可以是 IP 地址或域名。使用域名时,节点服务器本身的解析必须先成功,才能建立后续连接;这也是 proxy-server-nameserver 有价值的原因。端口写成数字,认证信息通常写成字符串。示例配置里的地址和凭据只用于说明结构,实际使用时应以订阅或服务提供方给出的参数为准,不要凭协议名称猜测加密方式、传输层或服务器名称。
Shadowsocks、Trojan 与 VLESS 示例
proxies:
- name: "SS 示例"
type: ss
server: 192.0.2.10
port: 443
cipher: aes-128-gcm
password: "your-password"
udp: true
- name: "Trojan TLS 示例"
type: trojan
server: 192.0.2.20
port: 443
password: "your-password"
sni: "edge.example.net"
skip-cert-verify: false
udp: true
- name: "VLESS WS 示例"
type: vless
server: 192.0.2.30
port: 443
uuid: "11111111-2222-3333-4444-555555555555"
network: ws
tls: true
servername: "edge.example.net"
ws-opts:
path: "/proxy"
headers:
Host: "edge.example.net"
Shadowsocks 的关键字段是 cipher 和 password,两者必须与服务器端一致。Trojan 通常运行在 TLS 上,sni 用于握手中的服务器名称。VLESS 的字段组合更多,常见差异包括 TLS、Reality、WebSocket、gRPC 与普通 TCP。配置里 network: ws 后,还要保证 ws-opts 的路径和 Host 与服务端对应。传输层写错时,服务器端口可能可以建立 TCP 连接,但协议握手仍会失败。
skip-cert-verify: true 会跳过证书校验,不应被当成通用修复按钮。证书错误可能来自设备时间不正确、服务器名称不匹配、证书链异常或中间网络干扰。先检查 sni、servername 和系统时间,再判断是否确有测试需要。生产使用中保持证书校验更容易暴露真实配置错误。
UDP、网络接口与链式代理
udp: true 表示节点允许内核尝试转发 UDP,但实际可用性还取决于协议、服务端和网络环境。启用字段不代表所有 UDP 应用都会自动工作;应用流量还必须被 TUN 或透明代理正确接管。游戏、语音和 QUIC 出现问题时,应先通过日志确认 UDP 会话是否进入内核,再检查节点能力。
interface-name 可以指定出站使用的系统网络接口,适合多网卡、拨号或路由器环境。普通桌面用户通常不需要设置,错误的接口名会让所有连接都走向不存在或不可达的网卡。routing-mark 主要服务于 Linux 策略路由,也不适合从其他配置中直接照抄。
mihomo 支持通过 dialer-proxy 等机制让一个节点经由另一个策略建立底层连接,可用于特定链式出口。链路越长,DNS、握手和故障定位越复杂。先确认每一段单独可用,再组合链路;不要在基础节点尚未通过测试时同时叠加链式代理、特殊传输和接口绑定。
节点来自订阅时如何修改
订阅更新通常会整体替换节点列表。直接编辑订阅生成的 proxies,下一次刷新后可能丢失改动。需要固定修改 SNI、跳过某个节点或调整 UDP 时,应优先使用客户端提供的覆写、脚本或节点转换功能。Clash Plus、Clash Verge Rev、FlClash 和 Clash Nyanpasu 对覆写入口的组织方式不同,但原则一致:保留原订阅作为数据源,把本地差异放在独立层。
策略组类型、引用关系与选择逻辑
Select、URL-Test、Fallback 与 Load-Balance
策略组是规则和节点之间的调度层。select 由用户手动选择节点或下级策略组,适合“节点选择”“流媒体”“下载”等需要明确控制的出口。url-test 会按照测试结果自动选择满足条件的节点,适合希望自动切换到可用连接的场景。fallback 按列表顺序选择第一个可用节点,强调优先级而非测试结果最小。load-balance 则按策略把不同连接分散到多个节点,适用于明确理解会话一致性影响的用户。
自动测试通常需要 url 和 interval。测试地址应稳定、响应轻量,并且能够反映目标网络路径。间隔过短会产生不必要的请求,过长又可能延迟发现节点变化。tolerance 用于减少测试值接近时频繁切换,不应把单次测试结果理解成实际下载速度。节点测速、网页首包、持续吞吐和晚高峰稳定性属于不同指标。
proxy-groups:
- name: "节点选择"
type: select
proxies:
- "自动选择"
- "故障转移"
- "SS 示例"
- "Trojan TLS 示例"
- DIRECT
- name: "自动选择"
type: url-test
url: "https://www.gstatic.com/generate_204"
interval: 600
tolerance: 80
proxies:
- "SS 示例"
- "Trojan TLS 示例"
- name: "故障转移"
type: fallback
url: "https://www.gstatic.com/generate_204"
interval: 600
proxies:
- "Trojan TLS 示例"
- "SS 示例"
策略组可以引用其他策略组
组内 proxies 不只可以写节点,也可以引用另一个策略组以及内置出口 DIRECT、REJECT。这种组合适合建立分层结构:底层组负责节点健康检查,中层组负责业务选择,顶层组作为规则目标。例如“流媒体”组可以包含“节点选择”和几个指定地区组,而地区组内部再使用自动测试。
引用关系必须避免循环。如果 A 组包含 B,B 又包含 A,内核无法得到最终出口。策略组名称也不能与节点名称混淆。维护大型配置时,可给组名采用一致前缀,但不必堆叠过多符号;清晰的业务名称比纯装饰字符更利于日志检索。规则目标必须与策略组名称完全一致,否则会在载入阶段报找不到策略。
使用 Provider 填充节点
当节点来自 proxy-providers 时,策略组可以通过 use 引用 Provider,而不必把每个节点名称写入 proxies。这样远端节点列表更新后,自动测试组会接收新节点。filter 和 exclude-filter 可按名称筛选,但筛选依赖正则表达式和订阅命名,供应方改名后结果可能为空。应给筛选组保留检查手段,不要假设地区关键词永远不变。
proxy-providers:
main-subscription:
type: http
url: "https://config.example.net/subscription.yaml"
path: "./providers/main.yaml"
interval: 3600
health-check:
enable: true
url: "https://www.gstatic.com/generate_204"
interval: 600
proxy-groups:
- name: "订阅节点"
type: select
use:
- main-subscription
- name: "自动测试"
type: url-test
use:
- main-subscription
url: "https://www.gstatic.com/generate_204"
interval: 600
怎样设计可维护的组层级
策略组不是越多越精细。每增加一层,用户需要理解的选择状态和排错分支都会增加。基础配置可以保持三层:一个总入口组、一个自动选择组、少量有明确需求的业务组。规则默认指向总入口,只有确实需要独立出口的服务才创建业务组。这样既保留手动控制,也能避免每次导入订阅后面对几十个含义相近的组。
排查“规则命中了却没有走预期节点”时,应从日志里的规则目标开始,逐层展开策略组:先看规则送到哪个组,再看该组当前选择了哪个子组,最后确认底层实际节点。只查看界面最上层组名容易漏掉下级自动选择。节点切换后已有连接也未必立即迁移,验证时应重新建立连接或关闭相关应用会话。
规则语法、匹配顺序与兜底策略
规则从上到下首次命中
rules 是有顺序的列表。内核从第一条开始检查,遇到首个匹配项后就停止继续查找,并把连接交给规则末尾指定的策略。规则顺序因此比规则数量更重要。精确域名、特殊业务和需要拒绝的条目通常放在前面,范围较大的域名后缀、IP 网段和地理规则放在后面,最后使用 MATCH 处理未命中的连接。
把 MATCH 放在中间会让其后的所有规则失去作用。把过宽的 DOMAIN-SUFFIX 放在精确例外之前,也会提前截获本应走其他策略的子域名。修改规则时,不只要看这一条是否正确,还要检查它前面是否已有更宽的匹配。日志中的规则类型和策略名称是判断实际命中位置的直接依据。
rules:
- DOMAIN,api.example.com,节点选择
- DOMAIN-SUFFIX,example.net,节点选择
- DOMAIN-KEYWORD,stream,流媒体
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- GEOIP,LAN,DIRECT
- GEOSITE,private,DIRECT
- GEOSITE,category-ads-all,REJECT
- MATCH,节点选择
域名规则的差异
DOMAIN 只匹配完整域名,例如 api.example.com,不会自动匹配其他子域。DOMAIN-SUFFIX,example.com 可匹配根域及其子域,适合整个站点使用相同策略。DOMAIN-KEYWORD 只要域名中出现对应片段就可能命中,范围较宽,短关键词容易误伤无关站点。能够使用完整域名或后缀时,不要优先使用关键词规则。
GEOSITE 引用分类数据库中的域名集合,适合维护规模较大的服务类别。它的匹配结果依赖本地 GeoSite 数据是否存在、规则集名称是否正确以及数据是否及时更新。数据库过旧时,新增域名可能无法命中;分类名称写错则会在配置载入或规则初始化时暴露。相关维护方法可参考GeoIP 与 GeoSite 数据库更新指南。
IP 规则与 no-resolve
IP-CIDR 匹配 IPv4 网段,IP-CIDR6 匹配 IPv6 网段。规则末尾的 no-resolve 表示当当前连接还没有目标 IP 时,不为了匹配这条规则额外发起 DNS 查询。它常用于局域网网段和已知 IP 集合,能够减少不必要解析,也能避免在域名规则之后再次触发查询。但如果某条 IP 规则必须依赖域名解析结果才能判断,就不应机械添加该参数。
GEOIP 根据目标 IP 所属地理数据库分类处理连接。它发生在 IP 层面,与 GEOSITE 的域名分类不同。一个域名可能使用全球分布式地址,解析结果也可能随网络位置改变,因此 GeoIP 不一定能表达某项服务的业务归属。需要按网站或服务分流时优先考虑域名集合;需要按实际目标网段处理时再使用 IP 规则。
DIRECT、REJECT 与 MATCH
DIRECT 让连接从本机网络直接发出,适合局域网、系统服务或明确需要本地出口的目标。REJECT 拒绝连接,常用于已确认的广告或追踪域名。拒绝范围过宽会造成页面资源缺失、登录失败或应用反复重试,因此需要结合日志逐条调整。MATCH 是最终兜底,它不判断域名或 IP 条件,任何此前未匹配的连接都会进入该策略。
一个易于理解的默认方案是:局域网和私有域名直连,明确拒绝项放行或拒绝按需求处理,特定服务进入业务组,其余流量交给总入口组。不要把大量来源不明的规则直接合并后期待一次生效。规则之间可能互相覆盖,不同列表也可能对同一域名给出相反策略。新增规则集后,应选择几个代表性域名查看日志,验证其命中顺序。
代理 Provider、规则集与外部文件
Provider 解决的维护问题
当节点和规则数量持续增长时,把所有内容塞进一个 YAML 会变得难以更新。proxy-providers 用于载入节点集合,rule-providers 用于载入规则集合。主配置只保留来源、缓存路径、更新间隔和引用关系,远端内容更新后不需要重写整个主文件。Provider 适合订阅和公共规则集,但它也引入了下载、缓存和格式三类依赖,排错时要区分主配置解析失败与远端文件更新失败。
type: http 表示从网络地址拉取,type: file 表示读取本地文件。path 是缓存或文件位置,通常使用相对于运行目录的路径。不同客户端的配置目录不同,不要把另一台设备上的绝对路径直接复制过来。interval 以秒为单位控制更新间隔;过短会频繁请求,过长则延迟接收变化。客户端手动更新订阅时,也可能触发 Provider 刷新。
rule-providers:
private-domain:
type: http
behavior: domain
format: yaml
path: "./rules/private-domain.yaml"
url: "https://rules.example.net/private-domain.yaml"
interval: 86400
private-network:
type: http
behavior: ipcidr
format: yaml
path: "./rules/private-network.yaml"
url: "https://rules.example.net/private-network.yaml"
interval: 86400
rules:
- RULE-SET,private-domain,DIRECT
- RULE-SET,private-network,DIRECT,no-resolve
- MATCH,节点选择
behavior 与文件内容必须对应
behavior: domain 表示规则集主要包含域名项目,内容可以是完整域名、后缀或相应域名规则形式;ipcidr 表示 IP 网段;classical 则允许在规则集中保留较完整的经典规则语法。行为类型与实际内容不一致时,规则可能无法解析或无法按预期匹配。选择类型应根据规则源提供的格式,而不是仅根据文件名判断。
常见 YAML 规则集会把条目放在 payload 下。domain 行为的简化条目可使用域名后缀形式,classical 行为则可写带类型的完整规则。主配置通过 RULE-SET 指定策略,因此 Provider 文件一般只描述匹配内容,不在每一行重复策略组。若规则源已经包含策略字段,应确认其格式是否确实要求 classical。
payload:
- "example.com"
- "+.example.net"
- "service.example.org"
更新、缓存和失败回退
远端规则更新失败时,内核通常会尝试继续使用已有缓存,但首次加载且本地没有缓存时,相关 Provider 可能不可用。日志中的 HTTP 状态、超时、文件权限和格式错误分别指向不同问题。可以先在浏览器或命令行确认地址能否访问,再检查客户端是否允许写入 path 指向的目录,最后验证下载内容确实是期望的 YAML 或 MRS 格式,而不是登录页或错误页面。
缓存文件不应由多个运行实例同时写入。同一设备启动两个客户端,且它们使用相同配置目录时,可能发生端口冲突,也可能争用 Provider 文件。迁移配置时,应连同需要的本地规则文件一起迁移,或者保证远端来源在新环境可访问。仅复制主 YAML 而遗漏本地 Provider,会出现主配置引用存在、实际文件缺失的情况。
规则集顺序仍由主配置决定
Provider 把许多条目包装成一个引用,但不会改变从上到下首次命中的原则。两个规则集范围重叠时,写在前面的 RULE-SET 先获得匹配机会。大型规则集不应无条件放在所有精确规则之前,否则会掩盖本地例外。需要覆盖公共规则集时,可把少量精确规则放在对应 RULE-SET 前面。
规则来源越多,冲突审查越重要。建议记录每个规则集的用途、behavior、更新来源和目标策略,删除长期未使用或功能重复的集合。出现服务分流异常时,临时禁用最近加入的 Provider,比在数万条远端规则中盲目搜索更高效。数据库和规则集更新后,也应重新验证几个关键域名,而不是只看下载状态显示成功。
覆写、合并、订阅更新与系统排错
为什么要把本地修改放在覆写层
订阅配置的生命周期通常是“远端生成、客户端下载、本地载入、定期刷新”。直接编辑下载后的原文件,下一次刷新时容易被替换。覆写层用于保存本地差异,例如固定端口、调整 DNS、增加少量规则、修改策略组默认选项。这样订阅负责提供节点和基础结构,本地层负责设备相关设置,两者职责更清楚。
不同客户端对覆写的称呼和能力并不完全相同,可能显示为覆写、扩展、合并、脚本或预处理。Clash Plus、Clash Verge Rev、FlClash、Clash Nyanpasu 等图形客户端通常都提供配置管理入口,但支持的合并语义需要以当前客户端界面和文档为准。简单键值覆盖较容易理解,数组合并则要特别谨慎,因为 rules、proxies 和 proxy-groups 都是有顺序或引用关系的列表。
映射覆盖与数组合并的差异
映射字段通常按键覆盖。例如基础配置中 log-level: info,覆写层设置为 debug 后,最终值只有一个。嵌套映射可能采用深度合并,也可能整块替换;如果覆写系统把整个 dns 块替换掉,只写 ipv6: false 就可能让原有 nameserver 消失。应用覆写后应查看客户端生成的最终配置,而不是只阅读覆写片段。
数组更复杂。追加规则必须考虑插入位置:需要优先命中的本地例外应放在公共规则集之前,普通兜底规则不能追加到 MATCH 之后。策略组数组若整体替换,原订阅中的组可能全部消失;若简单追加,又可能产生重名组。节点数组按名称去重还是按位置追加,也取决于实现。无法确认合并行为时,先用一份最小测试配置验证,再应用到主订阅。
# 基础配置
mode: rule
log-level: info
rules:
- GEOSITE,private,DIRECT
- MATCH,节点选择
# 本地目标
# 1. 保留原有私有域名规则
# 2. 在 MATCH 前加入精确例外
# 3. 仅把日志级别临时改为 debug
上面的本地目标不能仅靠“在文件末尾追加一条规则”实现,因为原有 MATCH 会提前兜底。正确做法是在客户端支持的规则前置区加入例外,或者生成一份合并后的完整规则数组。若客户端只能整块替换 rules,就需要把希望保留的原规则一并写入覆写结果。
一套可重复的排错流程
第一步检查配置是否成功解析。关注 YAML 行号、未知字段、重复名称和引用不存在等错误。第二步检查内核是否启动并监听预期端口;若启动后立刻退出,优先看端口占用、配置目录权限和控制接口冲突。第三步检查应用流量是否进入内核,通过日志确认能否看到目标域名或连接。看不到连接时,应检查系统代理、TUN 和应用自身代理,而不是修改节点。
第四步查看规则命中。日志应显示域名或 IP 命中了哪类规则、进入哪个策略组。若策略不对,检查规则顺序和 Provider 内容;若策略正确,再展开策略组确认底层实际节点。第五步检查 DNS。域名无法解析、Fake-IP 未被接管、浏览器使用独立 DNS,都可能表现为网页打不开。第六步检查节点连接阶段:超时通常表示路径不可达,拒绝连接常见于端口未监听,TLS 错误需要检查服务器名称和时间,认证错误则检查凭据。
每完成一步都应留下明确结论。例如“配置解析成功,7890 正在监听,浏览器连接已进入内核,命中节点选择组,但 TLS 握手失败”。这样的记录能把问题范围缩小到节点字段,而不是在所有配置块之间来回改动。启动闪退还可参考Clash 客户端启动闪退排查清单,界面入口不熟悉时可阅读代理、配置、日志三大页面讲解。
订阅更新后的回归检查
订阅刷新可能带来节点改名、策略组变化、规则目标变化和 Provider 地址更新。刷新后至少确认四项:原有本地覆写仍被启用;规则引用的策略组仍存在;自动选择组中仍有可用节点;DNS 与端口没有被订阅字段意外覆盖。若某个策略组突然为空,检查筛选正则是否仍匹配新的节点名称。
长期维护时,尽量减少对订阅内部结构的强依赖。比如规则统一指向一个稳定的本地总入口组,再由该组引用订阅节点,比让数十条规则直接写具体节点名更耐更新。节点变化由订阅处理,策略意图由本地配置表达,二者分离后迁移客户端也更容易。
最终配置的自检清单
- YAML 使用空格缩进,顶层键和列表层级清楚,没有制表符或全角标点。
- 监听端口未冲突,系统代理或 TUN 指向实际运行的内核。
- 每个策略组引用的节点、下级组和 Provider 都存在,组之间没有循环引用。
- 规则按精确到宽泛排列,所有兜底规则位于末尾,规则目标名称准确。
- DNS 上游可达,Fake-IP 过滤项保持必要范围,浏览器独立 DNS 已纳入检查。
- 覆写应用后的最终配置仍保留原订阅需要的字段,刷新订阅后完成一次回归验证。
完成字段核对后,可返回使用指南按导入、选择策略、连接和验证的主线操作;需要更换客户端时前往客户端下载页。常见现象与简短答案集中在常见问题,适合在已经确认错误阶段后快速查找对应处理方法。