配置文件的结构总览
Clash 系客户端的全部运行行为,由一份 YAML 格式的配置文件决定。订阅链接导入后,客户端从订阅地址取回的本质上也是这份文件;界面上切换节点、调整模式、增删规则,最终都会落回文件中的对应字段。把这份文件读通,客户端的每一项界面操作也就都有了着落。
文件通常命名为 config.yaml,存放在客户端的配置目录中。Clash Plus、Clash Verge Rev、FlClash 等图形客户端会代为管理这份文件的读写:导入订阅时生成,切换选项时改写。手工编辑之前,建议先退出客户端,或先确认该客户端的覆写策略,否则刚改好的内容可能被界面操作整份覆盖。覆写机制的详细说明见本页第 8 章。
顶层字段一览
一份完整配置的顶层由若干字段并列组成,字段之间没有先后依赖,书写顺序不影响解析。常用字段及其职责如下:
| 字段 | 类型 | 职责 |
|---|---|---|
| port / socks-port / mixed-port | 整数 | 本地监听端口,分别对应 HTTP、SOCKS5 与混合代理入口 |
| mode | 字符串 | 代理模式:rule 按规则分流、global 全局代理、direct 全部直连 |
| log-level | 字符串 | 日志输出级别,排错时临时调到 debug |
| dns | 映射 | 内置 DNS 的开关、上游与解析模式 |
| proxies | 列表 | 代理节点定义,逐项写出一个节点 |
| proxy-groups | 列表 | 策略组,把节点组织成可选择的集合 |
| rules | 列表 | 分流规则,自上而下逐条匹配 |
| proxy-providers | 映射 | 订阅来源,节点列表的外部提供方 |
| rule-providers | 映射 | 规则集来源,规则的外部提供方 |
| external-controller | 字符串 | 外部控制接口的监听地址,供面板与 API 使用 |
一份最小可用配置只需要三类内容:监听端口、至少一个节点、至少一条规则。其余字段均有默认值,缺省时内核按默认行为运行。订阅转换服务生成的配置往往字段齐全,手工精简时保留主干即可,不必逐项照搬。
YAML 语法的四条底线
YAML 的解析规则严格,绝大多数"配置无法启动"都源于格式问题而非内容问题。书写时守住四条底线:
- 缩进只用空格,不用 Tab;同一层级的缩进宽度必须一致,通行约定是两格。
- 键与值之间用半角冒号加一个空格分隔,写成
key: value;冒号后漏空格是高频错误。 - 列表项以半角连字符加空格开头;连字符顶格或缩进均可,但同一份文件里要统一风格。
- 值中含冒号、井号、花括号等特殊字符时,整个值用英文双引号包起;密码、令牌类字段建议一律加引号。
config.yaml · 最小骨架
mixed-port: 7890
mode: rule
log-level: info
proxies:
- name: "节点甲"
type: ss
server: ss.example.com
port: 8388
cipher: aes-128-gcm
password: "your-password"
rules:
- MATCH,节点甲
这份骨架只有九行,已经是一份可启动的配置:本地 7890 端口接收代理请求,所有流量经唯一节点转发。实际订阅配置在此基础上扩充节点、策略组与规则,骨架结构不变。后续章节逐一展开每个部分的字段细节。
通用字段:端口、模式与开关
顶层通用字段控制内核的整体行为:在哪个端口接收请求、按什么策略分流、日志写到什么程度、是否允许局域网共享。图形客户端大多把这些字段映射成设置页里的开关,手工编写时按本节对照即可。
监听端口
port 是 HTTP 代理端口,socks-port 是 SOCKS5 端口,mixed-port 是混合端口,同一个入口同时接受 HTTP 与 SOCKS5 两种连接。目前客户端普遍只暴露混合端口,系统代理与浏览器插件都指向它。三个字段可以并存,端口互不冲突即可;不需要的入口整行省略,内核便不监听对应端口。
redir-port 与 tproxy-port 服务于 Linux 透明代理,配合 iptables 转发使用,桌面用户一般用不到,路由器与网关场景才会启用。相关部署流程见 Linux 命令行部署 一文。
运行模式
mode 取三个值之一:rule 按规则列表分流,是日常使用模式;global 把全部流量交给名为 GLOBAL 的内置策略组,即界面上的"全局模式";direct 全部直连,等于暂停代理。界面上切换模式只是改写这个字段并热加载,配置文件里的初值决定每次启动时的默认模式。
日志与外部控制
log-level 从安静到啰嗦依次为 silent、error、warning、info、debug。日常用 warning 或 info;排查规则命中问题时临时调到 debug,能看到每条连接的匹配过程与命中结果。
external-controller 指定外部控制接口的监听地址,图形客户端的连接面板、延迟测试、配置热加载都走这个接口。external-ui 指向一套静态面板文件,浏览器打开对应地址即可直接管理内核;secret 是接口的访问密钥,为空表示不校验。
局域网共享与其他开关
allow-lan 置 true 后,同一局域网的设备可以把本机作为代理网关;bind-address 限定监听网卡,默认 * 表示全部网卡。其余常用开关:ipv6 控制是否解析与转发 IPv6;unified-delay 让延迟测试统一从握手完成计时,不同协议间的测速结果才有可比性;tcp-concurrent 让候选节点并发建连取最快;profile.store-selected 记住各策略组的手动选择,重启后不回弹到默认节点。
| 字段 | 常见取值 | 说明 |
|---|---|---|
| mixed-port | 7890 | 混合代理入口,桌面客户端的默认约定 |
| mode | rule | rule / global / direct 三选一 |
| log-level | warning | 排错时临时改为 debug |
| allow-lan | false | 共享给局域网设备时置 true |
| external-controller | 127.0.0.1:9090 | 仅本机访问;改 0.0.0.0 必须配 secret |
| unified-delay | true | 统一测速口径 |
| tcp-concurrent | true | 候选节点并发建连 |
| profile.store-selected | true | 记住策略组的手动选择 |
config.yaml · 通用字段示例
mixed-port: 7890
allow-lan: false
bind-address: "*"
mode: rule
log-level: warning
ipv6: false
external-controller: 127.0.0.1:9090
secret: ""
unified-delay: true
tcp-concurrent: true
profile:
store-selected: true
store-fake-ip: false
控制接口的边界:external-controller 绑定 127.0.0.1 时只接受本机连接;一旦改成 0.0.0.0,局域网内任何机器都能读取配置、切换节点,务必同时设置 secret,并只在可信网络中这样做。
DNS 字段:解析行为与上游
分流规则依赖域名与 IP 的对应关系,DNS 配置决定域名在何时、由哪台上游解析,是规则能否正确命中的前提。配置不当的典型症状是:该走代理的站点被判成直连,或打开网页前有明显停顿。
基本开关
dns.enable 是整段的总开关,缺省为 false,此时内核把域名解析交给系统,本节其余字段全部不生效。listen 指定内置 DNS 服务的监听地址,配合 TUN 模式或把系统 DNS 指向本机时使用;ipv6 控制是否应答 AAAA 查询。
解析模式:fake-ip 与 redir-host
enhanced-mode 取 fake-ip 或 redir-host。fake-ip 模式下,内核收到域名查询后直接返回 fake-ip-range 段内的虚拟地址(默认 198.18.0.1/16),应用拿着虚拟地址发起连接,内核在连接到来时再查表还原域名、按规则分流并解析真实 IP。这一安排省掉了应用侧的解析等待,也避免系统 DNS 的污染结果把分流带偏。redir-host 是传统模式:先代理解析出真实 IP 再交给应用,兼容性最好,速度略慢。
fake-ip-filter 列出不应返回虚拟地址的域名,命中这些域名时走真实解析。局域网域名、时间服务器、需要真实 IP 做服务发现的协议都应列入,否则会出现找不到局域网设备、系统时间无法同步一类怪象。
上游服务器
default-nameserver 负责解析"DNS 服务器自己的域名"——例如上游写成 dns.alidns.com 这类域名形式时,得先有一台纯 IP 的上游把它解析出来,因此这一层必须填 IP。nameserver 是主上游列表,支持 UDP、TLS、HTTPS 三种写法。fallback 是备用上游,在判定需要经代理解析时使用。nameserver-policy 按域名或 GEOSITE 分类指定专用上游,例如把国内域名固定交给运营商 DNS、把特定服务交给加密上游,颗粒度比 fallback 更细。
config.yaml · DNS 段示例
dns:
enable: true
listen: 0.0.0.0:53
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- "*.lan"
- "*.local"
- "time.*.com"
- "ntp.*.com"
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
fallback:
- https://1.1.1.1/dns-query
- tls://8.8.4.4
图形客户端的默认值:Clash Plus、Clash Verge Rev、FlClash 都内置了一套 DNS 默认配置,日常使用无需改动。手工编写整份配置时,enable 必须显式写 true;只写上游不写开关,是手工配置最常见的疏漏。
代理节点字段
proxies 是节点列表,列表中每一项描述一个出站节点。四个字段是任何协议的底线:name 节点名、type 协议类型、server 服务器地址、port 服务器端口。其余字段随协议而定。订阅导入的节点已由订阅方生成,手工场景主要是新增备用节点与微调个别字段。
公共字段
name 在整份配置里必须唯一,策略组靠名字引用节点,重名会让引用结果不可预期。udp 控制该节点是否转发 UDP 流量,语音通话、部分游戏与 QUIC 协议依赖它。sni 指定 TLS 握手时声明的域名,多数节点要求与节点域名一致;skip-cert-verify 置 true 跳过证书校验,只应在自签证书的测试环境使用。alpn 与 client-fingerprint 微调 TLS 指纹;dialer-proxy 指定前置节点,把本节点串在另一个节点之后,构成链式中转。
各协议写法
config.yaml · 四种协议的节点示例
proxies:
- name: "SS 节点"
type: ss
server: ss.example.com
port: 8388
cipher: aes-128-gcm
password: "your-password"
udp: true
- name: "VMess 节点"
type: vmess
server: vm.example.com
port: 443
uuid: 00000000-0000-0000-0000-000000000000
alterId: 0
cipher: auto
tls: true
servername: vm.example.com
network: ws
ws-opts:
path: /ray
headers:
Host: vm.example.com
- name: "Trojan 节点"
type: trojan
server: tj.example.com
port: 443
password: "your-password"
sni: tj.example.com
skip-cert-verify: false
- name: "Hysteria2 节点"
type: hysteria2
server: hy2.example.com
port: 443
password: "your-password"
sni: hy2.example.com
skip-cert-verify: false
各协议的必填字段与扩展项差异较大,下表列出常见协议的核对清单。字段名拼写错误时,内核会在启动校验阶段报出具体行号,报错定位方法见第 9 章。
| 协议 type | 必填字段 | 常见扩展字段 |
|---|---|---|
| ss | server、port、cipher、password | plugin、plugin-opts、udp |
| ssr | server、port、cipher、password、protocol、obfs | protocol-param、obfs-param |
| vmess | server、port、uuid、alterId、cipher | tls、network、ws-opts、servername |
| vless | server、port、uuid | flow、tls、reality-opts、network |
| trojan | server、port、password | sni、alpn、network、grpc-opts |
| hysteria2 | server、port、password | sni、obfs、up、down |
| tuic | server、port、uuid、password | congestion-controller、alpn |
订阅导入后如需核对节点字段,可在客户端的配置预览里查看解析结果:传输层(network)、TLS 开关与 SNI 是否齐全,决定了节点能否通过启动校验。手工新增节点时,建议先只写必填字段跑通连接,再逐项补充扩展字段,出问题时的定位范围会小得多。
策略组字段
proxy-groups 把节点组织成可选择的集合。分流规则的目标一般不直接写节点名,而是写策略组名:规则决定"流量交给哪个组",组决定"组里当前用哪个节点"。两层解耦之后,换节点不用动规则,改规则不用动节点。
组类型与选择方式
| 类型 | 选择方式 | 适用场景 |
|---|---|---|
| select | 手动选择,界面上的下拉列表 | 主策略组、需要人判断的分流出口 |
| url-test | 定时测速,自动选用延迟最低者 | 同地区多节点的自动择优 |
| fallback | 按列表顺序取第一个可用节点 | 主备切换,稳定性优先 |
| load-balance | 按连接在组内成员间分散 | 多线分担大流量 |
| relay | 按列出顺序把节点串成链路 | 固定的多层中转 |
测速字段
url-test、fallback、load-balance 三类组依赖健康检查。url 是测速目标地址,默认 http://www.gstatic.com/generate_204,返回 204 即视为可用;interval 是测速间隔秒数,过密会空耗节点流量;tolerance 是延迟容差毫秒数,新旧最优差距小于此值时不切换,避免节点来回跳动;lazy 置 true 表示组内无连接时暂停测速,适合挂多组备用链路的配置。
组成员的来源
proxies 字段直接列出成员名,可以是节点名,也可以是另一个策略组名——组允许嵌套,界面上"节点选择"组里套一个"自动选择"组是常见写法。use 字段引用 proxy-providers 中声明的订阅,把订阅里的全部节点纳入组内;配合 filter 正则只保留名字匹配的节点,exclude-filter 则反向排除。
config.yaml · 策略组示例
proxy-groups:
- name: "PROXY"
type: select
proxies:
- "自动选择"
- "手动节点甲"
- "手动节点乙"
- DIRECT
- name: "自动选择"
type: url-test
use:
- mysub
filter: "香港|台湾"
url: http://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
- name: "广告拦截"
type: select
proxies:
- REJECT
- DIRECT
DIRECT 与 REJECT 是内核内置的两个出站,无需在 proxies 里定义:DIRECT 表示直连,REJECT 表示直接拒绝连接,常用于广告与追踪域名拦截。
组嵌套时,界面展示的是最外层组,内层组的当前选择会作为外层组的一个成员出现。把"自动选择"嵌进 PROXY 之后,日常只需在 PROXY 里保持选中它,测速与切换都由内层组完成;需要指定节点时,再在外层临时改选,规则列表全程不用动。
规则语法与匹配顺序
rules 是分流的核心。每条连接建立时,内核从列表第一条开始逐条比对,命中即按该条指定的策略组出站,不再继续向下;全部未命中时由最后的 MATCH 兜底。顺序就是优先级,写规则的一半功夫花在排顺序上。
规则的三段结构
一条规则由逗号分成三段:类型、匹配内容、目标策略组,例如 DOMAIN-SUFFIX,example.com,PROXY。IP 类规则允许追加第四段 no-resolve:默认情况下,拿域名连接去比对 IP 规则会先触发一次解析;加了 no-resolve 的 IP 规则只匹配本身就是 IP 的连接,不为它去解析域名,既省 DNS 请求,也避免解析结果干扰分流。GEOIP 与 IP-CIDR 规则惯例上都带这个后缀。
规则类型速查
| 类型 | 匹配对象 | 示例 |
|---|---|---|
| DOMAIN | 完整域名,精确相等 | DOMAIN,api.example.com,PROXY |
| DOMAIN-SUFFIX | 域名后缀,含子域 | DOMAIN-SUFFIX,google.com,PROXY |
| DOMAIN-KEYWORD | 域名中任意片段 | DOMAIN-KEYWORD,telegram,PROXY |
| GEOSITE | 域名分类库 | GEOSITE,cn,DIRECT |
| IP-CIDR / IP-CIDR6 | IPv4 / IPv6 网段 | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve |
| GEOIP | IP 归属地 | GEOIP,CN,DIRECT,no-resolve |
| SRC-IP-CIDR | 连接来源的 IP 段 | SRC-IP-CIDR,192.168.1.0/24,DIRECT |
| DST-PORT / SRC-PORT | 目标 / 来源端口 | DST-PORT,22,DIRECT |
| PROCESS-NAME | 发起连接的进程名 | PROCESS-NAME,chrome.exe,PROXY |
| RULE-SET | 外部规则集 | RULE-SET,ads,REJECT |
| MATCH | 兜底,匹配一切 | MATCH,PROXY |
排序的实战含义
例外规则写在大范围规则之前:想让某个站点强制直连,它的 DOMAIN-SUFFIX 必须排在 GEOSITE、GEOIP 这类大范围条目之上,否则流量在到达它之前已被前面的条目截走。范围越小的规则越靠前,范围越大的越靠后,MATCH 永远在最后。进程类规则依赖系统进程信息,Windows 桌面端可用,移动端内核通常取不到进程名,写了也不会命中。
config.yaml · 规则列表示例
rules:
- DOMAIN-SUFFIX,internal.example.com,DIRECT
- RULE-SET,ads,REJECT
- GEOSITE,private,DIRECT
- GEOSITE,google,PROXY
- GEOSITE,cn,DIRECT
- GEOIP,private,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- MATCH,PROXY
规则数量与开销:逐条匹配意味着规则越多,每条连接的比对成本越高。日常配置建议控制在数百条以内;上万条的分流需求交给第 7 章的规则集,内核会为规则集建立索引,匹配开销与规则总数基本无关。
配置提供方:订阅与规则集
节点与规则都可以从主配置里拆出去,交给"提供方"管理:主配置只声明来源与更新方式,内容由客户端定时拉取。订阅链接导入后生成的正是 proxy-providers 条目;规则集则把成千上万条分流规则压缩成一次引用。
proxy-providers 订阅来源
每个订阅是一个命名条目。type 取 http(远程拉取)或 file(本地文件);url 是订阅地址;path 是本地缓存路径,断网时用缓存启动;interval 是自动更新间隔秒数。health-check 子段为整个订阅的节点统一开启测速,字段与策略组的测速字段相同。override 子段可以统一改写订阅内节点的字段,例如强制开启 UDP。
rule-providers 规则集来源
规则集的关键字段是 behavior:domain 表示条目按域名后缀匹配,ipcidr 表示按 IP 网段匹配,classical 表示条目本身是完整规则(带类型前缀)。前两种内核会构建专用索引,匹配极快,但文件里只能写纯粹的域名或网段列表。format 支持 yaml 与 text 两种文件格式。
config.yaml · 提供方示例
proxy-providers:
mysub:
type: http
url: "https://example.com/sub?token=xxxx"
path: ./providers/mysub.yaml
interval: 86400
health-check:
enable: true
url: http://www.gstatic.com/generate_204
interval: 300
rule-providers:
ads:
type: http
behavior: domain
format: yaml
url: "https://example.com/rules/ads.yaml"
path: ./providers/ads.yaml
interval: 86400
声明之后还要引用才生效:策略组里用 use: [mysub] 纳入订阅节点,规则列表里用 RULE-SET,ads,REJECT 挂上规则集。订阅链接的获取与格式转换,见 订阅导入一文。
内联与提供方两种写法可以混用:proxies 里手工维护一两个备用节点,proxy-providers 管订阅的大批节点,策略组把两者同时列入。更新订阅只影响提供方条目,手工节点不受波及——这也是比"全部写进 proxies"更稳的组织方式。
覆写与合并
订阅更新的本质是整份替换:客户端拉取新配置,旧文件连同手工改动一起被覆盖。要长期保住自己的修改,有两条路——用客户端提供的覆写机制把改动做成"补丁",或者利用 YAML 的锚点语法减少重复、降低维护成本。
客户端的覆写机制
主流图形客户端都把"订阅原文"与"用户改动"分层保存。Clash Verge Rev 提供全局扩展配置(Merge)与脚本两种覆写入口,前者按字段合并,后者用 JavaScript 自由改写;FlClash 在覆写页中增删改任意字段;Clash Plus 把界面设置与订阅配置分开存放,更新订阅时设置项自动保留。共同点是订阅文件保持原样,用户改动以补丁形式叠加,每次更新后重新套用。
需要留意的是合并语义因客户端而异:标量字段(端口、模式)一律以补丁为准;数组字段(rules、proxies)有的客户端按条目合并,有的整段替换,有的支持前插后插。改动生效后,最稳妥的确认方式是导出客户端最终生成的运行配置,核对目标字段是否如愿,而不是只看覆写页里的补丁文本。
YAML 锚点与引用
手写配置时,锚点能消除重复:在值前写 &名字 定义锚点,之后用 *名字 原样引用;映射类型还可用 <<: *名字 把锚点的键值合并进来。多个策略组共用同一份节点列表、同一组测速参数时,锚点让配置只维护一份真源,改一处即全改。
config.yaml · 锚点复用示例
proxy-groups:
- name: "自动选择"
type: url-test
url: &test-url http://www.gstatic.com/generate_204
interval: &test-interval 300
proxies: &all-nodes
- "节点甲"
- "节点乙"
- "节点丙"
- name: "备用链路"
type: fallback
url: *test-url
interval: *test-interval
proxies: *all-nodes
锚点被展开是正常现象:部分客户端导入配置时会先解析成内部结构再重新序列化,锚点在落盘时被展开成重复内容。运行行为完全一致,只是文件变长,无须处理。
校验与排错
配置问题集中在三类:YAML 格式错误、字段引用错误、规则逻辑与预期不符。按本节的顺序排查,绝大多数问题能在几分钟内定位。
启动前校验
mihomo 内核自带配置检查,不必启动即可验证:
终端 · 配置校验命令
mihomo -t -d /path/to/config-dir
输出 configuration ok 表示语法与字段检查通过;失败时报错会带行号与字段名,按提示回到对应章节核对。图形客户端在导入或保存配置时也会做同样的校验,报错弹窗的文字与命令行一致。
高频错误对照
| 报错片段 | 原因 | 处理 |
|---|---|---|
| mapping values are not allowed | 值里出现第二个冒号,解析器误判为新键 | 给整个值加英文双引号 |
| found character '\t' | 缩进里混入了 Tab | 全文替换为空格缩进 |
| proxy not found | 策略组或规则引用了不存在的名字 | 核对 proxies 与组的 name 拼写 |
| rules[N] error | 第 N 条规则段数不对或类型拼错 | 对照第 6 章速查表逐段检查 |
| field not found | 字段名拼写错误或层级放错 | 对照第 1 章顶层字段表 |
不重启让改动生效
图形客户端保存配置即触发热加载,无须重启内核。命令行场景可以请求外部控制接口:向 /configs?force=true 提交 PUT 并带上新配置路径即整体重载;fake-ip 缓存导致的解析残留,可清空对应缓存接口后重试。规则命中与预期不符时,把 log-level 临时调到 debug,日志会逐条打印每条连接命中的规则序号,对照序号回到 rules 列表即可看出是哪一条截了流量。
排错的一般顺序
遇到「改了配置没效果」时,建议按固定顺序排查,而不是反复重写整份文件。第一步确认改动确实已加载:图形客户端看配置页的生效时间,命令行看热加载接口的返回;第二步确认流量确实经过内核:系统代理或 TUN 是否开启,目标应用是否绕开了系统代理设置;第三步才回到规则本身,用 debug 日志观察命中序号。三步走下来,问题落在哪一层一目了然,再对照前面章节修改对应字段即可。还有一个容易被忽略的点是缓存:浏览器、系统代理解析结果与 fake-ip 缓存都可能让旧行为延续几分钟,改动后先清缓存或换隐私窗口验证,能避免把缓存现象误判为配置错误。
配置之外的问题——订阅导入失败、系统代理不生效、开机自启等——已在 新手十问 中逐条解答;上手主线见 使用文档,客户端安装包见 下载页。