配置结构与 YAML 语法
Clash 配置文件描述的是内核如何监听请求、解析域名、选择出口,而不是一份客户端界面的完整偏好设置。窗口位置、菜单栏图标、开机启动等通常由图形客户端另外保存。阅读配置前,先确认当前运行的是哪一种内核,以及客户端实际加载了哪个配置。文件名叫 config.yaml 不代表它必然是正在生效的文件;订阅配置、本地配置与运行时生成文件可能同时存在。
映射、列表与缩进层级
YAML 的映射采用键和值的形式,列表项使用短横线。顶层的 dns 是映射,proxies、proxy-groups 和 rules 通常是列表。下级字段必须比父级多缩进,建议统一使用两个空格,避免制表符。同一层的字段应当对齐。解析错误指向某一行时,真正原因也可能在上一行,例如引号没有闭合,或者某个列表项少写了短横线。
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
dns:
enable: true
nameserver:
- https://dns.alidns.com/dns-query
proxies: []
proxy-groups:
- name: "出口选择"
type: select
proxies:
- DIRECT
rules:
- MATCH,出口选择
这是一份只包含直连出口的结构示例,不包含可连接的远程代理节点。它适合检查 YAML 层级、策略组引用与规则兜底关系,不能代替服务提供方的节点配置。不要把各章片段直接首尾拼接成一个文件:同名顶层字段应合并到同一个位置,尤其不能重复出现两段 dns 或两段 rules,再假设内核会自动理解合并意图。
字符串、布尔值与特殊字符
包含冒号加空格、井号或容易产生类型歧义的值,建议使用引号包裹。井号在普通文本中可能开始一段注释,导致后半段内容不再作为密码或名称读取。布尔值直接写 true 和 false,端口写整数。节点名称、策略组名称与规则目标都是字符串,引用时要保持完整一致;中文名称可以使用,但名称前后的空格也可能成为字符串的一部分。
使用双引号时要注意反斜线转义;不需要转义的普通字符串可用单引号。编辑器自动替换成弯引号后,文件可能仍能解析,却得到意料之外的字符串。排查引用失败时,应比较原始文本,而不是只看界面中近似的名称。不要让两个节点或两个策略组使用相同名称,也不要用 DIRECT、REJECT 等内置出口名称给自定义对象命名。
配置来源与验证入口
订阅链接返回的内容不一定就是完整 YAML:有些链接返回编码节点列表,有些需要服务端转换,有些会根据请求方式返回不同格式。导入失败时,先在客户端确认配置类型,再看解析日志。网页返回的登录页、错误页或过期提示即使被保存为 YAML 扩展名,也不是有效配置。订阅地址可能包含访问凭据,不应贴到公开讨论区或截图中。
如果设备已经安装独立的 mihomo 命令行程序,可以在终端执行下列语法测试。图形客户端内置的内核未必加入 shell 搜索路径,因此出现找不到命令不等于配置损坏。测试时应使用与客户端相近的内核和相同资源目录;引用外部规则文件的配置,还依赖对应文件存在。测试通过仅说明可加载,不能证明远程节点可达或分流符合预期。
mihomo -t -f ./config.yaml
建议保留一份能够正常连接的原文件,每次只修改一组相关字段,并记录预期变化。这样出现问题时,可以明确区分语法错误、客户端覆写、网络不可达与规则命中异常。把大量不相关的网上片段一次性加入配置,会让错误之间相互遮蔽,也会使后续回滚失去可比较的基线。
监听端口与访问范围
端口字段决定本机应用把代理请求交给内核的入口。它们不等于远程节点端口,也不等于控制接口端口。浏览器连接本地混合端口后,内核才会依据规则选择远程节点或直连出口。远程节点的服务器端口则写在对应节点下。把这两个层次混淆,常见结果是把系统代理指向远程服务器,或者把远程节点地址错误地改成回环地址。
HTTP、SOCKS 与混合端口
| 字段 | 接收的请求 | 使用边界 |
|---|---|---|
port | HTTP 代理,包括 CONNECT 请求 | 可供系统 HTTP 与 HTTPS 代理使用 |
socks-port | SOCKS 代理 | 应用需支持相应代理协议 |
mixed-port | HTTP 与 SOCKS 代理 | 两种协议共享一个监听端口 |
external-controller | 内核管理 API | 不是网页流量代理入口 |
普通桌面使用可以只设置一个混合端口。示例采用 7890,并不代表所有客户端都采用这个数值;界面显示、运行配置和系统代理设置必须相互对应。若分别启用多个独立监听入口,应使用不同端口,避免同一地址上的监听冲突。关闭不需要的入口比堆叠所有端口字段更容易理解,也便于判断哪个入口正在被应用使用。
mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
回环地址与局域网共享
127.0.0.1 是当前设备的 IPv4 回环地址。手机填写这个地址时,连接的是手机自身,不会连接到 Mac。需要把 Mac 的代理共享给局域网设备时,应明确允许局域网连接、配置合适的监听地址,并在其他设备填写 Mac 的实际局域网地址。监听开放后还要考虑防火墙、网络隔离和访问认证,不能只把一个开关打开就忽略访问边界。
allow-lan 控制是否允许局域网请求,bind-address 则用于限制监听地址。实际可访问性取决于这些字段的组合、内核行为及系统防火墙。桌面自用时建议维持回环访问;共享场景应限制可信网络,不应在路由器上把本地代理端口直接映射到公网。公共无线网络中的其他设备并不因为处于同一网段就可信。
macOS 系统代理字段
macOS 的网页代理和安全网页代理通常都填写本地 HTTP 入口,安全网页代理的名称并不意味着本地入口必须额外启用 TLS。HTTPS 网站一般通过 HTTP CONNECT 建立隧道。若客户端使用混合端口,网页代理、安全网页代理与 SOCKS 代理可以指向相同的回环地址和端口;若使用独立端口,则需要分别对应,不能照抄示例数值。
下列命令可以查看名为 Wi-Fi 的网络服务当前设置。设备上的服务名称可能不同,可先用列表命令确认。系统中有多个网络服务时,应检查实际承载连接的那个服务;外接网卡、有线网络或网络服务改名,都可能让检查对象与真实出口不一致。命令输出中的地址正确,也不表示客户端一定正在监听,因此还要检查本地进程。
networksetup -listallnetworkservices
networksetup -getwebproxy Wi-Fi
networksetup -getsecurewebproxy Wi-Fi
networksetup -getsocksfirewallproxy Wi-Fi
lsof -nP -iTCP:7890 -sTCP:LISTEN
端口被占用时,先识别监听进程,不要直接结束不认识的系统进程。两个代理客户端同时运行可能争用端口,也可能轮流修改系统代理。退出其中一个后,仍需确认系统设置没有残留。若更换了端口,还要同步更新 shell 环境变量、编辑器代理配置和其他手动填写的应用设置,否则浏览器恢复正常而部分应用仍然连接旧地址。
运行模式与流量入口
运行模式决定请求进入内核之后如何选择出口,系统代理与 TUN 则决定请求如何进入内核。这是两组不同的问题。打开规则模式不会自动接管所有应用,打开 TUN 也不意味着所有流量必须经过远程代理。解释连接行为时,应先确认应用采用了哪一个入口,再确认内核当前处于哪一种运行模式,最后查看具体连接的匹配结果。
规则、全局与直连模式
mode: rule 按规则列表顺序选择策略;mode: global 使用全局策略选择;mode: direct 则采用直连行为。它们不是连接质量等级,也不是网络权限级别。全局模式适合短时对照测试,帮助判断异常是否与规则有关,但不应把它当作修复全部问题的开关。若所选远程节点本身不可达,切换全局模式通常不会改善结果。
mode: rule
log-level: info
ipv6: false
图形客户端一般允许在界面中切换模式,但界面状态可能通过控制接口修改运行中的内核,并不一定回写原始 YAML。重新加载配置后,模式是否保留取决于客户端的保存策略。排查时需要同时看文件与实时界面,不能仅凭编辑器中的 mode 值认定当前状态。客户端的运行日志、连接页和生成配置是更直接的观察依据。
系统代理与终端环境变量
系统代理主要影响遵循系统代理设置的应用。很多命令行程序有自己的代理逻辑,默认不会读取 macOS 网络设置。可为当前 shell 临时设置环境变量,再进行对照测试;新开的终端窗口不会自动继承另一个窗口后来添加的变量。不同工具对变量名称和大小写的支持存在差异,出现问题时应继续查对应工具文档,而不是反复切换系统代理。
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export all_proxy=socks5h://127.0.0.1:7890
curl -I https://example.com
unset http_proxy https_proxy all_proxy
这里的 socks5h 表示支持该写法的工具把目标域名交给代理侧处理,和先在本机解析再发送地址有所区别。环境变量只影响读取它们的程序,不会改变整个操作系统的网络路由。某些工具同时提供命令行参数与配置文件,优先级也可能高于环境变量,因此验证时应尽量减少重复设置,避免不知道究竟是哪一层在起作用。
TUN 配置与权限边界
TUN 借助虚拟网络接口接收更广范围的 IP 流量,通常需要客户端安装辅助服务或取得相应权限。下面是 mihomo 的常见字段组合,不是所有图形客户端都直接采用同样的输入方式。有些客户端会接管 TUN 字段、自动选择接口或生成排除路由,应优先使用该客户端支持的设置入口。完整启用步骤见TUN 模式教程。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
auto-route 让内核尝试建立相应路由,auto-detect-interface 用于自动识别出口接口。切换无线网络、接入扩展坞或启动其他 VPN 后,出口接口与路由可能变化。连接中断时应检查接口和路由状态,不要立即归因于节点。企业 VPN、虚拟机和其他网络扩展可能同时修改路径,组合使用需要逐个启用并观察。
DNS 劫持规则也有边界:上面的配置针对常规 DNS 端口流量,并不等于自动接管所有应用内置的加密 DNS。TUN 开启后如果仅有部分域名异常,需要联合检查 DNS 模式、应用自身设置和路由排除项。关闭客户端前还应让客户端正常撤销接管,避免强制结束进程后留下暂时不可用的网络状态。
故障对照可以按固定顺序进行:先关闭额外 VPN,只用系统代理测试;确认入口可用后再启用 TUN;最后恢复其他网络工具。每次只改变一个条件,并记录浏览器、终端与具体应用的差异。Windows 的应用回环属于另一平台机制,不是 macOS TUN 的同义词,相关补充放在Windows 应用回环说明。
DNS 字段与域名解析路径
DNS 配置需要回答三个问题:应用的查询是否进入内核、内核使用哪个解析器、解析结果如何参与后续连接。仅仅写入一个公共 DNS 地址,并不能保证所有应用都使用它。系统代理场景下,应用可能先调用系统解析器;通过 HTTP CONNECT 或远程解析的 SOCKS 请求则可能保留域名。TUN、应用内置加密 DNS 与本地缓存又会改变观察到的路径。
基础解析器与引导解析
dns.enable 启用内核 DNS 模块,nameserver 提供常规上游解析器。加密 DNS 地址本身如果使用域名,就需要先把这个域名解析成地址;default-nameserver 可用于这类引导解析,适合填写明确的 IP 地址。不要把所有解析器都写成相互依赖的域名,再让它们依靠尚未可用的代理链路完成首次连接。
dns:
enable: true
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
nameserver:
- https://dns.alidns.com/dns-query
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
fake-ip-filter:
- "*.lan"
- "*.local"
示例展示字段之间的关系,不代表某个公共解析器适合全部网络。选择上游时要考虑当前网络能否直连、组织内部域名是否需要专用解析器,以及远程节点所在网络的解析需求。proxy-server-nameserver 用于代理服务器域名解析,能够把节点地址解析与普通网站解析分开考虑,降低启动时出现循环依赖的风险。
fake-ip 与真实地址模式
fake-ip 模式为符合处理条件的域名返回合成地址,内核利用映射关系恢复原始域名,再进行连接和规则判断。示例网段属于基准测试用途地址空间,不是远程代理服务器地址。应用看到这类地址并不必然意味着解析错误;但如果请求拿到合成地址后绕过了内核,连接就可能失败,因此解析入口与流量入口必须保持一致。
使用真实地址响应的模式更接近传统 DNS 行为,但域名到连接的关联可能受到应用缓存、共享 IP 或连接方式影响。两种模式不是简单的优劣关系。局域网发现、游戏、设备管理或某些明确校验地址的应用,可能需要排除 fake-ip。添加过滤条目之前,应先确认异常确实来自地址兼容性,而不是远程节点或目标服务不可达。
按域名选择解析器
nameserver-policy 可为指定域名选择解析器,适合把公司内部域名交给内部 DNS。下面使用示例域名和私网地址说明结构,实际使用时必须替换为组织提供的真实值。若内部 DNS 只能通过企业 VPN 访问,还需要保证路由允许查询到达该地址。把内部域名交给公共解析器,通常无法得到有效结果,也可能暴露不必要的查询信息。
dns:
nameserver-policy:
"+.corp.example.com":
- 192.168.10.1
这段内容应合并进已有的 dns 映射,不能作为第二段同名顶层字段追加。引入基于规则选择 DNS 出口的高级配置前,应先建立可工作的基础解析链。某些 DNS 路由选项会让解析请求也参与规则判断,如果规则判定本身又需要 DNS,就需要结合内核文档处理依赖关系,而不是不断增加解析器数量。
DNS 问题的观察顺序
先确认客户端日志中是否出现对应查询,再看响应地址和连接最终选择的出口。普通 dig 测试通常不能证明应用内置的加密 DNS 行为;浏览器成功打开网页,也不能证明终端使用了同一解析路径。修改配置后,浏览器、系统和内核可能各自保留缓存,需要关闭旧连接并发起新请求,必要时再按客户端提供的方法清理缓存。
IPv6 也需要分层理解:顶层开关、DNS 是否返回 IPv6 地址、操作系统是否具备可用 IPv6 路由,是不同条件。关闭其中一个字段不是对所有 IPv6 问题的通用解释。遇到连接慢或首个请求等待,应对比解析时间、连接建立时间与所选出口,按网速慢的分层排查继续定位,避免把所有等待都归为 DNS 故障。
代理节点字段与远程提供者
代理节点描述一条具体的远程连接方式,核心是协议类型、服务器地址、服务端端口与认证参数。策略组负责选择节点,规则负责选择策略组,三者不能相互替代。服务提供方给出的节点字段应作为主要依据,不应根据节点名称猜测协议。例如名称里出现某种协议字样,只是标签,内核实际采用的仍然是 type 字段。
通用字段与协议专属字段
name 用于被策略组引用,server 是服务器域名或 IP,port 是远程服务监听端口。认证方式随协议变化:有的使用密码,有的使用用户标识,还有的同时要求 TLS 与传输参数。字段名称相似不代表可以跨协议照搬。下面的 Shadowsocks 示例仅说明结构,其中域名与密码是教学假值,不能直接建立远程连接。
proxies:
- name: "示例出口"
type: ss
server: proxy.example.com
port: 443
cipher: aes-128-gcm
password: "your-password"
udp: true
加密方法、密码和服务端端口必须与服务端一致。端口写成常见的网页端口,并不意味着该节点就是 HTTPS 服务,也不意味着普通浏览器可以直接访问它。udp: true 只表示配置允许相应能力,实际还取决于协议实现、服务端支持、上游网络与应用请求路径。UDP 不通时,应检查整个链路,而不是只反复切换这个字段。
TLS、服务器名称与传输参数
对启用 TLS 的协议,需要理解连接地址与证书验证名称可能不同。server 决定连接到哪里,部分协议中的 servername 等字段用于传递和验证服务器名称;具体名称取决于协议配置格式。WebSocket 路径、请求头、gRPC 服务名等也必须与服务端一致。漏掉这些参数时,TCP 端口可能可达,但上层握手仍然失败。
证书错误应先检查系统时间、服务器名称、证书链和服务端部署。跳过证书验证会改变安全边界,不应作为通用排错结论。也不要在不知道用途时自行添加指纹、传输优化或连接复用字段;某个字段在其他协议中有效,不代表当前协议支持。解析器接受了未知或无关字段,也不意味着这些字段正在产生预期作用。
远程节点集合与健康检查
proxy-providers 将节点来源与主配置分离,适合定期更新节点集合。提供者文件需要符合节点提供者的结构,不能随意把一份包含完整规则和 DNS 的订阅当成同一种输入。下面展示远程来源写法,链接是教学示例;正式配置应使用可信来源,并把访问凭据视作私密信息,不要提交到公开仓库。
proxy-providers:
remote-pool:
type: http
url: "https://example.com/proxies.yaml"
path: ./providers/remote-pool.yaml
interval: 86400
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
interval 表示更新间隔,健康检查间隔则控制可用性测试,两者承担不同任务。路径相对于内核工作目录解释,图形客户端可能使用专门的数据目录。更新失败时应区分远程响应异常、格式不符和本地目录不可写;已有缓存是否继续可用,也要结合日志判断。不要在没有备份时直接删除缓存,把原本还能工作的节点集合一起清空。
节点名称与引用稳定性
订阅更新可能改变节点名称。手工策略组如果逐个引用旧名称,更新后可能出现引用缺失。通过提供者的 use 引入集合,通常比复制大量节点名称更易维护,但筛选表达式也需要跟随命名方式调整。多个来源合并时要避免重名;重名不只是显示问题,还会让策略选择、日志阅读与覆写定位变得不确定。
节点列表能够显示,并不等于节点已经完成可用性验证。排查顺序应从域名解析、服务器连接、协议握手,再到目标访问逐层推进。单个节点失败时先与同一策略组中的另一个节点对照;全部节点失败时,再检查本机网络、入口、系统时间和配置来源。测速结果也不能代表所有网站、所有协议和所有时段的实际表现。
选择客户端时可先查看macOS 下载入口中的 Clash Plus,再根据功能需求比较 Clash Verge Rev 与 FlClash。客户端界面相近并不表示其内核字段支持范围完全相同。需要了解图形客户端与内核之间的分工,可继续阅读Clash 开源生态与 mihomo 关系,再决定配置应放在哪一层维护。
策略组字段与健康检查
策略组把节点组织成一个可引用的出口名称。规则通常指向组,而不是直接指向某个经常变动的节点,这样替换节点时不必重写整套规则。一个组也可以引用另一个组,构成手动选择与自动选择的层次。但引用关系必须保持无循环,组名要唯一,并且所有被引用的对象在最终运行配置中存在。只在原始订阅中存在、却被覆写删除的节点同样会造成问题。
手动选择组与嵌套关系
proxy-groups:
- name: "出口选择"
type: select
proxies:
- 自动选择
- DIRECT
- name: "自动选择"
type: url-test
use:
- remote-pool
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
示例中的 remote-pool 对应上一章定义的提供者。proxies 列出明确的节点或组名,use 引入提供者集合。使用 select 时,实际出口取决于用户当前选择,不会因为列表中的某个节点出现连接问题就自动改选,除非用户选择的是一个内部具备自动选择行为的子组。列表顺序也不等于当前选择状态。
多层嵌套适合把地区、用途与选择方式拆开,但层数过多会降低可读性。连接页显示命中了某个规则目标后,仍要沿着组的当前选择查看最终节点。排错时可先建立一个直接引用已知节点的简单选择组,验证节点本身可用,再恢复自动组和更复杂的嵌套。这样能把策略逻辑问题与远程连接问题分离。
自动选择、故障回退与负载均衡
| 类型 | 主要行为 | 适合的目标 |
|---|---|---|
select | 保留手动选择 | 需要明确控制出口 |
url-test | 根据探测结果选择节点 | 从可用候选中自动选择 |
fallback | 按候选顺序选择可用节点 | 优先固定出口,失效后回退 |
load-balance | 按所选策略分配连接 | 在多个出口间分担请求 |
url-test 的结果反映的是访问指定测试地址的表现,不是下载带宽,也不是对所有目标服务的综合评分。tolerance 用于减少小幅差异引起的频繁切换,数值单位为毫秒;它不是固定延迟承诺。候选节点质量相近时,适当容忍差异通常比追求每一次最小测量值更有利于维持出口稳定。
fallback 以候选顺序表达偏好,前面的节点可用时优先使用,而不是总挑测试值最小的节点。load-balance 则根据配置的分配策略处理连接,并不把一条连接拆成多条线路来叠加带宽。涉及登录状态、地区识别或会话一致性的应用,要考虑多出口可能产生的影响,不宜只因名称中有负载均衡就默认启用。
探测地址、间隔与懒检测
测试地址应稳定、响应轻量,并且能代表需要观察的连通性。若某个节点不能访问测试站点,却可以访问实际目标,自动策略也可能将它判为不适合当前测试条件。反过来,测试通过也不代表所有服务可用。选择测试地址时要理解这种局限,而不是把它当作整个互联网的健康状态。出现误判时应对照实际目标请求和日志。
缩短 interval 会增加探测频率,也会消耗更多请求和设备资源,不会直接提升节点带宽。提供者健康检查与策略组测试同时存在时,还可能产生重复探测。某些组支持懒检测行为,在没有被使用时减少检查;因此刚切换到该组时看到的状态可能需要等待刷新。应根据使用习惯设置,而不是把所有间隔统一改成极小值。
筛选表达式与选择状态
通过 filter 或排除表达式筛选提供者节点时,要先确认名称中确实包含预期内容。正则表达式里的括号、竖线和特殊字符有各自含义,不能把普通描述直接当作可靠筛选条件。订阅改名后,组可能变为空组;修改筛选后应检查展开列表,而不是只看组标题仍然存在。空候选集合往往是自动组异常的重要线索。
如果客户端或配置启用了选择状态保存,重新加载配置后可能恢复上一次的手动选择;名称改变后又可能无法恢复。测试 YAML 列表顺序时,应先看当前实际选择,不要误认为首项永远生效。三种自动策略的细节和使用场景,可继续参阅url-test、fallback 与 load-balance 对照,再决定是否需要调整现有组。
规则语法与匹配顺序
规则列表是一个有顺序的决策过程。内核从前向后检查,命中后采用对应出口,因此同样一批规则换一个顺序,结果可能不同。书写规则时应先表达明确的例外,再放较宽的范围,最后添加兜底规则。不要把 MATCH 放在列表开头,然后期望后面的域名规则继续生效;兜底已经接收了未加限制的请求。
域名、后缀与关键词规则
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN-SUFFIX,example.org,出口选择
- DOMAIN-KEYWORD,example,出口选择
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- MATCH,出口选择
DOMAIN 匹配完整域名,适合表达单个主机例外;DOMAIN-SUFFIX 匹配域名本身及其子域范围;DOMAIN-KEYWORD 按包含关系匹配,范围更宽,也更容易命中无关服务。规则中的域名不应附带 https://、路径或查询参数,因为这里处理的不是完整网页地址。需要区分具体主机时,应优先使用范围明确的规则。
每条规则最后的目标必须是存在的节点、策略组或内置出口。中文逗号不能替代英文逗号,名称中的多余空格也会使引用难以核对。出现目标不存在时,不要只检查规则本身,还要确认前面的节点合并或组覆写是否改变了名称。对于经常更新的节点集合,指向稳定的策略组名称通常比直接指向单个节点更容易维护。
IP 规则与解析副作用
IP-CIDR 和 IP-CIDR6 按地址网段判断。若请求只携带域名,某些 IP 类规则可能需要先解析域名再判断。追加 no-resolve 可避免该条规则为了匹配而主动发起解析,但不能简单理解为忽略所有 IP 请求:当连接已经具有目标 IP 时,仍可能按该地址匹配。这个选项控制的是解析行为,不是直连或代理行为。
私有网段规则适合保护局域网访问,但实际网络还可能包含其他地址段和特殊路由。不要把一个宽泛公网网段全部设为直连,只因为某次查询发现目标使用其中一个地址。大型服务可能共享地址,解析结果也会随网络变化。能用明确域名表达的策略,通常比追随单次解析 IP 更稳定;必须按 IP 分流时,要理解网段范围和更新来源。
远程规则集与声明方式
rule-providers:
local-services:
type: file
behavior: domain
format: yaml
path: ./rules/local-services.yaml
rules:
- RULE-SET,local-services,DIRECT
- MATCH,出口选择
对应的规则文件采用下列结构。这里的 behavior: domain 表示载荷是域名匹配内容,不是完整的逐条规则语句。若提供者采用 classical,载荷格式与可用规则类型又有所不同。规则提供者的声明方式、文件格式和实际内容必须一致;文件扩展名相同不能证明内部结构相同,下载失败返回的网页也不能作为规则集加载。
payload:
- "+.example.org"
- "router.example.com"
规则集只保存匹配内容,实际采用哪个出口由主配置里的 RULE-SET 规则决定。一个规则集被加载成功,不代表其中每个域名都会采用预期出口:它前面的规则可能已经命中。更新规则集后,还要观察连接页显示的实际规则类型和目标。不要为了修复一个域名,把整套远程规则移到最前面,从而改变原本需要优先保留的局域网与业务例外。
连接复用与验证方法
修改规则通常影响新建立的连接,已有长连接、浏览器连接池和应用会话可能继续沿用原路径。验证时应关闭相关连接,再请求一个明确目标,同时观察匹配规则、策略组与最终节点。网页中一个页面可能访问多个域名,主文档、图片、登录和接口请求未必走同一路径;仅凭页面能否打开,无法判定每个子请求的策略都正确。
域名信息也不是在所有入口中都天然可见。应用直接连接 IP、使用自己的解析机制或复用先前连接时,规则可获得的信息可能不同。嗅探能力可以在适用场景补充域名,但不是完整网址识别,也不能保证从所有加密连接中恢复信息。排查应基于连接记录实际显示的元数据,不要假定内核已经看到浏览器地址栏中的全部内容。
配置覆写、合并与验证流程
覆写用于在保留订阅更新能力的同时,维持本地端口、DNS、规则或策略选择。关键不在于额外写了一份 YAML,而在于客户端如何把多个来源合成为最终配置。原始订阅、本地覆写、客户端偏好和运行时 API 修改可能处于不同层次。某个字段最后由谁决定,没有跨客户端通用答案,应以当前客户端的合并说明与实际生成结果为准。
标量、映射与列表的差别
标量字段通常表现为后者覆盖前者,例如混合端口从一个数值变为另一个数值。映射可能采用深度合并,也可能整段替换;列表则可能替换、前置、后置或通过专用脚本处理。不能把某个客户端的合并经验直接套到另一个客户端。尤其是规则列表,替换会丢失原规则,后置又可能落在 MATCH 后面,从而失去实际匹配机会。
| 字段形态 | 常见处理 | 需要核对 |
|---|---|---|
标量,如 mixed-port | 用新值覆盖 | 界面是否再次改写 |
映射,如 dns | 深合并或整体替换 | 原有子字段是否保留 |
列表,如 rules | 替换、前置或后置 | 兜底与自定义规则顺序 |
对象列表,如 proxy-groups | 按工具规则处理 | 是否按名称匹配,是否重名 |
把订阅内容与本机差异分开
节点凭据和远程节点集合适合跟随可信订阅更新,监听端口、局域网权限和本机 DNS 例外适合保存在本地。不要直接修改一次性下载的缓存文件,再期待下次更新保留修改。也不要把当前设备的网卡名称、绝对路径和本地监听地址同步到全部设备;不同操作系统与客户端的数据目录、权限机制和支持字段并不相同。
# 本地字段片段;合并方式以客户端说明为准
mixed-port: 7890
allow-lan: false
log-level: info
profile:
store-selected: true
这段示例只表达希望保留的本地字段,不定义规则合并算法。profile.store-selected 用于保存策略组选择,和客户端保存订阅文件不是同一件事。若客户端已有对应设置,应确认界面生成值与覆写值谁优先。多个位置同时维护相同字段,容易出现编辑器里是一种值、界面又显示另一种值的情况,增加后续排错成本。
最终配置检查与最小修改
开始修改前,先导出或备份当前可用配置,并记录使用的客户端、内核类型和关键开关。修改后查看最终运行配置,核对目标字段有没有出现、是否被另一层覆盖、引用的组名是否仍然存在。原始订阅没有变化而运行配置变化,是正常的生成过程;原始文件修改成功但运行配置没变,则可能编辑了错误对象,或者尚未触发重新生成。
验证可分为四层:先做 YAML 语法和内核加载检查,再确认本地端口监听,然后测试一个明确的代理请求,最后观察规则与最终出口。每一层都有不同证据。语法通过不能证明节点可达,节点可达不能证明系统代理已设置,浏览器可用也不能证明终端走代理。只有逐层闭环,才不会在错误的配置区域持续尝试。
mihomo -t -f ./config.yaml
lsof -nP -iTCP:7890 -sTCP:LISTEN
curl --proxy http://127.0.0.1:7890 -I https://example.com
命令行测试应与客户端实际环境对照。独立内核的工作目录、规则缓存与权限可能不同,不能只因为独立测试成功就排除客户端生成问题。重新加载配置后,关注日志中的解析失败、对象缺失和监听失败,并优先处理最早出现的明确错误。后续大量连接失败常常只是前面一个加载错误的结果,不宜逐条作为独立网络故障处理。
回滚、共享与常见问题
如果修改导致连接中断,先恢复上一份可用配置,关闭新加的覆写,再逐项重新引入差异。保留原订阅,不要用临时测试文件覆盖唯一副本。跨设备同步时,只共享确实通用的内容,将本地路径、网络接口和设备专属规则留在设备侧;订阅地址和节点密码应放在受控存储中。具体方案见多设备配置同步说明。
修改 YAML 后,客户端为什么仍使用旧端口?
订阅更新后,自定义规则为什么消失?
同一份配置可以在所有 Clash 客户端中直接使用吗?
维护配置的目标是让每个字段都有明确来源、每条规则都有可解释的顺序、每次变更都有可回退的基线。遇到问题先缩小范围,再增加细节。需要重新安装或比较客户端时使用下载页;需要按顺序完成导入、模式选择和连接验证时返回快速上手教程,避免把查阅手册当成必须一次启用全部字段的清单。