一、YAML 结构总览
Clash 的全部行为由一份 YAML 格式的配置文件驱动。客户端界面上的每一个开关、每一个策略组、每一条分流规则,最终都对应这份文件里的某个字段。理解它的整体结构,是后续所有修改动作的前提:知道一个字段属于哪一段,才知道改动会影响什么、会不会被订阅更新覆盖。
一份完整配置在顶层由若干个固定名称的段落组成,内核按名称识别,顺序不影响解析。常用段落如下:
- 通用字段:散落在顶层的标量配置,如
mixed-port、mode、log-level,控制端口、代理模式与运行参数; dns:域名解析行为,包括是否启用内置 DNS、Fake-IP 模式与上游服务器列表;proxies:代理节点数组,每个条目描述一个出口服务器的协议、地址与凭据;proxy-groups:策略组数组,把节点组织成可选择、可自动测速的分组;rules:分流规则数组,决定每一条连接走哪个策略组或直连;proxy-providers/rule-providers:从外部地址或本地文件引入节点与规则集,便于拆分维护;tun:虚拟网卡模式,接管系统全局流量时使用。
一份能跑起来的最小配置只需要三段:一个入站端口、至少一个节点(或直接用 DIRECT)、一条兜底规则。下面的骨架可以直接保存为 config.yaml 验证:
mixed-port: 7897
mode: rule
log-level: info
proxies: []
proxy-groups: []
rules:
- MATCH,DIRECT
YAML 有几条硬性的书写约定,配置解析失败的多数原因都出在这里。第一,层级完全由缩进表达,同一层级的缩进宽度必须一致,惯例是两个空格;第二,冒号后面必须有一个空格,mode:rule 是非法写法;第三,字段名区分大小写,Mode 不会被识别为 mode;第四,字符串一般可以不加引号,但含有冒号、井号、星号等特殊字符时必须用引号包裹,例如密码 "p@ss:word#1"。
禁止使用 Tab 缩进
YAML 规范不接受制表符缩进,内核会直接报 found a tab character that violates indentation 并拒绝加载。用记事本、vim 等编辑器修改配置前,先确认编辑器把 Tab 键映射为空格;从网页复制粘贴的片段也要检查行首是否混入了制表符。
关于配置文件的存放位置与订阅更新时哪些段会被整体替换,可参阅站内文章《Clash 配置文件(Profile)结构解析》,本页第八章也会给出让本地改动在更新后存活的合并方案。
二、通用字段:端口、模式与运行控制
通用字段直接写在配置顶层,控制内核以什么姿态运行。它们数量不多,但几乎每一次排错都要先核对这一段——端口冲突、模式选错、局域网设备连不上,根源都在这里。
2.1 入站端口
内核可以同时开启多种入站监听。port 是纯 HTTP 代理端口,socks-port 是纯 SOCKS5 端口,而 mixed-port 在同一个端口上同时识别 HTTP 与 SOCKS5 请求,是目前多数客户端的默认选择——系统代理和第三方软件都指向同一个端口,配置最简单。三者可以并存,但监听端口号不能重复,也不能与系统上其他程序占用的端口冲突;启动时报 bind: address already in use,就是端口被占,换一个未使用的端口号即可。
2.2 局域网访问
allow-lan 决定入站端口是否接受来自本机以外的连接。设为 true 后,同一局域网内的手机、电视盒子可以把代理服务器指向这台机器的内网 IP,共享同一套出口与规则;配合 bind-address 可以限定只在某块网卡上监听。开启前注意所处网络环境:在公司或公共 Wi-Fi 上开放局域网监听,意味着同网段任何设备都能使用这个代理端口。
2.3 代理模式 mode
mode 接受三个值:rule(按规则段逐条匹配分流)、global(所有流量交给全局出口)、direct(所有流量直连)。日常应固定停留在 rule,另外两个模式是排查工具而非常驻选项——什么时候临时切换、切换后如何验证,站内文章《Clash 三种代理模式怎么选》有完整的操作顺序说明。
2.4 常用通用字段速查
| 字段 | 类型 / 取值 | 说明 |
|---|---|---|
| mixed-port | 1-65535 | HTTP 与 SOCKS5 混合入站端口,推荐作为唯一入站 |
| allow-lan | true / false | 是否允许局域网设备接入本机代理端口 |
| bind-address | IP / "*" | 监听地址,配合 allow-lan 限定网卡 |
| mode | rule / global / direct | 代理模式,日常保持 rule |
| log-level | silent / error / warning / info / debug | 日志级别,排错时临时调到 debug |
| ipv6 | true / false | 是否处理 IPv6 流量,网络环境不支持时关闭可减少解析噪音 |
| external-controller | IP:端口 | RESTful 控制接口地址,客户端面板依赖它读写内核状态 |
| secret | 字符串 | 控制接口的访问令牌,开放局域网时务必设置 |
external-controller 值得单独解释:它开放一个 HTTP 接口,客户端图形界面正是通过这个接口切换节点、读取延迟与流量数据。默认绑定 127.0.0.1:9090 只对本机开放;如果改成 0.0.0.0:9090 供局域网面板访问,必须同时配置 secret,否则同网段设备可以直接操纵内核。
2.5 TUN 段速览
系统代理只对遵守代理设置的应用生效,命令行工具、游戏与部分客户端软件会绕过它。tun 段通过创建虚拟网卡在网络层接管全部流量,解决"设了代理但某个程序不走"的问题:
tun:
enable: true
stack: system
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
stack 指定协议栈实现(system / gvisor / mixed),兼容性问题可在几种取值间切换对比;auto-route 自动写系统路由表;dns-hijack 把发往 53 端口的明文 DNS 查询劫持到内置 DNS,配合下一章的配置避免解析绕过。启用 TUN 需要管理员或 root 权限,各客户端会引导安装对应的系统服务。
三、DNS 段:解析行为与 Fake-IP
代理场景下 DNS 是最容易被忽视的一环:如果域名解析仍然走本地运营商的明文 53 端口,即使流量本身走了代理,访问了哪些域名依然会暴露在本地链路上,部分域名还会被解析到污染地址导致连接失败。dns 段的作用就是让内核接管解析过程,统一决定"由谁解析、怎么解析、解析结果怎么用"。
3.1 基础开关与监听
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
enable: true 启用内置 DNS 模块;listen 让它同时作为一个普通 DNS 服务器对外提供解析,主要配合 TUN 的 dns-hijack 或路由器场景使用。enhanced-mode 是这一段的核心选择,决定解析结果的呈现方式。
3.2 Fake-IP 与 Redir-Host
fake-ip 模式下,内核不等待真实解析完成,而是立刻从 fake-ip-range 保留网段(默认 198.18.0.1/16)分配一个虚拟地址返回给应用,同时记住"这个虚拟地址对应哪个域名";应用拿着虚拟地址发起连接时,内核按域名而非 IP 匹配规则并转发。好处是省掉一次解析往返、显著降低首包延迟,且规则匹配始终基于域名,准确度高。redir-host 则返回真实解析结果,行为更接近传统 DNS,兼容性好但速度与匹配精度略逊。两种模式的机制差异、以及局域网服务和游戏联机等需要回避 Fake-IP 的场景,站内文章《Clash Fake-IP 模式工作原理》有专门拆解。
使用 Fake-IP 时,某些必须拿到真实 IP 的查询要通过 fake-ip-filter 排除,典型的有局域网主机名、系统联网检测域名与 NTP 服务:
fake-ip-filter:
- "*.lan"
- "+.local"
- "+.msftconnecttest.com"
- "+.pool.ntp.org"
其中 * 匹配单级子域,+ 匹配任意多级子域并包含域名本身。
3.3 上游服务器的三层结构
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
geoip-code: CN
三组服务器职责不同,不能混为一谈。default-nameserver 只能填纯 IP,专门用来解析后面两组加密 DNS 服务器自身的域名,解决"先有鸡还是先有蛋"的问题;nameserver 是主力解析组,推荐使用 DoH(https:// 前缀)或 DoT(tls:// 前缀)等加密协议;fallback 是备用组,与 fallback-filter 联动——当主力组的解析结果命中过滤条件(如 geoip-code: CN 之外的结果),就改用备用组的答案,以此对抗污染。若不需要这套双查询机制,可以只保留 nameserver 一组。
DNS 泄漏自查
系统代理模式下,应用的 DNS 查询不一定经过内核;只有 TUN 模式配合 dns-hijack,或应用本身通过代理端口发起连接时,解析才会被完整接管。如果泄漏检测工具显示出口是运营商 DNS,优先检查是否启用了 TUN、dns 段的 enable 是否为 true。更多判断方法见常见问题页的故障排查分类。
四、代理节点字段(proxies)
proxies 是一个数组,每个条目完整描述一个出口节点。订阅配置里这一段由服务商生成,通常不需要手写;但在自建节点、给订阅补充私有出口、或对照排查"某个节点为什么连不上"时,需要能读懂每个字段的含义。
4.1 所有协议共有的字段
无论哪种协议,四个字段必不可少:name(节点名,策略组通过它引用,同一配置内不能重名)、type(协议类型)、server(服务器域名或 IP)、port(服务端口)。此外 udp: true 声明该节点支持 UDP 转发,语音通话、游戏等依赖 UDP 的应用需要它。
4.2 三种常见协议示例
proxies:
- name: "HK-01"
type: ss
server: hk01.example.com
port: 8388
cipher: aes-256-gcm
password: "your-password"
udp: true
- name: "JP-01"
type: vmess
server: jp01.example.com
port: 443
uuid: 0f7b7c4e-3a52-4e70-9d2b-1c8a5f6e0d43
alterId: 0
cipher: auto
tls: true
network: ws
ws-opts:
path: /ws
headers:
Host: jp01.example.com
- name: "US-01"
type: trojan
server: us01.example.com
port: 443
password: "your-password"
sni: us01.example.com
udp: true
Shadowsocks(ss)的关键字段是 cipher 加密方法与 password,两端必须完全一致。VMess 用 uuid 做身份凭据,alterId 在现行协议下固定为 0;network 声明传输层(ws、grpc、http 等),选了哪种传输层就配套哪个 *-opts 子段,示例中的 ws-opts 指定 WebSocket 的路径与 Host 头。Trojan 天然运行在 TLS 之上,sni 指定握手时声明的服务器名,与服务端证书不匹配会直接连接失败。
mihomo 内核在这三类之外还支持 vless、hysteria2、tuic、wireguard 等协议,字段结构遵循同样的模式:公共四字段加协议专属字段。拿到一个新协议节点时,先确认 type 拼写与内核支持列表一致,再逐个补协议要求的凭据字段。
慎用 skip-cert-verify
TLS 类节点(vmess+tls、trojan、vless 等)支持 skip-cert-verify: true 跳过证书校验。它只应作为排查证书问题时的临时手段,长期开启等于放弃对服务器身份的验证,中间人可以伪装成节点服务器。生产配置里如非服务商明确要求,保持默认的校验开启。
五、策略组字段(proxy-groups)
如果说 proxies 是原材料,proxy-groups 就是把原材料组织成"可决策单元"的一层。规则段的出口几乎总是指向策略组而不是单个节点——这样换节点时只需要在组内切换,规则不用动。客户端主界面上的分组选择列表,就是这一段的可视化。
5.1 四种组类型
| 类型 | 行为 | 典型用途 |
|---|---|---|
| select | 手动选择,保持用户上次的选择 | 顶层总开关组、按用途分类的业务组 |
| url-test | 定期测延迟,自动选用最快节点 | 不想手动挑节点的"自动"组 |
| fallback | 按列表顺序取第一个可用节点,失效自动后移 | 主备结构:优先固定主力,故障时兜底 |
| load-balance | 按策略把连接分散到多个节点 | 多节点分摊并发,降低单点压力 |
5.2 完整示例与参数说明
proxy-groups:
- name: "节点选择"
type: select
proxies:
- 自动测速
- HK-01
- JP-01
- US-01
- DIRECT
- name: "自动测速"
type: url-test
url: http://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
proxies:
- HK-01
- JP-01
- US-01
自动类组的三个参数直接影响体验。url 是测速目标,惯例使用返回 204 状态码的轻量地址,测的是"经该节点访问此地址"的完整往返;interval 是测速间隔秒数,过短会产生大量探测流量;tolerance 是切换容差(毫秒)——新的最快节点要比当前节点快出这个差值才会切换,用来避免两个延迟接近的节点来回抖动。lazy: true 让组在未被使用时暂停测速,减少后台开销。
组可以引用组:示例中的「节点选择」把「自动测速」作为第一个可选项,形成"顶层手动、底层自动"的两级结构。订阅配置常见的「香港」「日本」等地区组,再汇入一个总组,也是同样的嵌套。两个保留名可以直接出现在任何组里:DIRECT 表示直连,REJECT 表示拒绝连接(常用于广告拦截规则的出口)。需要注意组与节点共享同一个命名空间,组名不能与节点名重复,也不能构成循环引用——A 组包含 B 组、B 组又包含 A 组会导致加载失败。
六、规则语法(rules)
rules 段决定每一条连接的去向,是整份配置里最值得亲手维护的部分。每条规则是一行逗号分隔的文本,基本形态为「类型,匹配值,出口」,出口填策略组名、节点名或 DIRECT / REJECT。
6.1 匹配顺序:自上而下,首条命中即停
内核对每条新连接从第一条规则开始逐条尝试,命中即采用该条的出口,后面的规则不再参与。这个机制推导出规则编排的全部原则:精确规则放前面,宽泛规则放后面,兜底规则放最后。一条 GEOIP,CN,DIRECT 如果被放在了针对某个域名的代理规则之前,而该域名恰好解析到国内 IP,后面的域名规则就永远不会生效——绝大多数"规则明明写了却不生效"的问题都是顺序问题。
6.2 常用规则类型
| 类型 | 匹配对象 | 示例 |
|---|---|---|
| DOMAIN | 域名完全相等 | DOMAIN,dl.example.com,DIRECT |
| DOMAIN-SUFFIX | 域名本身及其任意子域 | DOMAIN-SUFFIX,openai.com,节点选择 |
| DOMAIN-KEYWORD | 域名包含关键字 | DOMAIN-KEYWORD,github,节点选择 |
| IP-CIDR | 目标 IPv4 属于网段 | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve |
| IP-CIDR6 | 目标 IPv6 属于网段 | IP-CIDR6,fd00::/8,DIRECT,no-resolve |
| GEOIP | 目标 IP 的地理数据库归属 | GEOIP,CN,DIRECT |
| PROCESS-NAME | 发起连接的进程名(桌面端) | PROCESS-NAME,steam.exe,DIRECT |
| DST-PORT | 目标端口 | DST-PORT,22,DIRECT |
| RULE-SET | 引用 rule-providers 规则集 | RULE-SET,telegram,节点选择 |
| MATCH | 无条件命中,必须是最后一条 | MATCH,节点选择 |
DOMAIN-SUFFIX,example.com 会同时命中 example.com 与 a.b.example.com,是覆盖一个站点最常用的类型;DOMAIN-KEYWORD 范围最宽,容易误伤,只在确认关键字足够独特时使用。IP 类规则末尾的 no-resolve 参数含义是"如果当前连接的目标是域名而非 IP,跳过这条规则,不要为了匹配它而发起解析"——给内网网段规则加上它,可以避免所有域名连接都先被解析一遍拖慢匹配。
6.3 一段可直接套用的编排
rules:
- PROCESS-NAME,steam.exe,DIRECT
- DOMAIN,dl.example.com,DIRECT
- DOMAIN-SUFFIX,openai.com,节点选择
- DOMAIN-KEYWORD,github,节点选择
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,节点选择
这段编排体现了推荐的层次:进程与精确域名规则最先,业务域名规则其次,内网网段与地理位置直连靠后,MATCH 兜底收尾。MATCH 之后的任何规则都是死代码,内核不会报错但永远不会执行,自查配置时可以把它当作"规则段结束标记"。自定义规则写好后如何验证命中情况,见第九章的日志方法。
七、外部资源:proxy-providers 与 rule-providers
当节点来自多个订阅、规则条目成百上千时,把所有内容堆在一份 YAML 里会迅速变得不可维护。Provider 机制允许把节点列表与规则集拆成独立文件,由内核按周期自动拉取更新,主配置只保留引用关系。
7.1 proxy-providers:节点来源与健康检查
proxy-providers:
main-sub:
type: http
url: "https://example.com/subscribe/token"
path: ./providers/main-sub.yaml
interval: 86400
health-check:
enable: true
url: http://www.gstatic.com/generate_204
interval: 600
proxy-groups:
- name: "订阅节点"
type: select
use:
- main-sub
type: http 表示从远程地址拉取,path 是本地缓存路径(拉取失败时沿用缓存,保证离线可启动),interval 是自动更新周期(秒)。health-check 让内核周期性测试该来源下所有节点的可用性,失效节点会在自动类组里被跳过。策略组通过 use 字段引用 provider 名,与 proxies 字段可以并存——一个组可以同时包含手写节点和整个订阅来源。
7.2 rule-providers:规则集的三种 behavior
rule-providers:
telegram-ip:
type: http
behavior: ipcidr
format: yaml
url: "https://example.com/rules/telegram.yaml"
path: ./rules/telegram-ip.yaml
interval: 86400
rules:
- RULE-SET,telegram-ip,节点选择
behavior 声明规则集文件的内容形态,三个取值不可混用:domain 表示文件内全部是域名条目,ipcidr 表示全部是网段条目,这两种形态内核会构建高效索引,适合上万条的大列表;classical 表示文件内是带类型前缀的完整规则行,灵活但匹配开销更高。format 支持 yaml 与 text,需与文件实际格式一致。主配置里用 RULE-SET,规则集名,出口 引用,这一行在规则段里的位置仍然遵循第六章的顺序原则。
更新周期的取舍
interval 不必设得很短:节点订阅一天一次(86400)通常足够,规则集变动更慢,数天一次也可以。周期过短除了浪费流量,还会在来源服务器不稳定时频繁触发拉取失败日志,干扰排错判断。
八、覆写与合并:让改动在订阅更新后存活
直接编辑订阅生成的配置文件有一个根本问题:订阅更新是整份替换,手工加的节点、改的规则会在下一次更新时全部丢失。解决思路只有一个——把"服务商提供的内容"与"本地自定义的内容"分开存放,由客户端在加载时合并。各客户端都提供了这一机制,叫法不同,原理一致。
8.1 客户端的覆写机制
下载中心首推的 Clash Plus 提供配置覆写入口,可以在不改动订阅原文的前提下追加规则与节点;Clash Verge Rev 提供「合并(Merge)」与「脚本(Script)」两类扩展配置——Merge 用声明式 YAML 描述追加与替换,Script 用 JavaScript 函数在加载时改写配置对象,能处理条件逻辑;FlClash 同样支持覆写配置。无论用哪个客户端,原则相同:订阅文件本身永远保持只读,所有自定义都写在覆写层。
8.2 Merge 式覆写示例
prepend-rules:
- DOMAIN-SUFFIX,internal.example.com,DIRECT
- PROCESS-NAME,steam.exe,DIRECT
append-rules:
- DOMAIN-KEYWORD,tracker,REJECT
append-proxies:
- name: "自建-HK"
type: ss
server: my.example.com
port: 8388
cipher: aes-256-gcm
password: "your-password"
prepend-* 把条目插到对应段落最前面,append-* 追加到最后面。方向的选择要结合规则匹配顺序:希望优先命中的自定义规则用 prepend-rules;兜底性质的拦截规则用 append-rules,但要注意它会落在订阅原有的 MATCH 之后——若订阅末尾已有 MATCH,追加的规则实际不可达,这种情况应改用 prepend 或直接替换整个 rules 段。对 mixed-port、dns 这类标量或映射字段,在覆写层写同名字段即整体替换。
8.3 手动维护场景
在 Linux 服务器等直接跑 mihomo 内核、没有图形客户端的环境里,没有现成的合并层,推荐把订阅下载为一份基准文件,再用脚本或手工把自定义段落拼接成最终配置,更新订阅时只替换基准部分。目录组织与 systemd 常驻方案见站内文章《Clash 在 Linux 下的两条部署路线》。
改配置前先备份
无论通过哪种方式修改,动手前复制一份当前可用的配置文件存到配置目录之外。合并逻辑出错时,回滚到备份是最快的恢复手段——比对着日志逐行找错要省时得多。多配置切换与备份的具体做法见Profile 管理指南。
九、校验与排错
配置改完不要直接重载了事,先验证语法、再观察行为,能把问题定位的时间压缩到最短。本章给出一套固定的验证顺序。
9.1 加载前:语法校验
mihomo 内核自带配置测试参数,不启动服务、只做解析,几秒内给出结果:
mihomo -t -f config.yaml
输出 configuration file test is successful 即语法通过;否则会打印出错的字段路径与行号提示。桌面客户端在导入或保存配置时也会执行同等校验并弹出错误详情,报错文案与内核一致,可以直接按下表对照。
9.2 常见报错对照
| 报错关键字 | 原因 | 处理 |
|---|---|---|
| found a tab character | 行首混入制表符 | 把 Tab 全部替换为空格,统一两空格缩进 |
| did not find expected key | 缩进层级错位,字段挂错了父级 | 核对出错行与上下文的缩进宽度是否一致 |
| proxy not found / group not found | 规则或组引用了不存在的名称 | 检查名称拼写与全角/半角空格,确认引用目标确实存在 |
| bind: address already in use | 入站或控制端口被其他程序占用 | 换端口,或找到占用进程结束它 |
| duplicate proxy name | 节点或组重名 | 重命名其中一个,注意组与节点共享命名空间 |
| unsupported proxy type | type 拼写错误或内核不支持该协议 | 核对协议名拼写,确认使用的是 mihomo 内核 |
9.3 加载后:观察实际行为
语法通过不代表分流符合预期。把 log-level 临时调到 debug 后重载,客户端日志面板会逐条打印连接记录,格式类似 example.com:443 --> 节点选择 (match DOMAIN-SUFFIX/example.com),直接标明每条连接命中了哪条规则、走了哪个出口——这是验证自定义规则最可靠的手段,比反复刷新网页猜测高效得多。确认无误后记得把日志级别调回 info,debug 级别的日志量很大。
需要在命令行环境确认内核存活时,可以直接访问控制接口:
curl -s http://127.0.0.1:9090/version -H "Authorization: Bearer 你的secret"
有正常 JSON 返回说明内核在运行且控制接口可达;无响应则说明内核未启动或 external-controller 地址与预期不符。客户端启动即闪退、连日志都来不及看的情况,按《Clash 客户端启动闪退排查手册》给出的各平台日志位置与验证顺序逐项处理。
9.4 下一步
如果读到这里你还没有一个能跑通的基础环境,建议先回到快速上手按主线流程完成第一次连接,再带着具体需求回来查对应章节;客户端本体在下载中心按平台获取,全平台首推 Clash Plus。使用过程中的高频疑问——开机自启、订阅失效、节点超时等——集中整理在常见问题页,与本页互为补充。