策略组类型与实际组合
先区分“选节点”和“做判断”
策略组位于规则与代理节点之间。规则只负责把连接交给某个策略名称,真正决定使用哪条线路的是策略组。把两者混在一起,常见结果是配置中重复出现大量节点名,节点一旦调整,规则也要跟着修改。更稳妥的结构是先按用途建立稳定的策略组,例如“节点选择”“自动选择”“流媒体”“即时通信”和“漏网之鱼”,规则长期引用这些名称,节点变化则交给订阅与策略组处理。
select 是手动选择组,适合需要明确控制出口的场景。用户在客户端界面中选择一个节点、另一个策略组或 DIRECT,选项会保持到配置重载或持久化状态发生变化。它不主动检测线路质量,因此最适合作为顶层入口:下面可以同时放“自动选择”“故障转移”和若干地区组。这样既能保留自动化,也能在特定网站出现兼容问题时快速切换。
url-test 会按指定地址定期进行连通性测试,并选择结果较优的节点。它适合网页浏览、软件更新等对响应时间敏感、连接可以重新建立的流量。测试结果只反映测试目标的连接情况,不等同于所有网站的真实速度;节点到测试地址很快,也可能到目标服务绕路。因此不要把检测间隔压得过短,更不要把一次测试当成线路质量的永久结论。
fallback 按列表顺序选择第一个可用项。它重视稳定的优先级,而不是每次都追求最低延迟。主线路固定、备用线路只在故障时接管的场景,更适合使用该类型。load-balance 则会把不同连接分配到多个节点,可用于大量并发、彼此独立的请求,但同一业务若同时看到多个出口地址,可能触发登录状态变化或风控。网银、账号管理和持续会话不应随意交给负载均衡组。
| 类型 | 决策方式 | 适用场景 | 主要边界 |
|---|---|---|---|
select |
用户手动指定 | 顶层出口、地区切换 | 不会主动避开失效节点 |
url-test |
选择测试结果较优项 | 网页、更新、一般应用 | 测试目标不能代表所有服务 |
fallback |
按顺序使用首个可用项 | 主备线路、固定优先级 | 切换后既有连接可能需要重建 |
load-balance |
按策略分配不同连接 | 并发下载、独立请求 | 多出口可能影响会话一致性 |
用 provider 管理动态节点
订阅节点经常增删,直接在每个策略组内写完整节点列表会让配置很快失去可维护性。mihomo 可以通过 use 引用 proxy-providers,再使用 filter 或 exclude-filter 按节点名称筛选。筛选表达式只处理名称,不验证节点实际位置,所以应以订阅中稳定的命名规则为基础。若服务提供方频繁改名,优先使用一个包含全部节点的自动组,再把少量特殊线路手动放入专用组。
proxy-providers:
primary:
type: http
url: "https://example.com/subscription"
path: ./providers/primary.yaml
interval: 86400
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
proxy-groups:
- name: 节点选择
type: select
proxies:
- 自动选择
- 故障转移
- DIRECT
- name: 自动选择
type: url-test
use:
- primary
url: https://www.gstatic.com/generate_204
interval: 600
tolerance: 80
- name: 故障转移
type: fallback
use:
- primary
url: https://www.gstatic.com/generate_204
interval: 600
tolerance 用于减少小幅波动造成的频繁切换。两条线路只有几毫秒差异时,持续改变出口往往比维持当前线路更糟。检测地址应返回轻量、稳定且可访问的响应;如果检测目标本身被规则直连、被 DNS 错误解析或所在网络无法到达,整组健康状态都会失真。排查时先确认检测请求实际经过哪条链路,再判断节点是否真的不可用。
策略组排序也会影响操作体验。顶层手动组放在规则直接引用的位置,地区组与自动组作为下层能力,不要形成循环引用。例如 A 组包含 B,B 又包含 A,内核无法得到有效出口。修改后先在客户端的策略页面确认每个组都有可选项,再查看连接日志中的“规则名称—策略组—实际节点”三段信息。若想进一步理解规则的自上而下匹配顺序,可阅读自定义规则语法与优先级详解。
规则集订阅化管理
从单条规则拆到 rule-provider
少量自定义规则可以直接写在 rules 中,但当域名、网段和应用分类达到数百条后,主配置会变得难以审阅。规则集的作用是把规则内容拆成独立文件,由 rule-providers 负责下载、缓存和定期更新,主规则列表只保留引用顺序。这样可以分别维护广告过滤、私有网络、特定服务和地区网络规则,也能在某个来源异常时单独停用,而不必替换整个订阅。
provider 的 behavior 决定文件内容的解释方式。domain 面向域名集合,适合纯域名分类;ipcidr 面向 IPv4 与 IPv6 网段;classical 接收带类型的完整规则,例如 DOMAIN-SUFFIX、PROCESS-NAME 和 IP-CIDR。三者不能随意互换。一个声明为 domain 的文件里若塞入完整规则语法,加载时可能报格式错误,或内容无法按预期匹配。
format 常见为 yaml、text 或二进制规则格式。YAML 便于人工审阅,文本格式适合一行一条的简单来源。无论选择哪种格式,都要让声明与远端文件实际内容一致。path 是本地缓存位置,不同 provider 不应共用同一个文件,否则后下载的内容会覆盖前者。桌面客户端通常会代管配置目录,相对路径比写死某个用户目录更易迁移。
rule-providers:
private-network:
type: http
behavior: classical
format: yaml
path: ./rules/private-network.yaml
url: "https://example.com/rules/private-network.yaml"
interval: 86400
service-domains:
type: http
behavior: domain
format: yaml
path: ./rules/service-domains.yaml
url: "https://example.com/rules/service-domains.yaml"
interval: 86400
regional-cidr:
type: http
behavior: ipcidr
format: yaml
path: ./rules/regional-cidr.yaml
url: "https://example.com/rules/regional-cidr.yaml"
interval: 86400
rules:
- RULE-SET,private-network,DIRECT
- RULE-SET,service-domains,节点选择
- RULE-SET,regional-cidr,DIRECT,no-resolve
- MATCH,漏网之鱼
顺序、解析与 no-resolve
Clash 规则按从上到下的顺序匹配,命中后停止继续检查。因此“规则集已经包含某域名”不代表一定会使用它:如果更靠前的规则已经命中,后面的 provider 永远没有机会执行。一般应把范围小、意图明确的本地规则放在前面,把业务规则集放在中间,把地区网段和兜底规则放在后面。临时修复某个网站时,也应优先在主配置顶部加一条清晰规则,而不是立刻修改大型远端集合。
IP 类规则可能触发域名解析。当连接最初只带域名,而规则引擎需要判断目标 IP 是否属于某个网段时,内核必须先取得地址。no-resolve 表示这条规则不要为了匹配而主动发起解析,适合放在域名规则之后的 IP 规则,减少额外 DNS 查询并避免解析过程改变原始判断。但如果流量入口只提供 IP,IP 规则仍可直接匹配;no-resolve 并不是禁用这条规则。
远端规则集不可用时,要区分“更新失败”和“本地缓存不可用”。如果已有缓存仍然有效,临时网络故障通常不会让所有规则立即消失;首次加载、缓存文件损坏或格式变化则可能导致 provider 无法就绪。日志中应重点查看 provider 名称、HTTP 状态、解析错误和本地路径,而不是只看最终连接失败。远端 URL 建议使用稳定的 HTTPS 地址,并根据更新频率设置合理间隔。一天变化一次的集合没有必要每几分钟下载。
| 现象 | 优先检查 | 处理方式 |
|---|---|---|
| 规则集显示不可用 | URL、网络、缓存目录权限 | 手动更新并查看 provider 日志 |
| 规则存在但未命中 | 主规则顺序、behavior 类型 | 用连接日志确认更早命中的规则 |
| 更新后大量域名失效 | 文件格式与内容结构 | 回退缓存并单独验证新文件 |
| DNS 请求异常增多 | IP 规则是否触发解析 | 调整域名规则顺序并评估 no-resolve |
规则订阅化并不意味着所有规则都应交给第三方维护。局域网域名、家庭服务器、公司测试环境和个人例外项属于本地事实,最好保留在自己的覆写文件中。公共规则集负责广泛分类,本地规则负责精确纠偏。每次大规模替换规则来源前,先保留旧缓存和主配置副本,再用几个明确目标验证直连、代理、拒绝三类结果。能解释每条测试连接为什么走到当前出口,才算完成迁移。
DNS 配置与解析路径优化
理解请求从哪里发出
DNS 配置的难点不是填写更多服务器,而是明确每次查询由谁发起、走哪条网络路径,以及返回结果如何进入规则判断。系统应用可能直接询问操作系统 DNS,也可能自行使用加密 DNS;启用 TUN 与 DNS 劫持后,常规的 53 端口查询可以交给 mihomo,但应用内置的加密解析仍可能绕过。出现“浏览器能开、其他应用不行”时,首先比较两者实际使用的解析方式,而不是反复更换节点。
nameserver 是主要上游,负责常规域名解析。default-nameserver 用于解析 DoH 或 DoT 上游自身的域名,因此通常填写可直接访问的 IP 地址。否则会出现“为了连接域名形式的 DNS 上游,先要解析这个上游域名;但解析又依赖尚未连接的上游”的循环。proxy-server-nameserver 可专门解析代理服务器地址,适合节点主机名需要通过稳定解析通道获得 IP 的情况。
nameserver-policy 可以按域名把请求交给指定上游。例如内部域名走局域网 DNS,特定服务走另一组解析器。它解决的是“不同域名由谁解析”,不是“解析后的连接走哪个策略组”;后者仍由规则决定。若策略范围写得过宽,可能让大量域名绕开主 nameserver。调整后应分别测试策略命中的域名、普通域名和节点域名,确认三条路径都能独立工作。
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver:
- https://dns.alidns.com/dns-query
- https://cloudflare-dns.com/dns-query
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
nameserver-policy:
"+.lan":
- 192.168.1.1
"+.internal.example":
- 192.168.1.1
fake-ip-filter:
- "*.lan"
- "*.local"
- "time.*.com"
- "time.*.gov"
并发上游不是简单的数量竞赛
增加上游数量不必然提高可靠性。多个解析器可能返回不同 CDN 地址、不同 IPv6 结果或不同地区线路,导致同一域名在短时间内表现不一致。更重要的是,上游之间的查询路径若不同,最快返回的结果未必适合最终出口。例如直连 DNS 返回的地址适合本地网络,但连接随后通过远端节点建立,目标 CDN 可能并非最佳。配置时应先确定主要出口,再选择与网络模型一致的上游组合。
ipv6 控制 DNS 模块是否返回 AAAA 结果,但系统是否真的能通过 IPv6 建立连接还取决于物理网络、TUN 栈、路由和代理节点。开启返回却没有可用 IPv6 路径,应用可能先尝试一个无法完成的连接,再回退到 IPv4,表现为首开缓慢。关闭 IPv6 只是排错手段,不应替代对链路能力的判断。若家庭宽带、服务器和节点都支持 IPv6,可以保留并分别验证直连与代理结果。
解析缓存能减少重复请求,但也会让错误结果持续一段时间。修改 hosts、nameserver-policy 或 fake-ip-filter 后,旧缓存可能仍被应用、系统或内核使用。标准排查顺序是重载配置、清理客户端 DNS 缓存、必要时清理操作系统缓存,再重新启动目标应用。只刷新网页通常不足以覆盖所有缓存层。浏览器还可能维护独立的连接池和 DNS 缓存,测试时使用新建窗口或完全退出重开更可靠。
本地域名与特殊服务的过滤
Fake-IP 模式下,部分设备发现、局域网服务、时间同步和依赖真实地址校验的应用不适合接收映射地址,应加入 fake-ip-filter。过滤范围要尽量小。直接加入过宽的通配符会让大量域名回到真实 IP 模式,削弱域名规则的稳定性。每增加一个过滤项,都应记录对应现象,例如投屏找不到设备、局域网主机名无法访问或时间服务拒绝响应,避免日后无法判断该例外是否仍有必要。
DNS 监听地址也涉及边界。桌面客户端只供本机使用时,不必把端口暴露给整个局域网;路由器作为网关服务其他设备时,则需要监听可达地址,并配合防火墙限制来源。监听成功不代表系统已经使用它,仍要检查系统 DNS、TUN 劫持和端口占用。若启动日志提示 bind 错误,可参考端口冲突定位流程,确认现有进程后再修改监听端口。
TUN 模式与 Fake-IP 协同
TUN 解决系统代理覆盖不到的连接
系统代理只对主动读取代理设置的应用有效。命令行程序、游戏、部分商店应用和直接发起 UDP 的软件可能完全忽略它。TUN 模式创建虚拟网络接口,从 IP 层接管经过系统路由的流量,因此覆盖范围更广。它不是“更强的全局模式”:规则模式、全局模式和直连模式决定接管后的分流方式,TUN 只负责把原本看不到的连接送进内核。
启用 TUN 通常需要管理员权限或系统授权。不同平台对虚拟接口、路由表和 DNS 设置的实现不同,客户端会尽量完成自动配置,但休眠恢复、网络切换、VPN 共存和安全软件拦截仍可能留下旧路由。出现启用后完全断网时,先关闭 TUN 并确认基础网络恢复,再检查日志中的接口创建、路由写入和 DNS 劫持错误。不要同时连续切换多个相关开关,否则很难判断是哪一步改变了系统状态。
auto-route 让内核自动写入路由,适合普通桌面环境。auto-detect-interface 用于识别当前默认出口,避免代理连接再次被送回 TUN 形成回环。多网卡、虚拟机、热点共享或同时连接有线与无线时,自动识别可能选到非预期接口;此时应查看路由表和日志中的实际接口,而不是凭接口名称猜测。strict-route 会更严格地限制旁路流量,能减少某些绕过情况,但也可能影响局域网访问和其他虚拟网络。
tun:
enable: true
stack: mixed
dns-hijack:
- any:53
- tcp://any:53
auto-route: true
auto-detect-interface: true
strict-route: false
mtu: 1500
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
Fake-IP 保存域名语义
传统 redir-host 方式先取得真实 IP,再把连接交给规则引擎。多个域名共享同一 CDN 地址时,仅凭 IP 很难判断原始目标。Fake-IP 会为查询的域名分配一段保留地址中的映射值,应用连接这个映射地址后,内核可以反查到原域名,再执行域名规则和远端解析。它的核心价值是保存域名语义,不是加速所有 DNS 查询。
映射地址通常只在运行中的内核与其缓存内有意义。看到应用连接 198.18.0.0/16 一类地址并不代表目标真的位于该网段。若 DNS 查询没有经过 mihomo,应用却拿到了此前的映射地址,或连接未被 TUN 接管,就可能出现“能解析但连不上”的断裂。因此 Fake-IP、DNS 劫持和流量接管必须作为同一链路检查。只开启 enhanced-mode,却让系统继续使用其他 DNS,配置不会完整生效。
UDP 是 TUN 排错中容易遗漏的一层。语音、游戏、QUIC 和部分 DNS 查询依赖 UDP,节点协议、客户端设置与目标服务都要支持相应路径。网页能打开只能证明部分 TCP 流量正常,不能证明 TUN 的 UDP 链路完整。排查时可先测试普通 TCP,再测试 DNS UDP、QUIC 或实际应用;若只有 UDP 失败,检查节点能力、规则策略和系统防火墙,而不是立刻否定整个 TUN 配置。
| 组合 | 域名规则能力 | 典型用途 | 注意事项 |
|---|---|---|---|
| 系统代理 + 常规 DNS | 取决于应用提交域名还是 IP | 浏览器和常规桌面软件 | 忽略系统代理的应用无法覆盖 |
| TUN + redir-host | 基于真实解析结果补充判断 | 需要真实 IP 的兼容场景 | 共享 IP 可能降低域名识别精度 |
| TUN + Fake-IP | 保留查询域名并稳定匹配 | 规则分流与全设备接管 | DNS 与连接必须同时进入内核 |
MTU、局域网与其他隧道
某些网络下,小请求正常而上传、视频或大页面卡住,可能与 MTU 和分片有关。TUN 包装会增加额外开销,底层网络若不允许相应大小的数据包通过,连接会在特定负载下停滞。调整 MTU 应小步进行,并用可重复的大文件请求验证,不能把任意断流都归因于 MTU。若只在某个节点出现,还要比较该节点协议与传输层的额外开销。
局域网访问失败时,先确认私有网段规则位于前部并指向 DIRECT,再检查 strict-route、防火墙和目标设备是否允许当前接口访问。与其他 VPN 同时运行时,两个程序都可能修改默认路由和 DNS,最终结果由路由优先级决定。最可靠的验证方法是先单独启用 Clash,再逐项恢复其他隧道;如果必须共存,应明确哪些网段由哪个接口负责,而不是依靠启动顺序碰运气。
域名嗅探与目标还原
嗅探处理的是“只看到 IP”的连接
规则引擎最希望获得域名,因为域名通常比共享 IP 更能表达业务含义。但有些连接进入内核时只有目标 IP,例如应用使用自己的 DNS、系统缓存了真实地址,或透明代理阶段没有携带域名。域名嗅探会读取连接初期可见的协议信息,从 HTTP Host、TLS SNI 等字段中还原目标域名,再交给域名规则判断。它补充的是缺失信息,不是替代 DNS。
嗅探能力受协议本身限制。明文 HTTP 的 Host 通常可见,TLS 握手中的 SNI 在常见情况下也能提供域名;如果应用使用不含域名的连接方式、协议内容不可识别,或加密机制隐藏了握手信息,嗅探就无法恢复。UDP 协议的可见性也不同,不能假设所有流量都能得到域名。配置规则时仍应保留合理的 IP 规则与兜底策略。
override-destination 决定识别出域名后是否用它替代原目标参与连接处理。开启后有助于让域名规则与远端解析生效,但在少数依赖固定 IP、证书行为特殊或目标域名与连接地址刻意不一致的应用中可能产生兼容问题。更稳妥的方式是先针对常见端口启用,再通过 skip-domain 或跳过源地址为已知异常应用建立小范围例外。
sniffer:
enable: true
force-dns-mapping: true
parse-pure-ip: true
override-destination: true
sniff:
HTTP:
ports:
- 80
- 8080-8880
override-destination: true
TLS:
ports:
- 443
- 8443
QUIC:
ports:
- 443
skip-domain:
- "Mijia Cloud"
- "+.push.apple.com"
force-dns-mapping 与 parse-pure-ip
force-dns-mapping 会让嗅探器关注与 DNS 映射相关的连接,适合 Fake-IP 链路。parse-pure-ip 则允许尝试分析目标表现为纯 IP 的流量。两者开启后覆盖面更大,也意味着更多连接会进入识别过程。现代设备通常能够承担这部分开销,但路由器等资源有限环境仍应观察连接数、CPU 和日志量,不应仅因为参数存在就全部打开。
端口范围是控制嗅探准确度的重要边界。HTTP 嗅探若覆盖所有端口,非 HTTP 协议的初始数据可能被反复尝试解析,既增加开销,也提高误判机会。应从明确的 80、8080 和常见 Web 端口开始;TLS 通常集中在 443 与少量自定义端口。某个应用确实使用特殊端口时,再根据连接日志补充。配置越具体,后续解释一次匹配结果就越容易。
嗅探与 Fake-IP 都能帮助恢复域名,但触发阶段不同。Fake-IP 在 DNS 查询时建立映射,应用随后连接映射地址;嗅探则在连接已经到达后,从协议握手中提取信息。前者通常更稳定,后者是绕过内核 DNS、真实 IP 连接和透明代理场景的重要补充。如果同一连接存在映射域名和嗅探域名,应查看日志中最终采用哪一个,尤其注意 CDN 跳转或证书使用通用域名的情况。
误判时不要直接关闭全部嗅探
某个应用启用嗅探后异常,先定位具体连接。日志中检查原始目标 IP、还原域名、命中规则和最终策略。如果还原出的域名明显不属于目标业务,可将该域名加入跳过列表,或缩小对应协议的端口范围。若只有一个局域网服务异常,可以对其域名或网段做例外;直接关闭全局嗅探会让其他依赖域名识别的连接退回 IP 规则,可能引入更多难以察觉的分流变化。
测试嗅探时应选择规则结果明确的域名。准备一个应直连和一个应代理的服务,清理应用连接缓存后分别访问,再查看连接详情是否显示域名。如果只看到 IP,检查流量是否经过 TUN、协议是否可识别、端口是否包含在 sniff 范围。若域名已显示但策略错误,问题在规则顺序或策略组,而不在嗅探。把“识别目标”和“选择出口”拆开判断,可以避免在错误层面反复改参数。
域名嗅探也不能修复错误 DNS。应用若在连接前已经得到不可达地址,嗅探虽然可能识别域名,但底层路由、证书或目标服务仍可能受影响。稳定配置通常以正确的 DNS 接管为主,以嗅探补充纯 IP 连接,再用 IP 规则覆盖无法还原的流量。三层各自负责一个问题,叠加后才形成完整判断链。
本地覆写与多订阅合并
把上游配置视为可更新输入
订阅配置由服务提供方维护,更新时可能替换代理节点、策略组和规则。如果直接在订阅生成的文件里修改,下一次更新通常会覆盖本地内容。正确思路是把订阅视为输入,把本地需求放在独立覆写层:订阅负责节点与基础结构,本地层负责端口、DNS、TUN、规则优先级和专用策略组。Clash Plus 等图形客户端通常提供配置覆写、脚本或合并入口,具体名称可能不同,但目标都是让本地修改可重复应用。
覆写有“替换”和“合并”两种语义。标量字段如 mixed-port、mode 通常直接替换;映射字段如 dns 可以按键合并,也可能整体覆盖;数组字段如 rules 和 proxy-groups 最容易产生歧义。某些客户端将新数组追加到尾部,某些会按名称合并,还有些会完整替换。因此在使用任何合并脚本前,先导出最终配置,确认实际结果,而不是只检查输入片段。
规则数组尤其需要区分前置和后置。自定义直连规则放到 MATCH 之后不会生效;修正某个业务分流的规则通常应插入远端通用规则之前。若合并工具支持 prepend 与 append,应明确选择。策略组按名称合并时,也要避免本地组与上游组同名却类型不同,否则更新后可能保留旧字段,形成难以理解的混合结构。
# 本地覆写示意:具体合并入口由客户端提供
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
dns:
enable: true
enhanced-mode: fake-ip
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
rules:
- DOMAIN-SUFFIX,internal.example,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
多订阅不等于简单拼接
合并多个订阅时,最先遇到的是名称冲突。不同来源可能都包含“自动选择”“节点选择”或完全相同的节点名。若客户端按名称去重,后加入的项目可能覆盖前者;若不去重,界面上会出现难以区分的重复项。可以在 provider 层保留不同来源名称,再建立自己的统一策略组,通过 use 同时引用多个 provider。这样不必把所有节点展开到静态数组,也能单独暂停某个来源。
第二个问题是更新周期。多个订阅若同时频繁更新,会增加请求量,并在配置重载时打断现有连接。节点信息通常不需要分钟级刷新。可以让 provider 按较长周期更新,手动更新则用于服务方明确变更或节点异常后的验证。健康检查与订阅下载是两件事:前者测试现有节点,后者获取新的节点清单。不要用极短订阅更新间隔替代健康检查。
第三个问题是来源之间的能力差异。某些节点支持 UDP,某些不支持;部分线路适合固定地区业务,另一些适合一般浏览。单一自动组把全部节点混在一起,可能选择到不符合业务要求的出口。应按可验证的命名或来源建立专用组,例如“来源 A 自动”“来源 B 备用”,顶层“节点选择”再引用这些组。若节点名称不能稳定表达能力,只能通过实际连接测试与手动分组维护。
| 合并对象 | 推荐方式 | 常见风险 |
|---|---|---|
| 端口与运行模式 | 本地标量覆盖 | 端口占用、客户端重载后失效 |
| DNS 与 TUN | 本地维护完整模块 | 部分字段合并后语义冲突 |
| 规则 | 明确前置、后置和兜底位置 | 自定义规则落在 MATCH 之后 |
| 多个节点订阅 | 分别建立 proxy-provider | 节点重名与更新相互覆盖 |
| 策略组 | 本地建立稳定业务层 | 与上游同名但类型不同 |
建立可回退的修改流程
每次修改前保留上一份能工作的最终配置,而不只是保存覆写片段。最终配置能反映合并后的真实顺序,也便于比较哪一段发生变化。建议一次只调整一个模块:先策略组,再规则,再 DNS,最后启用 TUN 与嗅探。每一步至少验证配置可加载、基础网页可访问、一个直连目标和一个代理目标符合预期。多项同时修改虽然省操作,但失败时无法快速定位。
订阅更新后若出现异常,先比较 provider 是否成功、策略组是否为空、规则引用的名称是否仍存在。很多问题并非节点失效,而是上游把策略名称改掉,本地规则仍引用旧名称。内核加载时通常会报告找不到策略或 provider;如果客户端只显示“配置失败”,应打开详细日志查看具体键名。不要为了恢复连接而立刻删除全部本地覆写,这会丢失最有价值的差异线索。
本地覆写应保持短而有解释。可以按模块写注释,记录某项规则解决的具体问题,但不要把长期失效的试验参数一直留在文件中。每隔一段时间审查例外项:确认目标服务仍存在、远端规则集是否已经覆盖、旧网络环境是否已经更换。配置维护的目标不是字段越来越多,而是每个保留字段都能说明用途和边界。
外部控制面板与 API 边界
控制端口可以做什么
mihomo 的外部控制接口允许图形客户端或 Web 面板读取策略组、切换节点、查看连接、触发 provider 更新和调整部分运行状态。桌面客户端中的策略页面、连接列表和日志窗口,很多都建立在这套接口之上。它是控制面,不是代理入口;mixed-port、HTTP 端口和 SOCKS 端口负责转发流量,external-controller 只处理管理请求。
只在本机使用时,将控制地址绑定到回环接口最稳妥。绑定 127.0.0.1 后,局域网其他设备无法直接访问。若需要从另一台设备管理路由器上的内核,可以监听局域网地址,但必须同时设置访问凭据、限制防火墙来源,并避免把端口映射到公网。管理接口能够观察连接目标和改变出口,权限应等同于本机管理权限。
external-controller: 127.0.0.1:9090
secret: "your-password"
# 可选:由内核托管本地控制面板文件
external-ui: ./ui
secret 为空时,能够访问控制端口的程序可能无需认证即可调用接口。本机回环环境仍应考虑同机其他进程的访问风险;局域网监听则必须设置凭据。示例中的值只是明显的教学值,实际使用时应替换为独立凭据,不与订阅地址、系统账户或其他服务共用。面板连接失败时,检查地址、端口、协议和凭据是否完全一致。
external-ui 指向静态面板文件目录。内核托管这些文件后,可以通过控制地址打开界面;也可以使用客户端内置的控制面板。界面文件与内核 API 需要兼容,若页面能加载但策略组为空,先查看浏览器网络请求和控制接口响应,而不是重新下载节点订阅。静态文件加载成功只证明 Web 资源可达,不代表 API 认证已经通过。
局域网访问与反向代理
在家庭服务器或路由器上使用时,常见结构是控制端口只监听本机,再由受控的反向代理提供 HTTPS 入口。这样可以集中处理访问控制和证书,也能避免直接暴露管理端口。但反向代理配置错误可能丢失 WebSocket 或认证头,表现为面板首页正常、连接列表无法实时更新。排查时分别测试静态页面、普通 API 请求和实时连接通道,确认问题位于哪一层。
若直接监听 0.0.0.0,必须检查设备防火墙。allow-lan 主要控制代理端口是否允许局域网设备使用,不应被误认为控制接口的防火墙。控制接口是否可达取决于它自己的监听地址和系统网络规则。可以从局域网另一台设备测试端口,但测试完成后仍应限制来源网段,不要把“暂时访问方便”固化成长期开放状态。
控制面板中显示的连接信息来自内核当前状态。切换策略通常只影响新建连接,已经建立的 TCP 会话可能继续使用旧节点,直到连接关闭。测试节点切换时,应在面板中关闭旧连接或重启目标应用,再观察新连接的链路。只看策略组当前选项,不能证明正在传输的会话已经迁移。
| 访问场景 | 监听建议 | 额外控制 |
|---|---|---|
| 桌面客户端本机管理 | 127.0.0.1:9090 |
设置独立凭据,避免端口冲突 |
| 家庭局域网管理 | 设备局域网地址 | 防火墙限制来源设备或网段 |
| 反向代理访问 | 控制端口仍绑定本机 | HTTPS、认证与实时连接转发 |
| 容器运行 | 容器内部接口 | 只映射必要地址与端口 |
API 排错顺序
面板无法连接时,先在运行内核的设备上确认控制端口正在监听,再从访问端测试网络可达性,最后检查认证。三步顺序不能颠倒:端口未监听时修改浏览器设置没有意义,网络被防火墙拦截时反复更换凭据也不会成功。若端口与其他程序冲突,修改控制端口后还要同步更新客户端或面板地址。
面板可以提高观察效率,但不应成为唯一配置来源。重要修改仍应落在可备份的 YAML、覆写文件或客户端配置中。只在运行时通过 API 切换的状态,重启或重载后可能恢复默认。长期使用的策略选择可以依赖客户端持久化,结构性变更则应回到配置文件。把临时操作与持久配置区分开,才能避免“界面里改过但重启后消失”的问题。
远程管理还要控制日志范围。连接列表可能包含目标域名、来源地址和流量信息,不适合在不受控网络中公开。日常运行使用满足排错需要的日志级别即可,遇到问题时短期提高详细度,完成后恢复。外部控制面板的价值在于看清规则与连接,不在于长期保存所有访问记录。
配置验证、联调与故障定位
先验证语法,再验证行为
配置排错分为两层。第一层是结构是否能被内核读取,包括 YAML 缩进、字段类型、策略引用和 provider 格式;第二层是加载成功后,实际连接是否按预期经过 DNS、规则和策略组。语法通过只说明文件可解析,不代表分流正确。反过来,应用无法联网也不一定是配置语法错误,可能只是某条规则选择了不可用节点。
YAML 使用空格表达层级,Tab、错误缩进和冒号后的格式都会改变结构。列表项前的短横线必须位于正确层级,布尔值和数字不需要引号,包含特殊字符的名称或 URL 则可以加引号。策略组名称属于精确引用,“节点选择”和“节点选择 ”看起来接近,但尾部空格会形成两个不同字符串。配置较长时,先从日志报告的行附近检查,再向上寻找所属模块。
mihomo 可通过命令行检查配置目录,具体可执行文件名取决于平台与安装方式。下面的命令表达常见检查方式:指定配置目录后进行测试,不直接启动长期服务。图形客户端用户也可以使用其配置检查功能,并查看核心日志中的首个错误。后续错误常由第一个结构错误连锁产生,应从最早出现的一条修复。
mihomo -t -d /path/to/config-directory
# 若需要以前台方式观察加载过程
mihomo -d /path/to/config-directory
建立最小验证矩阵
每次修改后至少验证四类目标:局域网地址应直连,一个明确的普通站点按预期策略连接,一个只在代理出口可用的目标经过代理,以及一个未被专用规则覆盖的目标落入兜底组。若启用 TUN,再增加一个忽略系统代理的应用;若启用 IPv6,再分别验证 A 与 AAAA 连接。固定测试对象能让不同配置之间具有可比性。
连接日志应按处理链阅读。先看入站类型,确认连接来自 HTTP、SOCKS 还是 TUN;再看目标是域名还是 IP,判断 DNS 映射或嗅探是否工作;随后看命中的规则和策略组;最后看实际节点或 DIRECT。如果入口就不对,继续调整规则没有意义。如果规则正确但节点错误,问题在策略组选择。如果节点正确仍无法连接,再检查节点能力、目标服务和底层网络。
DNS 问题应单独验证。记录查询域名、上游、返回类型和连接目标,避免仅凭“网页打不开”推断 DNS 错误。可以暂时使用简单的 nameserver 配置建立基线,再逐步恢复 policy、Fake-IP 过滤和多上游。每恢复一项都重复相同测试。复杂 DNS 配置一次性整体替换,很容易把上游不可达、策略范围过宽和缓存残留混为一个问题。
| 故障表现 | 最可能层级 | 首个检查动作 |
|---|---|---|
| 配置无法加载 | YAML 或字段引用 | 读取首条核心错误并检查对应层级 |
| 浏览器正常,其他应用失败 | 系统代理覆盖或 TUN | 确认失败应用的连接是否进入内核 |
| 域名规则未命中 | DNS、嗅探或规则顺序 | 查看连接目标显示为域名还是 IP |
| 切换节点后仍走旧线路 | 既有连接未关闭 | 关闭旧连接并重新发起请求 |
| 小请求正常,大传输停滞 | MTU、UDP 或传输链路 | 比较不同节点并检查分片相关现象 |
| 更新订阅后策略为空 | provider 或名称合并 | 确认 provider 状态与策略组引用名称 |
一次只改变一个变量
有效排错依赖可重复。关闭所有高级功能后恢复基础连接,再依次启用 DNS、Fake-IP、TUN、嗅探和规则 provider,是比随机切换开关更快的路径。每一步记录改动和结果,失败时回到上一份可用配置。若客户端支持配置副本,可以建立“基础”“TUN 测试”“完整规则”三个独立配置,避免在同一文件上持续覆盖。
端口类错误应确认具体监听者。mixed-port、DNS 监听和 external-controller 都可能与其他程序冲突,错误日志中的端口号决定要检查哪一项。修改端口后,系统代理、面板地址或其他依赖端也要同步更新。详细命令与平台差异可参考Clash 端口被占用的定位流程。
节点全部超时时,先判断健康检查地址是否可达,再手动测试一个节点。若所有 provider 同时失败,问题更可能位于本地网络、DNS、订阅更新或系统时间,而不是所有节点恰好同时失效。若只有某一来源失败,则检查该 provider 的 URL、缓存和节点协议。首次连接的基础验证可回到选节点、测延迟与确认代理生效逐项核对。
性能调整建立在正确性之后
缩短健康检查间隔、增加 DNS 上游、扩大嗅探范围和启用更多规则集都会增加工作量,但不一定改善体验。先用默认或保守参数得到正确、稳定的处理链,再根据明确现象调整。网页首开慢可以分别测 DNS 时间与连接时间;节点切换频繁可以提高 tolerance 或延长检测间隔;路由器负载高可以减少规则集数量、降低检查频率并缩小嗅探端口范围。
日志级别同样影响观察与开销。日常使用保留一般信息即可,问题复现期间临时提高详细度,记录完成后恢复。长期输出大量连接细节会增加磁盘写入,也会积累不必要的访问记录。排错日志应包含问题发生前后的完整链路,但不需要无限保留。
一份成熟配置不以字段数量衡量。更重要的是入口、解析、匹配、决策和出口五个阶段都能被解释,并且任何高级功能都可以独立关闭而不破坏基础连接。完成本页的模块化配置后,建议导出最终 YAML 与覆写文件,记录客户端中的关键开关。需要更换设备时,可先从下载页选择对应平台客户端,首推支持多平台的 Clash Plus,再按模块逐项恢复,而不是直接复制一份无法解释的庞大配置。