CH-01策略组:配置里的换挡机构
先分清两件事。规则负责判断:这条流量归谁管。策略组负责回答:归它管之后,具体走哪个节点。一份耐用的配置,几乎所有规则出口都不直接指向单个节点,而是指向策略组——节点今天在明天没,组的名字不会变。把组搭好,后面换机场、换节点都只是换弹匣,不用动枪。
五种类型,一张规格表
| 类型 | 选节点方式 | 典型用途 |
|---|---|---|
select | 手动挑,挑了就不变 | 总开关、地区切换、需要人拍板的场景 |
url-test | 定时测延迟,自动选最快 | 日常自动挡,大多数流量的默认去处 |
fallback | 按列表顺序,前面挂了才换后面 | 有明确主备优先级的场景 |
load-balance | 把连接分摊到多个节点 | 单节点限速时摊流量,注意部分服务对 IP 变动敏感 |
relay | 按顺序串成链,流量逐跳转发 | 链式代理,开销大延迟高,仅特殊需求使用 |
挑的原则很朴素:交给机器判断的用 url-test,需要人做主的用 select,其余三种是特定场景的专用件。新手把前两种用熟,已经覆盖九成需求。
url-test 的三颗旋钮
url 是测速目标,惯例填一个返回 204 状态码的轻量地址,例如 https://www.gstatic.com/generate_204——它只回一个空响应,测的是纯粹的链路耗时,不掺网页加载时间。interval 是测速周期,单位秒,300 表示五分钟测一轮;调太小会频繁发测速请求,调太大则节点挂了半天才发现。tolerance 是容忍差值,单位毫秒:新旧最快节点的延迟差不超过这个值就不切换。不设它的话,两个节点延迟在 80 和 85 之间来回抖,组就跟着来回跳,长连接反复被掐断。再补一颗常用旋钮 lazy: true:组没被使用时不发起测速,能省掉后台一批无谓请求。
一套耐用的分层结构
实战里推荐三层:最上面一个 select 总开关,中间挂自动测速组和各地区组,底层才是具体节点。规则一律指向组名,永远不点名单个节点。想手动锁定某个地区,在总开关里切;想全自动,切回自动测速组。结构如下:
proxy-groups:
- name: 手动总闸
type: select
proxies: [自动测速, 香港节点, 日本节点, DIRECT]
- name: 自动测速
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
proxies: [HK-01, HK-02, JP-01, JP-02]
- name: 香港节点
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
proxies: [HK-01, HK-02]
- name: 日本节点
type: select
proxies: [JP-01, JP-02]
rules 里引用它的地方——引用了不存在的组,内核会在启动时直接报错,一条都不会放行。用 filter 让节点自动进组
机场节点动辄上百条,手写 proxies 列表一次能忍,每月改一次就想砸键盘。filter 字段接受一段正则,配合 use 挂载订阅弹匣时,只有名字匹配的节点才会被收进这个组。于是「香港节点」组写成 filter: "香港|HK|Hong",机场明天新增五条香港线路,组里自动就多五条,你一个字都不用改。反过来还有 exclude-filter,把名字里带「过期」「剩余流量」「官网」这类信息条目排除掉——这些伪节点连不上,留在自动测速组里只会拖慢每一轮测速。写正则时优先用竖线列多个关键词,别写复杂的分组回溯,匹配规模大时性能差异很明显。
还有一个容易被忽略的字段是 disable-udp。部分节点声称支持 UDP,实际转发不通,游戏和语音一走上去就丢包。把这类节点单独归一组并声明 disable-udp: true,UDP 流量就会自动落到下一个可用出口,而不是卡死在一条假通道上。搭配 expected-status 校验测速目标返回的状态码,能进一步筛掉那些「握手成功但被劫持到广告页」的节点——延迟数字漂亮,实际不可用,这类节点最会骗人。
三个高频误区
第一个误区是把 fallback 当自动挡用。它只在前一个节点判定为不可用时才换,判定依赖健康检查,存在滞后;节点没挂只是变慢,它会一直守着不动。要「哪个快用哪个」,请用 url-test。第二个误区是给 load-balance 组挂上需要固定 IP 的服务:登录态、支付验证、部分网盘会因为同一会话里 IP 反复跳变而直接判定异常,轻则重新登录,重则触发风控。第三个误区是层层嵌套:组里套组、套到第四五层,内核每次选路都要顺着链条走一遍,面板上也彻底看不出流量最终落在哪。三层封顶是经验值,再深的结构除了炫技没有别的收益。
CH-02规则集:把规则做成可换的弹匣
把几百条规则一条条写进主配置,等于把所有零件焊死在底板上——想换一颗都得拆整机。rule-providers 的思路是把规则拆成可插拔的弹匣:主配置里只留一句 RULE-SET 引用,弹匣本体挂在外部地址上,到点自动更新。维护者改弹匣,你这边什么都不用动。
槽位规格
每个 provider 有五个关键字段。type 分 http(从 URL 拉取)和 file(读本地文件)两种;behavior 声明弹匣里装的是什么类型的子弹,见下一节;format 是文件格式,yaml 或 text;path 是下载后的本地缓存路径;interval 是自动更新周期,单位秒,86400 即一天一换。缓存的意义在于:断网重启时内核直接读本地副本,不会因为拉不到规则而起不来。
behavior 三选一怎么挑
domain 弹匣里只装域名,内核会为它建专用索引,匹配最快、内存最省;ipcidr 只装 IP 段,同样走专用匹配;classical 什么类型都能装(DOMAIN-SUFFIX、IP-CIDR、PROCESS-NAME 混着来),灵活但逐条匹配,规则一多就吃性能。选法:纯域名列表用 domain,纯 IP 段用 ipcidr,混装才用 classical。拿 classical 装纯域名列表,能跑,但等于用卡车送快递。
装配示例与更新节奏
rule-providers:
streaming:
type: http
behavior: classical
format: yaml
url: "https://example.com/rulesets/streaming.yaml"
path: ./rulesets/streaming.yaml
interval: 86400
cn-ip:
type: http
behavior: ipcidr
format: text
url: "https://example.com/rulesets/cn-ip.txt"
path: ./rulesets/cn-ip.txt
interval: 86400
rules:
- RULE-SET,streaming,手动总闸
- RULE-SET,cn-ip,DIRECT,no-resolve
- MATCH,手动总闸
no-resolve 后,只有流量本身带 IP 时才参与匹配,不主动解析——既省一次等待,也避免解析请求走了不该走的通道。IP 规则放在域名规则后面,并且尽量都带上这个参数。更新周期按弹匣性质定:社区维护的分流列表一天一换足够;自己维护、频繁调整的列表可以缩到几小时。规则集拉取失败的排查思路与订阅更新失败一致,可参考帮助中心的故障排查分类。
规则的匹配顺序就是它的优先级
这是整份配置里最容易踩的坑:rules 是一个有序列表,内核从第一条往下逐条比对,命中即停,后面的规则连看都不看。所以同一个域名被两条规则同时覆盖时,谁写在前面谁说话。很多人抱怨「我明明写了让这个网站直连,它还是走了代理」,翻开配置一看,上面二十行处有一条更宽泛的 DOMAIN-KEYWORD 早就把它兜走了。
推荐的排列顺序是:最上面放特例——单个域名的精确放行或强制代理,数量少、优先级最高;接着是进程级规则 PROCESS-NAME,它比域名判断更早生效,适合处理某个软件整体走向;然后是域名类规则,按「精确 DOMAIN → 后缀 DOMAIN-SUFFIX → 关键词 DOMAIN-KEYWORD → 分类 GEOSITE / RULE-SET」由窄到宽排;再往下是 IP 类规则 IP-CIDR 与 GEOIP,统统记得带 no-resolve;最后一条 MATCH 收尾,把所有漏网流量指向一个明确出口。MATCH 必须存在且必须在最后,缺了它未匹配流量的走向就成了未定义行为。
调试顺序问题有个笨办法但极其有效:打开控制面板的连接列表,找到那条流量,看它右侧显示命中的规则是哪一条。是哪条就去改哪条,不要凭记忆猜。规则条数上千时还要留意性能:DOMAIN-KEYWORD 需要对每个域名做子串扫描,是最贵的一类,能用 DOMAIN-SUFFIX 表达的就别用关键词;而 domain 型规则集走的是专用索引,几万条也几乎不耗时间,这就是前面强调 behavior 要选对的现实理由。
CH-03DNS 配置优化:一半的锅在解析
「代理开了但网页打不开」「规则明明写了却不命中」——这类问题一半出在 DNS。内核内置一台 DNS 解析器,配置得当,解析又快又稳;配置混乱,污染和泄漏轮着来。这一章把解析链路上的每个槽位讲清楚。
先看懂解析链路
解析器有三层。default-nameserver 是引导层:当你的主力解析器本身是个域名(比如 DoH 地址 https://doh.pub/dns-query),得先有人把这个域名解析成 IP,干这活的就是引导层,所以它只能填纯 IP,填域名会陷入先有鸡还是先有蛋的死循环。nameserver 是主力层,日常查询都从这里走。fallback 是备胎层,专门应对主力层可能被污染的场景。三层各司其职,别把 DoH 地址塞进引导层,也别把主力层留空。
nameserver 与 fallback 的分工
工作方式是并发:一次查询同时发给主力和备胎,然后由 fallback-filter 裁决用谁的答案。最常用的裁决器是 geoip: true 加 geoip-code: CN:主力层返回的 IP 落在中国大陆段,就采信主力(说明是正常的境内解析);落在境外段,则改用备胎的答案(境内解析器给出境外 IP,有被污染的嫌疑)。这套机制的代价是每次查询多发一份请求,换来的是抗污染能力。如果你的主力层本身走加密通道(DoH/DoT),污染风险已经很低,fallback 可以从简。
nameserver-policy:给域名指定专属解析器
有些域名你明确知道该在哪解析:境内服务用境内解析器,得到就近的 CDN 节点;测速、局域网域名各有专属去处。nameserver-policy 就是这张定向分拣表,支持通配和 geosite 分类。完整示例:
dns:
enable: true
listen: 0.0.0.0:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
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
- https://8.8.8.8/dns-query
fallback-filter:
geoip: true
geoip-code: CN
nameserver-policy:
"geosite:cn": https://doh.pub/dns-query
"+.lan": 223.5.5.5
enhanced-mode 的两种取值差异,见下一章。DoH、DoT 与明文解析怎么选
明文 DNS 走 UDP 53,报文全程裸奔,链路上任何一跳都能看到你查了什么,也能伪造一个假答案抢先返回——这就是污染的技术原理。DoT 把解析封进 TLS 走 853 端口,加密了,但端口特征明显。DoH 把解析伪装成普通 HTTPS 请求走 443,和网页流量混在一起,最不容易被单独针对,代价是每次建连要多一次 TLS 握手,首次查询稍慢。实用组合是:主力层填两个 DoH,引导层填两个纯 IP 的明文解析器(它只负责把 DoH 的域名解析出来,查询量极小),这样既有加密保护,又不会陷入循环依赖。
另外两个值得设的字段:use-hosts: true 让内核读取配置里的 hosts 段,方便临时把某个域名钉死到指定 IP 做验证;respect-rules 让 DNS 查询本身也遵守分流规则,避免境外解析器的查询包从直连出口发出去而被拦。ipv6 字段建议按实际网络环境定:上游没有 IPv6 却打开它,会让每次查询多等一份必然失败的 AAAA 响应,表现就是「打开网页前先卡半秒」。
CH-04TUN 与 Fake-IP:系统层兜底与假地址号牌
TUN:接管不听话的流量
系统代理是个君子协定:只有「愿意读系统代理设置」的应用会走它。命令行工具、部分游戏客户端、一些桌面软件对这份设置视而不见,流量直接出门。TUN 模式的做法是插一块虚拟网卡,把整台设备的出站流量在网络层截下来交给内核——应用配不配合都一样,想溜的也得过安检。
顺带说清 Android 上的情况:客户端点「启动」时向系统申请的 VPN 通道,本质就是一块 TUN 网卡。所以 Android 用户天生就在 TUN 模式里,不需要手动配这一段;需要显式打开 TUN 的是桌面平台。各平台客户端的获取见下载页,横向差异见横向评测。桌面端的关键字段:stack 是协议栈实现,system 性能好但依赖系统能力,gvisor 用户态实现兼容性稳,mixed 取两者所长,不确定就选 mixed;auto-route 自动接管路由表;dns-hijack 把发往任意 53 端口的明文 DNS 请求劫回内核,防止应用自带的解析绕过分流。
Fake-IP:先发号牌,后办业务
银行叫号的逻辑。应用问「这个域名的 IP 是多少」,内核不去真解析,立刻从 198.18.0.1/16 这个保留段里发一个假地址当号牌,零延迟。应用拿号牌发起连接,连接到达内核时,内核凭号牌反查出域名,按域名规则分流;需要走代理的,真实解析交给出口那头去做。好处有两个:省掉本地一次真实解析的等待,起连快;域名规则的命中率也高,因为内核始终知道每条连接背后的域名。
代价是号牌不能拿出营业厅用。局域网设备发现、打印机、部分游戏联机、需要把 IP 回传给服务器的场景,拿到假地址就抓瞎。解药是 fake-ip-filter:名单里的域名不发号牌,老老实实真解析。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
dns:
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- "*.lan"
- "+.local"
- "+.msftconnecttest.com"
- "+.stun.*.*"
fake-ip 与 redir-host 对照
| 对比项 | fake-ip | redir-host |
|---|---|---|
| 本地解析等待 | 无,立即返回假地址 | 有,等真实解析完成 |
| 域名规则命中 | 稳定,内核持有域名映射 | 依赖解析结果,部分场景失明 |
| 局域网兼容 | 需要 fake-ip-filter 放行 | 天然兼容 |
| 适合人群 | 大多数日常使用 | 局域网服务多、特殊兼容需求 |
enhanced-mode 之间切换后,务必断开重连一次:应用手里可能还攥着旧模式发的地址,新旧号牌混用会出现一段时间的诡异连接失败。CH-05域名嗅探:贴在入站口的读码器
Fake-IP 打好了补丁,链路上还剩一条缝:有些流量到达内核时手里只有 IP,没有域名。典型元凶是应用自带的加密解析(应用内置 DoH,不经过内核的 DNS),或者写死 IP 直连的客户端。域名规则对这种流量集体失明,只能靠 IP 规则或 MATCH 兜底,分流精度直线下降。
sniffer 是贴在入站口的条码读取器:流量进来时,从 TLS 握手的 SNI 字段、HTTP 请求头的 Host 字段里把域名重新读出来,贴回这条连接,再送去规则匹配。域名找回来了,规则就能正常干活。
配置件规格
sniff 下按协议声明要扫描的端口:TLS 通常扫 443 和 8443,HTTP 扫 80 与常见代理端口段。override-destination 决定嗅探出的域名是否覆盖原目标地址,HTTP 场景建议开。force-domain 是强制嗅探名单,列出的域名即使已有解析结果也重新嗅一遍;skip-domain 是免检名单——对证书校验严格、或对 SNI 改动敏感的服务(苹果推送是常客),嗅探反而会把连接弄断,列进去直接放行。
sniffer:
enable: true
sniff:
TLS:
ports: [443, 8443]
HTTP:
ports: [80, 8080-8880]
override-destination: true
force-domain:
- "+.v2ex.com"
skip-domain:
- "+.push.apple.com"
0-65535 全扫。遇到某个应用开嗅探后频繁掉线,第一反应是把它的域名加进 skip-domain。CH-06本地覆写与多订阅合并:改动不怕更新冲
为什么不直接改订阅文件
直接在订阅下发的配置文件里改规则、加节点,手感是顺的,结局是惨的:订阅一更新,整个文件被服务端的新版本覆盖,你的改动全部归零。正确姿势是覆写——订阅原文永远保持只读,你的改动记在本地另一层,每次订阅更新完成后自动重放到新文件上。改动和订阅从此互不干涉。
客户端里的覆写入口
主流客户端都内置了这层机制,名称各异,思路一致。以 Clash Verge Rev 为例,提供两级:Merge 用声明式片段做合并,适合追加规则、追加策略组这类结构化改动;Script 用脚本对整份配置做程序化改写,适合批量重命名节点、按条件过滤这类复杂操作。能用 Merge 解决的别上 Script——声明式片段一眼能看懂,脚本出错时排查成本高得多。各客户端覆写能力的差异,横向评测里有专门一节。
用 proxy-providers 合并多订阅
手里有两家以上机场时,别来回切换配置文件。proxy-providers 与规则集的 provider 是同一个思路:每份订阅是一个节点弹匣,策略组用 use 字段同时挂载多个弹匣,两家的节点就混编进同一个自动测速组,谁快用谁。
proxy-providers:
airport-a:
type: http
url: "https://example.com/sub/a.yaml"
path: ./providers/a.yaml
interval: 43200
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
airport-b:
type: http
url: "https://example.com/sub/b.yaml"
path: ./providers/b.yaml
interval: 43200
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
proxy-groups:
- name: 全部节点
type: url-test
use: [airport-a, airport-b]
url: https://www.gstatic.com/generate_204
interval: 300
health-check 给弹匣里的节点做定期体检,挂掉的节点会被自动测速组跳过;interval: 43200 表示订阅本体半天拉取一次新版。订阅链接的格式识别与导入入口,可以先读这篇:Clash 订阅链接导入教程。
url 字段;把含真实订阅地址的配置文件传到公开仓库,等于把钥匙挂在门上。CH-07外部控制面板:给内核装一个遥控接口
三个字段开启遥控
external-controller 声明 RESTful API 的监听地址,惯例是 127.0.0.1:9090;secret 是访问口令,所有请求都要带它;external-ui 指向一个本地目录,把网页面板的静态文件放进去,浏览器直接访问监听地址就能打开图形界面。市面上的网页面板(metacubexd、yacd 一系)本质都是这套 API 的前端皮肤,换皮不换芯。
external-controller: 127.0.0.1:9090
secret: "your-strong-password"
external-ui: ./ui
不开面板也能用:三条常用命令
API 本身就是可用的工具,写脚本、做自动化时直接调:
# 查看全部策略组与节点状态
curl -H "Authorization: Bearer your-strong-password" \
http://127.0.0.1:9090/proxies
# 把「手动总闸」组切到 HK-01
curl -X PUT -H "Authorization: Bearer your-strong-password" \
-d '{"name":"HK-01"}' \
http://127.0.0.1:9090/proxies/手动总闸
# 给单个节点测一次延迟
curl -H "Authorization: Bearer your-strong-password" \
"http://127.0.0.1:9090/proxies/HK-01/delay?timeout=5000&url=https://www.gstatic.com/generate_204"
面板上值得常用的三块
连接列表:实时看每条连接命中了哪条规则、走了哪个出口——「这条流量为什么直连了」这类问题在这里一眼见底。日志:把级别临时调到 debug,规则匹配的完整过程逐条打印,排查完记得调回,debug 日志量很大。Provider 管理:手动触发某个订阅或规则集立即更新,不用等 interval 到点。
external-controller 监听在 0.0.0.0 又不设 secret,等于把遥控器挂在公网门口:任何能访问这个端口的人都能改你的出口、看你的连接。只在本机用就锁 127.0.0.1;确需局域网访问,必须配强口令。CH-08配置故障速查表
症状对号入座,先查最常见的原因,再顺着链接跳到对应章节或文章。多数问题在前两步就能解决。
| 症状 | 最常见原因 | 先查这里 |
|---|---|---|
| 改了规则不生效 | 改在订阅原文里,被更新冲掉了 | CH-06 覆写 |
| 订阅更新失败 | 链接过期,或更新请求本身没走通 | 帮助中心故障排查分类 |
| 节点延迟全部超时 | 测速 URL 不可达、系统时间偏差过大 | 首次连接与测延迟 |
| 部分应用不走代理 | 应用无视系统代理设置 | CH-04 TUN;Windows 商店应用见UWP 回环限制解除 |
| 延迟正常但网页打不开 | DNS 配置问题,或模式切换后的旧缓存 | CH-03 DNS 与 CH-04 Fake-IP |
| 局域网设备、打印机失联 | 本地域名被发了 Fake-IP 号牌 | CH-04 的 fake-ip-filter |
| 某应用开嗅探后频繁掉线 | 该服务对 SNI 改动敏感 | CH-05 的 skip-domain |
一套通用的排查手法
不管症状是什么,按这五步走一遍,绝大多数问题会自己浮出水面。第一步,分层定位:先在面板的连接列表里确认这条流量到底有没有进内核。没进,问题在系统代理或 TUN 这一层,和规则无关;进了但出口不对,问题在规则或策略组。第二步,看命中规则:面板会直接告诉你它匹配了哪一条,对照 CH-02 的顺序原则去改那一条。第三步,单点验证:把总开关临时切成 DIRECT 再切成某个具体节点,分别试一次——直连通、代理不通,说明是节点或链路问题;两个都不通,回去查 DNS。第四步,清缓存重连:改过 DNS 段、切过 enhanced-mode 之后必须做,否则你验证的是旧状态。第五步,二分法回退:把最近的改动逐段注释掉,找出到底是哪一行引起的,比盯着整份配置猜要快得多。
还有两个好习惯值得从第一天就养成。一是改配置前先复制一份备份,文件名带上日期;配置文件是纯文本,一份不到几十 KB,留十个版本也不占地方,但能在改崩的时候救你一次。二是把日志级别在排查时调到 debug、排查完立刻调回 info:debug 会把每次规则匹配、每次 DNS 查询都打出来,信息量足够定位问题,但长期开着既刷屏又白耗磁盘。
表里没覆盖的问题,去帮助中心按「基础认知 / 安装配置 / 使用技巧 / 故障排查」四个分类翻;怀疑是客户端本身的问题,先在横向评测里确认它的能力边界,必要时到下载页换一台首推的 Clash Plus 再试。基础操作忘了的,随时回快速上手补课。