01 / YAML STRUCTURE
YAML 结构总览
配置文件由哪些区域组成
Clash 配置文件是一个 YAML 映射。顶层键负责定义监听端口、运行模式、DNS 行为、代理节点、策略组、规则以及外部 Provider。内核读取文件时先解析 YAML 语法,再检查字段类型和引用关系,最后建立代理、策略组与规则之间的运行链路。语法正确只表示 YAML 可以被读取,不代表每个节点都能连接,也不代表策略组引用一定完整。因此排错时需要把“文本语法”“字段结构”“名称引用”“网络连通”分成四层检查。
常见顶层区域包括 mixed-port、allow-lan、mode、log-level、external-controller、dns、proxies、proxy-groups、rules、proxy-providers 与 rule-providers。并非每份配置都需要写齐这些字段。由客户端界面管理系统代理时,端口和控制器地址可能由客户端生成;由订阅提供商生成配置时,节点及策略组通常随订阅更新。手工配置的重点是明确哪些字段属于基础运行参数,哪些字段会在订阅刷新时被替换。
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
external-controller: 127.0.0.1:9090
dns:
enable: true
ipv6: false
enhanced-mode: fake-ip
nameserver:
- https://1.1.1.1/dns-query
proxies:
- name: Example-Trojan
type: trojan
server: proxy.example.com
port: 443
password: "your-password"
sni: proxy.example.com
proxy-groups:
- name: 节点选择
type: select
proxies:
- Example-Trojan
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,节点选择
- MATCH,节点选择
上例展示了最小的关系闭环:规则把请求交给“节点选择”,策略组再把请求交给具体节点或 DIRECT。规则最后的目标名称必须与策略组名称完全一致,策略组中的节点名称也必须与 proxies 项一致。名称比较通常区分字符、空格与全角半角差异。“节点选择”和“节点选择 ”看起来接近,实际上是两个名称。修改名称时需要同步修改所有引用位置。
缩进、序列与标量
YAML 使用缩进表达层级。建议统一使用两个空格,不使用制表符。以短横线开头的项目属于序列,例如 proxies 下的每个节点、rules 下的每条规则。冒号后必须保留空格,字符串中本身含有冒号、井号、方括号或前后空格时,使用引号可以减少歧义。密码、UUID、域名和节点名称适合按字符串处理;端口、间隔和并发数量通常使用数字;开关使用 true 或 false。
井号在未被引号包围时表示注释起点。例如 password: abc#123 可能只把 abc 作为值,正确写法是 password: "abc#123"。布尔值也应使用明确的 true 与 false,避免使用容易被不同 YAML 解析器解释为布尔值的单词。节点名称包含逗号时不会直接破坏节点对象,但把该名称写进逗号分隔的规则或部分简写字段时可能引起解析歧义,因此节点与策略组名称宜保持简短、唯一且不含控制字符。
解析顺序与引用检查
配置文件的书写顺序主要服务于阅读,顶层区域不必严格按固定顺序排列,但规则列表内部的顺序具有执行意义。节点可以写在策略组之前,策略组也可以写在规则之前;内核完成整份配置解析后再建立引用。出现“找不到代理”或“策略组不存在”时,先复制报错中的名称,与定义处逐字符核对,再检查该名称是否由 Provider 动态提供。Provider 尚未成功加载时,依赖它的策略组可能暂时为空。
配置测试应从完整文件开始,而不是只验证某个 YAML 片段。片段能够通过语法检查,不代表放回原文件后层级仍然正确。客户端提示配置无效时,先保留原文件副本,再把最近新增的区域按块移除,以二分方式定位错误。若问题发生在订阅更新之后,可参考订阅链接与配置导入说明,确认导入的是订阅地址、完整 YAML,还是仅含节点信息的内容。
02 / GENERAL FIELDS
通用字段:端口、模式与控制接口
监听端口如何选择
port 用于 HTTP 代理,socks-port 用于 SOCKS5 代理,mixed-port 可以在同一端口接收 HTTP 与 SOCKS5 请求。桌面客户端通常只需要一个 mixed-port,应用程序再把代理地址设置为 127.0.0.1 和对应端口。端口只是本机监听入口,不是远端节点端口。节点对象中的 port 表示远端服务器端口,两者名称相同但层级和用途不同。
监听端口不能与其他程序占用的端口重复。启动日志出现 address already in use、bind failed 或类似信息时,应先关闭残留进程,或者把本地监听端口改为未被占用的值。客户端界面若会自动写入端口设置,应以界面最终生成的运行配置为准。仅修改订阅原始文件,而客户端随后又套用本地覆写,运行中的端口可能与文件内容不同。
| 字段 | 作用 | 常见使用方式 | 检查重点 |
|---|---|---|---|
| port | HTTP 代理监听端口 | 供只支持 HTTP 代理的程序使用 | 确认程序代理类型与端口一致 |
| socks-port | SOCKS5 代理监听端口 | 供支持 SOCKS5 的程序使用 | 不要误填远端节点端口 |
| mixed-port | 混合代理监听端口 | 桌面客户端常用的统一入口 | 检查端口占用与系统代理设置 |
| redir-port | 透明代理重定向入口 | 特定 Linux 网络方案 | 需要配合系统路由与防火墙规则 |
| tproxy-port | TPROXY 透明代理入口 | Linux 路由器或网关 | 需要内核和策略路由支持 |
allow-lan 与监听地址
allow-lan 控制局域网设备能否使用本机代理。设为 false 时,通常只服务本机连接;设为 true 后,还要结合 bind-address、操作系统防火墙和当前网络类型判断是否能够从其他设备访问。局域网共享代理时,应仅在受控网络中启用,并为控制接口与代理入口设置清晰的访问边界。公共网络环境下不应把控制器或代理端口暴露给不受信任的设备。
mixed-port: 7890
allow-lan: true
bind-address: 0.0.0.0
authentication:
- "device-user:your-password"
示例中的认证作用于代理入口,具体客户端与内核对认证字段的支持方式需要以实际运行配置为准。若只需要本机使用,保持 allow-lan: false 更直接。局域网设备无法连接时,依次检查本机局域网地址、端口监听范围、防火墙入站规则、设备是否处在同一网络,以及移动设备是否把代理类型填错。
mode 的三种常用取值
mode: rule 按 rules 从上到下匹配,是日常使用的主要模式。mode: global 把连接交给全局策略组,适合临时验证某个节点是否可用,但它会绕过精细分流。mode: direct 让连接直接访问,适合确认问题是否由代理链路引起。排错时可以短暂切换模式进行对照,确认后应回到目标模式,不要把全局模式当作修正规则遗漏的长期替代方案。
模式只决定流量如何进入策略,不会自动解决 DNS 解析、系统代理未启用、TUN 未接管或应用绕过代理的问题。浏览器可以访问而命令行工具无法访问时,常见原因是浏览器遵循系统代理,而命令行程序没有读取系统代理设置。此时应为程序显式设置 HTTP 或 SOCKS5 代理,或者使用经过正确配置的 TUN 模式。
日志、IPv6 与控制器
log-level 常见值包括 silent、error、warning、info 与 debug。日常运行使用 info 通常足够,定位配置与连接问题时临时改为 debug,完成排查后再恢复,避免日志中过量信息干扰判断。阅读日志时先找最早出现的错误,不要只看最后一行;后续大量连接失败有时只是首个 DNS 或配置错误的连锁结果。
ipv6 决定内核相关网络行为是否启用 IPv6。网络本身没有稳定 IPv6 路由时,盲目开启可能产生解析结果可得但连接路径不可用的情况。DNS 区域还存在独立的 dns.ipv6,它控制是否返回 AAAA 结果。顶层 IPv6 与 DNS IPv6 应结合实际网络条件设置,而不是只修改其中一处。
external-controller 是客户端界面与内核通信的控制接口,常见写法为 127.0.0.1:9090。绑定到回环地址时仅供本机访问。若设置了 secret,控制端需要携带对应凭据。控制器端口与代理端口用途不同,不能把系统代理指向控制器端口。图形客户端通常会自动管理这些字段,手工修改前应确认客户端是否会在启动时覆盖。
03 / DNS PIPELINE
DNS 配置与解析路径
DNS 模块处理什么问题
DNS 区域决定域名由谁解析、使用哪种传输方式、是否返回 Fake IP,以及解析请求本身通过直连还是代理发出。浏览器显示连接失败时,节点链路和 DNS 链路需要分别检查:节点能够建立连接,不代表域名已经得到正确结果;DNS 可以返回地址,也不代表该地址对应的连接路径能够到达。配置 DNS 的目标是让解析来源、分流规则和实际连接出口保持一致。
dns.enable 开启内核 DNS 模块。使用 TUN、Fake IP 或需要避免系统解析路径与代理分流脱节时,通常需要启用。listen 指定 DNS 服务监听地址,例如 0.0.0.0:1053。桌面 GUI 可能由内核内部接管而不要求用户直接访问该端口;路由器和网关场景则常把局域网设备的 DNS 请求转发到这里。监听到局域网地址时仍需考虑防火墙和访问范围。
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:
- "*.lan"
- "*.local"
- "time.*.com"
default-nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver:
- https://dns.alidns.com/dns-query
- https://1.1.1.1/dns-query
proxy-server-nameserver:
- https://1.1.1.1/dns-query
nameserver-policy:
"geosite:cn":
- https://dns.alidns.com/dns-query
default-nameserver 与 nameserver
default-nameserver 主要用于解析加密 DNS 服务器自身的域名,以及在建立上游连接前提供基础解析。这里通常填写可直接访问的 IP 地址 DNS,不宜全部写成仍需域名解析的 DoH 地址,否则可能形成“解析 DNS 服务器域名还需要先访问该 DNS 服务器”的依赖环。nameserver 是主要上游,可以使用普通 UDP DNS、DoT 或 DoH。选择上游时需要考虑本地网络可达性和分流出口,不是协议名称越复杂越合适。
proxy-server-nameserver 用于解析代理服务器域名。节点的 server 如果填写域名,内核必须先得到该域名的地址才能连接节点;若这一步错误地依赖尚未建立的代理,就会形成启动环。为代理服务器提供独立、可直连访问的解析上游,可以降低这类问题。节点服务器直接使用 IP 时不需要解析,但服务端地址变更将无法通过 DNS 自动更新。
nameserver-policy 可以按域名或 geosite 分类指定上游。它解决的是“某类域名交给哪组 DNS 查询”,不是“最终连接走哪个代理”。连接出口仍由 rules 决定。DNS 策略与流量规则可以使用相似的域名集合,但两者作用阶段不同。修改其中一处时,应确认另一处是否仍符合预期。
Fake IP 与 Redir Host
enhanced-mode: fake-ip 会为域名返回保留地址段中的映射地址。应用连接该地址后,内核根据映射恢复原始域名,再进行规则匹配和代理转发。这样可以保留域名信息,减少应用先在系统层完成真实解析而导致分流失去域名上下文的情况。fake-ip-range 应使用专门保留的地址范围,不要与当前局域网、VPN 或其他虚拟网络网段重叠。
部分局域网服务、设备发现、时间同步、游戏平台或依赖真实地址结果的程序不适合 Fake IP,可加入 fake-ip-filter。过滤项过宽会让大量域名退回真实解析,削弱 Fake IP 的一致性;过滤项过窄则可能出现局域网服务无法发现或应用拒绝保留地址。应根据日志与具体域名逐项添加,而不是复制一份来源不明的超长列表。
redir-host 返回真实解析地址,再由连接过程继续匹配。它与部分传统透明代理环境兼容较好,但域名信息在某些路径中可能不足。选择增强模式时,应先确定客户端是否使用 TUN、系统代理还是路由器透明代理,再以实际应用兼容性验证。切换模式后需要清理操作系统和浏览器 DNS 缓存,否则旧结果可能持续影响测试。
DNS 故障的定位顺序
第一步确认内核 DNS 模块已经启动,日志中没有端口占用和配置解析错误。第二步直接查询一个普通域名,观察是否得到结果;Fake IP 模式下得到保留地址属于预期现象。第三步测试节点服务器域名能否通过 proxy-server-nameserver 解析。第四步观察目标域名命中了哪条规则、连接走向哪个策略组。第五步再检查操作系统是否仍把 DNS 请求发往其他接口。
所谓 DNS 泄漏通常涉及“哪些解析请求绕过了预期路径”。仅看到不同 DNS 服务返回结果,不能直接判断原因。浏览器可能启用独立的安全 DNS,系统可能保留其他网络接口,应用也可能自行发起 DoH。排查时应先统一浏览器、系统与内核的 DNS 路径,再逐项恢复需要的功能。TUN 环境还要确认 DNS 劫持设置是否覆盖 UDP 与 TCP 查询。
| 现象 | 优先检查 | 常见原因 |
|---|---|---|
| 节点域名无法解析 | proxy-server-nameserver | 解析路径依赖尚未建立的代理 |
| 局域网设备名称失效 | fake-ip-filter | 本地域名被分配 Fake IP |
| 得到 AAAA 但连接超时 | dns.ipv6 与实际网络 | IPv6 解析可用但路由不可用 |
| 修改 DNS 后表现未变化 | 系统与浏览器缓存 | 旧解析结果仍在缓存期内 |
04 / PROXY DEFINITIONS
代理节点字段
节点对象的公共结构
proxies 是节点对象序列。每个对象至少需要唯一的 name、协议 type、服务器 server 与远端 port,其余认证和传输字段由协议决定。节点名称只在本地配置中充当引用标识,不会改变服务端参数。为了便于策略组和规则维护,名称应体现地区或用途,同时保持稳定;如果每次订阅刷新都改变名称,手工策略组中的直接引用容易失效。
server 可以是域名或 IP。域名便于服务端迁移,但依赖 DNS;IP 减少一次解析,但地址变化后需要更新配置。udp 表示该节点是否允许处理 UDP 流量,是否真正可用还取决于协议、服务端和网络路径。只打开客户端中的 UDP 开关并不能让不支持 UDP 的服务端获得该能力。
Shadowsocks 与 Trojan 示例
proxies:
- name: Example-SS
type: ss
server: ss.example.com
port: 8388
cipher: aes-128-gcm
password: "your-password"
udp: true
- name: Example-Trojan
type: trojan
server: trojan.example.com
port: 443
password: "your-password"
sni: trojan.example.com
skip-cert-verify: false
udp: true
Shadowsocks 的 cipher 必须与服务端一致,密码也要按字符串处理。不同加密方法对应不同密钥要求,不能只改客户端名称。Trojan 常通过 TLS 建立连接,sni 用于指定 TLS 握手中的服务器名称,一般应填写服务端要求的域名。skip-cert-verify: false 表示正常验证证书。证书名称不匹配时,应先核对服务器域名、SNI、系统时间和服务端证书配置,不宜把关闭验证当作长期处理方式。
VMess 与 VLESS 的身份和传输字段
proxies:
- name: Example-VMess
type: vmess
server: vmess.example.com
port: 443
uuid: 00000000-0000-4000-8000-000000000000
alterId: 0
cipher: auto
tls: true
servername: vmess.example.com
network: ws
ws-opts:
path: /proxy
headers:
Host: vmess.example.com
- name: Example-VLESS
type: vless
server: vless.example.com
port: 443
uuid: 00000000-0000-4000-8000-000000000000
network: tcp
tls: true
servername: vless.example.com
udp: true
uuid 是认证标识,必须保持标准格式并与服务端一致。示例 UUID 仅用于展示结构,不能作为真实连接参数。VMess 配置中的 alterId、cipher 等字段应按服务端提供值填写。VLESS 的传输与流控字段取决于服务端方案;客户端支持某个字段不代表可以自行添加后让服务端兼容。
network 描述传输层形态,例如 TCP、WebSocket 或 gRPC。使用 WebSocket 时,ws-opts.path 和 Host 请求头必须与服务端反向代理配置一致。使用 gRPC 时要核对服务名称。TLS 相关的 servername、SNI、ALPN 与指纹字段属于握手参数,任何一项与服务端入口不一致都可能表现为连接建立后立即关闭。
协议字段不能跨节点照搬
节点对象没有一套适用于所有协议的完整字段表。相同名字的字段也可能在不同内核版本或协议实现中有不同约束。最稳妥的来源是服务端或订阅生成的参数,再按当前内核支持的结构整理。把另一节点的 TLS、WebSocket 或插件参数整体复制过来,容易造成字段存在但语义不匹配。解析器可能接受这些字段,连接仍会失败。
订阅链接通常由提供方维护节点参数。用户需要修改的往往是节点名称、策略组组织和分流规则,而不是协议底层字段。若订阅导入后全部节点同时不可用,先检查订阅有效性、系统时间、DNS 与本地网络;若只有单个节点失败,再对照该节点的服务器、端口、认证和传输配置。节点筛选方法可参考延迟、地区、倍率与协议判断。
节点可用性与延迟测试的边界
延迟测试通常请求一个测试地址并记录完成时间,它反映的是某个时刻、某条测试路径的响应,不等同于所有网站的访问质量。测试超时可能来自节点不可达、测试地址被阻断、DNS 失败或策略组引用错误。延迟较低也不表示带宽、稳定性和目标地区访问一定更好。选节点时应结合连续测试、实际目标站点和持续连接表现。
节点对象加载成功但策略组中看不到,通常是策略组没有引用该节点,或 Provider 过滤条件将其排除。节点名称在订阅更新后改变时,静态 proxies 列表引用也会失效。需要长期维护的配置宜使用 proxy-providers 配合 use,并通过稳定的过滤规则组织节点,而不是在多个策略组中重复写入大量名称。
05 / POLICY GROUPS
策略组字段与选择逻辑
策略组是规则和节点之间的中间层
proxy-groups 把节点、内置动作和其他策略组组织成可选择的出口。规则通常不直接指向某个会变化的节点名称,而是指向稳定的策略组,例如“节点选择”“流媒体”“下载服务”。这样订阅节点变化时,只需调整策略组成员,不必重写所有规则。策略组可以嵌套,但应避免环形引用:A 引用 B、B 又引用 A 会导致配置无法形成有效出口。
内置目标常见有 DIRECT、REJECT 和兼容内核提供的其他动作。DIRECT 表示直接连接,REJECT 表示拒绝请求。规则目标既可以是策略组,也可以是具体节点或内置动作。为提高可维护性,除少数固定场景外,建议让规则指向策略组,再在策略组中决定实际出口。
select、url-test、fallback 与 load-balance
| 类型 | 选择方式 | 适用场景 | 注意事项 |
|---|---|---|---|
| select | 用户手动选择成员 | 主策略、地区选择、固定业务 | 选择结果需要成员名称保持稳定 |
| url-test | 按测试结果选择响应较快者 | 同用途节点自动选择 | 测试地址与间隔会影响结果 |
| fallback | 当前成员失败时切换 | 优先级明确的备用链路 | 恢复与切换速度取决于检测周期 |
| load-balance | 按策略分配连接 | 多个可用出口的连接分配 | 不等同于单连接带宽叠加 |
select 最容易理解,成员顺序决定界面展示顺序,当前选择由客户端保存。url-test 定期请求指定 URL,根据结果自动选择。interval 控制检测间隔,tolerance 用于减少结果接近时频繁切换。检测过于频繁会增加节点请求,间隔过长则无法及时反映链路变化。测试地址应稳定、响应体较小,并能代表预期网络路径。
fallback 按成员顺序保留优先级,当前节点不可用时选择后续可用成员,适合主备关系明确的配置。load-balance 在多个节点之间分配连接,具体分配行为由 strategy 等字段决定。它不会把一个下载连接拆分到多个节点,也不能突破单节点和目标服务器的带宽限制。需要保持同一目标会话出口稳定时,应选择能够维持一致性的策略。
proxy-groups:
- name: 节点选择
type: select
proxies:
- 自动选择
- 故障切换
- DIRECT
- name: 自动选择
type: url-test
proxies:
- Example-SS
- Example-Trojan
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
- name: 故障切换
type: fallback
proxies:
- Example-Trojan
- Example-SS
url: https://www.gstatic.com/generate_204
interval: 300
策略组嵌套与业务分层
一套清晰的分层通常包含“总入口—地区或自动选择—具体节点”。例如规则把普通代理流量交给“节点选择”,“节点选择”包含“自动选择”“故障切换”和若干地区组,地区组再包含对应节点。这样用户既可以使用自动策略,也可以手动固定地区。嵌套层级不宜过深,否则界面选择路径和故障定位都会变长。
业务组用于表达出口需求,不应简单复制节点列表。例如“流媒体”可以引用地区组,“开发服务”可以引用主选择组,“直连服务”可以只含 DIRECT。多个业务组引用同一个地区组时,节点维护集中在一处。若每个业务组都重复列出几十个节点,订阅更新后容易出现成员差异和遗漏。
Provider 成员与过滤
策略组可以使用 use 引用一个或多个 proxy-providers,从外部节点集合动态取得成员。部分内核还支持 filter、exclude-filter 等筛选方式。筛选通常使用正则表达式,应先用少量名称验证。地区关键词可能同时出现在套餐说明、倍率标记或其他节点名称中,过于宽泛的表达式容易误收,过于严格则可能得到空组。
proxy-groups:
- name: 香港节点
type: url-test
use:
- subscription-main
filter: "(?i)香港|HK|Hong Kong"
url: https://www.gstatic.com/generate_204
interval: 300
- name: 节点选择
type: select
proxies:
- 香港节点
- DIRECT
use:
- subscription-main
同时写 proxies 与 use 时,策略组会按内核支持方式组合静态成员和 Provider 成员。若界面出现大量重复节点,检查同一个节点是否既被静态写入,又由 Provider 引入。自动策略组为空时,先看 Provider 是否下载成功,再看筛选表达式,最后检查 Provider 中的节点名称是否与预期一致。
06 / RULE ENGINE
规则语法与匹配顺序
从上到下,命中即停止
rules 是有顺序的规则序列。连接到来后,内核从第一条开始检查,命中后把请求交给该条规则指定的策略,不再继续检查后续条目。因此具体规则应放在宽泛规则之前,兜底规则放在最后。把 MATCH 写在中间会使其后的规则无法执行;把广泛的域名后缀规则放在精确域名前面,也可能遮住后面的特殊处理。
多数规则采用逗号分隔结构:规则类型、匹配内容、目标策略,部分规则还可以附加额外参数。例如 DOMAIN-SUFFIX,example.com,节点选择 把 example.com 及其子域交给“节点选择”。规则中的目标名称必须存在。若名称含逗号会破坏分隔结构,因此策略组名称不宜使用逗号。
rules:
- DOMAIN,api.example.com,节点选择
- DOMAIN-SUFFIX,example.com,节点选择
- DOMAIN-KEYWORD,example,节点选择
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,节点选择
域名规则的差异
DOMAIN 只匹配完整域名,适合处理明确的 API 主机或需要特殊出口的单一服务。DOMAIN-SUFFIX 匹配指定域名及其子域,适合一个站点的整体分流。DOMAIN-KEYWORD 只要域名中含有关键词就可能命中,覆盖范围更宽,也更容易误伤。可以使用精确域名时,不应为了省几行配置而改用宽泛关键词。
域名匹配依赖内核在连接阶段获得域名信息。系统代理中的 HTTP 请求、带 SNI 的 TLS 连接以及 Fake IP 映射通常能提供域名上下文;纯 IP 连接只能进入 IP 类规则。应用自行解析后直接连接 IP 时,域名规则可能无法命中。遇到日志只显示目标 IP 时,应检查 DNS 是否由内核接管,以及应用是否绕过系统代理。
IP、GEOIP 与 no-resolve
IP-CIDR 用于 IPv4 网段,IP-CIDR6 用于 IPv6 网段。局域网、回环、链路本地等地址通常应直接连接,避免交给远端代理。CIDR 前缀长度决定范围,写错一位可能扩大到远超预期的地址段。修改网段规则前应先确认目标地址属于哪个网络,不要根据某一次解析结果直接添加过宽范围。
no-resolve 表示匹配该 IP 规则时不主动进行 DNS 解析。它适用于已经得到目标 IP、且不希望为了规则判断额外解析域名的情况。若规则必须通过域名解析才能获得 IP,添加 no-resolve 会改变匹配条件。该参数不是通用性能开关,应根据规则类型和当前连接上下文使用。
GEOIP 根据 IP 数据库分类,它匹配的是地址归属信息,不等同于域名类别。数据库需要随内核资源更新,分类结果也可能存在边界差异。需要稳定控制某个业务时,域名规则或维护明确的规则集通常更直接;GEOIP 更适合作为接近兜底位置的大范围分流条件。
进程、端口与网络类型规则
兼容内核可提供进程名、进程路径、目标端口、入站类型等扩展规则。进程规则依赖操作系统权限和内核获取进程信息的能力,移动平台、容器环境和部分沙箱应用可能无法提供完整信息。进程名也可能随更新变化,因此应在运行日志中确认实际识别结果。
端口规则适合协议范围明确的场景,但同一端口可以承载不同服务,单独依赖端口分流容易过宽。网络类型规则可以区分 TCP 与 UDP,适合处理特定 UDP 应用或需要直接连接的本地服务。复杂规则应写明用途注释,并控制数量;半年后仍能理解为什么存在,比追求极短配置更重要。
自定义规则的插入位置
自定义规则是否生效,关键在于它被插入到最终规则列表的哪个位置。需要覆盖订阅默认行为的精确规则,应放在对应宽泛规则之前;本地直连网段应位于代理兜底之前;MATCH 始终位于最后。许多客户端提供“规则前置”“规则追加”或脚本覆写。前置适合高优先级例外,追加适合补充订阅没有覆盖、且不会被已有兜底提前命中的规则。
验证规则时不要只看配置文本,应查看运行日志中的规则命中信息。先访问一个明确目标,再确认域名或 IP、命中规则类型、目标策略组、最终节点是否符合预期。若日志命中的是更早的一条规则,就调整顺序或缩小前一条规则范围。更多常见问题可在常见问题中按“使用技巧”和“故障排查”分类继续查询。
07 / PROVIDERS
Proxy Provider 与 Rule Provider
为什么把外部内容拆成 Provider
Provider 用于把经常更新的节点或规则集合从主配置中分离。proxy-providers 提供节点对象,供策略组通过 use 引用;rule-providers 提供规则内容,供 RULE-SET 调用。主配置负责运行框架和策略关系,Provider 负责外部数据更新。这样可以避免每次节点或规则变化都替换整份主配置。
Provider 不是策略组。节点 Provider 下载成功后,仍需被某个策略组引用;规则 Provider 下载成功后,仍需在 rules 中通过 RULE-SET 指定目标策略。只定义 Provider 而没有引用,不会自动改变流量。反过来,规则引用了不存在或加载失败的 Provider,也会造成对应集合无法匹配。
proxy-providers 结构
proxy-providers:
subscription-main:
type: http
url: "https://subscription.example.com/api/client?token=xxxx"
path: ./providers/subscription-main.yaml
interval: 21600
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 300
proxy-groups:
- name: 自动选择
type: url-test
use:
- subscription-main
url: https://www.gstatic.com/generate_204
interval: 300
- name: 节点选择
type: select
proxies:
- 自动选择
- DIRECT
use:
- subscription-main
type: http 表示从远端地址获取内容,url 是订阅地址,path 是本地缓存路径,interval 是更新间隔。路径应位于客户端允许写入的配置目录中。多个 Provider 不应共用同一个缓存文件,否则更新时可能互相覆盖。订阅地址属于访问凭据,应保存在客户端配置和受控备份中,不要发布到公开文档或截图。
health-check 对 Provider 中的节点执行可用性检测。它与策略组自身的 url-test 有关联但不完全相同:Provider 健康检查维护节点状态,策略组测试用于选择成员。检测地址、周期和网络环境会影响结果。节点数量较多时,不宜把周期设置得过短,以免产生密集请求。
rule-providers 的 behavior
rule-providers:
private-domain:
type: http
behavior: domain
format: yaml
url: "https://rules.example.com/private-domain.yaml"
path: ./rules/private-domain.yaml
interval: 86400
private-network:
type: http
behavior: ipcidr
format: yaml
url: "https://rules.example.com/private-network.yaml"
path: ./rules/private-network.yaml
interval: 86400
rules:
- RULE-SET,private-domain,DIRECT
- RULE-SET,private-network,DIRECT,no-resolve
- MATCH,节点选择
behavior 描述规则集内容类型。domain 用于域名类条目,ipcidr 用于地址网段,classical 可以承载带规则类型的经典格式。Provider 文件内容必须与 behavior 对应。把完整的 DOMAIN-SUFFIX,example.com 条目放进只接受域名载荷的集合,或把纯网段放入不匹配的格式,都会导致加载错误或条目失效。
域名 behavior 的 YAML 载荷通常写成 payload 序列,具体条目格式依据内核约定。经典格式则保留完整规则类型。选择 behavior 时先看规则源提供的实际格式,不要只根据文件名判断。远端地址返回网页、登录页或错误提示时,即使 HTTP 请求成功,内容也不是有效规则文件。
Provider 更新与缓存
远端更新失败时,内核可能继续使用本地缓存,因此“当前仍能运行”不代表 Provider 已完成本次刷新。日志中应区分下载失败、解析失败、写入失败与缓存读取成功。下载失败通常检查网络、地址和访问权限;解析失败检查返回内容格式;写入失败检查目录权限与路径;缓存损坏则可在备份配置后删除对应缓存,让客户端重新获取。
更新间隔使用秒数。节点订阅和规则集不必使用相同周期:节点可能变化较频繁,稳定规则集可以降低更新频率。客户端启动时是否立即更新、失败后如何重试,取决于内核和 GUI 管理方式。不要通过设置极短周期替代手动排错,持续失败只会重复产生请求和日志。
多 Provider 的组织方法
同时使用多个订阅时,应为每个 Provider 使用独立名称、缓存路径和健康检查。策略组可按来源直接引用,也可通过名称过滤后按地区组合。来源名称适合管理订阅,地区策略适合日常选择,两者不应混在同一命名层级。例如 Provider 使用“subscription-main”,策略组使用“香港节点”“自动选择”,用户界面会更清楚。
规则 Provider 也应按用途拆分,例如私有网络、开发服务、媒体服务和拦截列表。拆分过细会产生大量远端请求和复杂顺序,拆分过粗则不便指定不同策略。应以“是否需要独立更新、独立策略或独立优先级”为判断标准。多个 RULE-SET 之间仍遵循从上到下首次命中的规则逻辑。
08 / OVERRIDE AND MERGE
覆写、合并与配置维护
先识别配置的来源层级
图形客户端中的最终运行配置通常由多个来源组成:订阅原始内容、客户端生成的基础参数、用户界面设置、本地覆写文件、脚本处理结果以及运行时补充字段。用户看到的订阅 YAML 不一定等于内核最终载入的配置。修改没有生效时,第一步应在客户端中查找“运行配置”“配置预览”或日志输出,确认最终值来自哪一层。
Clash Plus、Clash Verge Rev、FlClash、Clash Nyanpasu 等客户端对覆写界面的命名和执行顺序可能不同,移动端也可能只开放部分字段。桌面与移动设备优先使用客户端提供的覆写入口,避免直接编辑由订阅管理的缓存文件。订阅缓存通常会在刷新时重建,手工修改容易被下一次更新覆盖。
映射、序列与标量的合并差异
YAML 顶层值可以分为映射、序列和标量。dns 是映射,内部还有多级键;rules、proxies 和 proxy-groups 通常是序列;mode、mixed-port 是标量。覆写系统处理这三类值的方式可能不同。标量通常直接替换,映射可能按键递归合并,序列则可能整体替换、前置、追加或按名称处理。
这一区别决定了覆写是否安全。只想增加一条规则时,如果覆写机制对 rules 采用整体替换,就会丢失订阅全部规则;只想修改 dns.enhanced-mode 时,如果系统进行浅层替换,整个 dns 映射可能只剩一个字段。操作前必须查看客户端对 merge、prepend、append、override 的定义,不能假设所有客户端都采用同一种算法。
| 操作 | 典型结果 | 适合内容 | 主要风险 |
|---|---|---|---|
| Override | 用新值替换旧值 | mode、端口、完整 DNS 区块 | 序列被整体覆盖 |
| Merge | 按键合并映射 | 通用字段、DNS 子项 | 浅合并与深合并结果不同 |
| Prepend | 插入序列开头 | 高优先级自定义规则 | 过宽规则遮住订阅规则 |
| Append | 追加到序列末尾 | 策略成员或补充规则 | 可能位于 MATCH 之后而失效 |
规则合并要处理 MATCH
规则覆写最常见的问题是兜底位置。订阅规则通常已经以 MATCH 结束,简单把本地规则追加到末尾,这些规则不会被执行。正确做法通常是把本地高优先级规则插到订阅规则之前,或者在脚本中暂时取出末尾 MATCH,插入附加规则后再放回。最终列表只保留一个明确的兜底目标。
# 前置规则示意
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN-SUFFIX,dev.example.com,节点选择
# 最终配置仍应接续订阅规则,并以一个 MATCH 结束
# - RULE-SET,...
# - GEOIP,...
# - MATCH,节点选择
前置规则应尽量精确。如果在最前面加入过宽的 DOMAIN-KEYWORD、大范围 CIDR 或地区规则,订阅中的细分策略会被提前截断。每次新增规则后,至少验证一个应命中的目标和一个不应命中的相邻目标,并在日志中查看实际命中项。
策略组与节点的名称合并
策略组序列的合并不能只看对象位置。部分工具按 name 查找并修改已有组,部分工具只是把新对象追加到列表。若追加了同名策略组,内核可能报重复名称,也可能由客户端预处理时保留其中一个,结果不易预测。需要修改已有组成员时,应使用客户端明确提供的按名称覆写方式;不支持时,生成完整的目标策略组序列更可控。
节点列表也存在同名冲突。订阅中已有“香港 01”,本地又添加同名节点时,引用无法清楚区分来源。自建节点应使用稳定前缀,例如“LOCAL-”或用途名称。Provider 过滤器依赖名称时,也要确认前缀不会被地区正则误选。
DNS 覆写要保持完整依赖
修改 DNS 时不能只关注 nameserver。使用域名形式的 DoH 上游时,需要可工作的 default-nameserver;节点服务器使用域名时,需要检查 proxy-server-nameserver;使用 Fake IP 时,还要保留地址范围和过滤项。一个看似只替换上游地址的浅层覆写,可能意外删除这些依赖字段。
更稳妥的方法是先导出最终 DNS 区块,复制为本地维护版本,再一次性修改并验证。确认客户端采用递归合并时,才使用最小子键覆写。切换 DNS 方案后,重新加载配置、清理缓存并测试节点域名和普通目标域名,不要只以客户端显示“配置成功”作为完成标准。
建立可恢复的修改流程
每次修改只处理一个主题,例如先改 DNS,再改策略组,最后改规则。修改前保留当前可运行配置;修改后进行语法加载、Provider 更新、策略组成员检查、规则命中和实际访问五项验证。一次同时替换多个区块,出现错误后很难判断是哪一层引起。
配置文件中可以用注释记录修改目的、来源和依赖,例如“必须放在订阅规则之前”“需要 Provider subscription-main”“仅供局域网地址直连”。注释不应包含订阅凭据或节点密码。长期维护时,比对结构变化比单纯比对整行文本更有效,因为订阅可能调整节点顺序和名称。
订阅更新后启动异常时,先切回保留的可运行配置,确认客户端和内核本身能够启动,再比较新旧配置的顶层字段、策略组名称和规则目标。若客户端启动即退出、窗口不显示或更新后崩溃,可继续查看客户端启动闪退排查顺序。需要重新完成首次连接验证时,返回使用指南按订阅、节点、系统代理和连接状态逐步检查。
最终配置自检清单
加载前检查 YAML 缩进、冒号空格、引号和序列层级;加载后检查端口是否成功监听、DNS 是否启动、Provider 是否取得有效内容。随后确认每个规则目标都有对应策略组,每个策略组至少存在一个有效成员,嵌套关系没有循环,最终规则列表只有一个位于末尾的 MATCH。最后分别测试直连域名、代理域名、局域网地址、节点服务器域名和需要 UDP 的应用。
配置通过一次测试并不表示所有网络环境都相同。切换 Wi-Fi、移动网络、公司网络或 IPv6 环境后,DNS 可达性、MTU、防火墙和系统代理行为可能变化。排查时保留同一份配置,只改变一个环境变量,才能判断问题来自配置还是网络。需要更换客户端时,可在下载中心查看 Windows、macOS、Android、iOS 与 Linux 对应选项;普通用户优先选择 Clash Plus,再导入同一订阅进行对照测试。