MIHOMO / CONFIGURATION REFERENCE

Clash YAML 配置文件参考

结构总览 · 字段含义 · 引用关系 · 生效检查

本页面向需要编辑配置、维护规则或排查字段冲突的用户。先确认配置由哪个客户端生成,再检查内核最终读取的内容。首次安装、导入订阅和连接验证请先阅读使用指南;本手册按字段之间的依赖关系展开,适合在修改时逐章查阅。

示例以 mihomo 配置语义为基础,不代表所有 Clash 分支都支持相同字段。图形客户端可能接管端口、DNS、TUN 或控制接口。尚未选择客户端时,可从下载页查看首推的 Clash Plus 及各平台其他选择,再结合客户端的实际配置入口操作。

1. YAML 结构与配置加载边界

配置文件首先是一份有类型、有层级的数据,不是一组按行执行的命令。顶层的 mixed-port 描述监听端口,dns 是映射,proxies、proxy-groups 与 rules 通常是列表。内核先解析数据,再创建监听器、解析代理和策略组,最后接收连接。因此,配置中的书写先后不等于启动步骤,但规则列表内部的顺序会影响匹配结果。

缩进、类型与名称引用

统一使用两个空格缩进,不使用制表符。同一父级下的字段必须对齐;列表项前的短横线表示新元素,不是装饰符号。把 enable 写到 dns 同级,会改变字段归属;把 rules 缩进到策略组内部,也不会得到预期的顶层规则。编辑器显示缩进参考线,比仅观察文字是否整齐更可靠。

布尔值写成 true 或 false,端口与时间间隔通常写成整数。节点名称、密码和包含特殊符号的内容建议加引号,尤其是带有冒号后接空格、井号或前导零的字符串。引号不能修复错误缩进,也不能把列表自动变成映射;报错时应先确认结构,再检查值的类型。

代理与策略组通过名称相互引用。名称中的空格、大小写和中文标点都属于实际内容,"手动选择" 与 "手动 选择" 是两个不同名称。新增规则之前先确认目标名称存在,删除节点之前先搜索哪些策略组仍在引用它。名称重复也应清理,否则界面显示和实际解析可能难以对应。

建立能启动的本地基线

下面的配置只建立本地混合代理入口,所有请求最终直连。它适合确认文件路径、端口监听和规则解析是否正常,不提供远程代理能力。测试时让浏览器使用本机的混合端口,或者暂时启用客户端系统代理;不要把“内核成功启动”误认为“已经连接远程节点”。

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false

proxies: []

proxy-groups:
  - name: "手动选择"
    type: select
    proxies:
      - DIRECT

rules:
  - MATCH,手动选择

先保留一份已经验证的基线,再逐次加入真实节点、自动测试组和 DNS。每完成一类修改就重新加载并检查日志,能够把故障范围限制在最近变更内。如果一次性替换整份配置,语法、网络、引用和客户端覆写问题会同时出现,定位成本明显增加。

YAML 映射中不要重复定义同一个键。例如文件前半段和后半段各出现一次 dns,不代表两个区域会自动合并。不同解析器可能拒绝重复键,也可能保留后一个结果;依赖这种行为会使同一文件在不同客户端中出现差异。需要合并时应在生成阶段得到唯一的顶层字段。

区分源文件与运行文件

订阅下载的原始文本、用户编辑的配置、客户端生成的运行配置,可能是三份不同文件。客户端通常在启动前追加管理接口或替换端口,所以手工编辑运行目录中的文件,下一次更新就可能被覆盖。应优先使用客户端提供的本地配置、扩展配置或覆写入口,并确认该入口的作用范围。

配置报错中的行号指向内核实际读取的文件,不一定对应订阅原文。遇到引用缺失或字段不符时,先在客户端查看当前启用的配置名称与运行配置内容。分享排错材料前,应移除订阅地址、节点密码和控制接口密钥;只保留足以复现问题的结构,不能直接公开完整运行文件。

2. 通用字段、监听端口与运行模式

通用字段决定流量从哪里进入内核,以及内核采用哪种处理方式。它们不负责创建远程节点,也不会自动修改所有应用的网络设置。排查时先分清“内核正在监听”“系统代理已经设置”“应用愿意使用系统代理”这三个状态,避免把入口问题当成节点故障。图形客户端中的开关与 YAML 字段可能有关联,但不是同一个层次。

选择端口与监听范围

字段主要用途使用边界
portHTTP 代理监听端口供支持 HTTP 代理的应用使用
socks-portSOCKS 代理监听端口应用需选择对应代理协议
mixed-port同一端口接收 HTTP 与 SOCKS 请求常用于桌面客户端的统一入口
allow-lan是否允许局域网设备接入需同时检查绑定地址与防火墙
bind-address监听的本地地址范围不负责配置路由器端口转发

混合端口适合让多个应用共享一个入口,独立端口则便于区分 HTTP 与 SOCKS 的接入行为。没有业务需求时不必同时开启全部入口。两个监听器不能占用同一地址上的同一个端口;端口冲突也可能来自另一套代理软件、旧内核进程或客户端未退出的后台服务,而不是当前配置写错。

mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false

本机使用时优先限制在回环地址。确实需要让手机或其他电脑通过当前设备转发时,再配置局域网监听,并按网络范围设置防火墙与访问认证。只把 allow-lan 改为真,并不能保证其他设备能连接;只开放防火墙,也不能让绑定在回环地址上的服务接受外部请求。

规则、全局与直连模式

mode: rule 按 rules 从上往下匹配,适合日常分流。global 使用全局策略选择出站,不按普通规则列表决定目标;direct 则用于直连。界面切换模式后,原文件里的 mode 不一定同步改变,因为客户端可能通过控制接口修改运行状态。应以当前界面状态和连接记录为准。

全局模式不能修复不经过内核的流量。如果某个应用绕过系统代理,在规则模式下没有连接记录,切换全局后通常仍然没有记录。需要先检查应用自己的代理设置,或者在确有必要时使用 TUN。相反,连接已经进入内核但匹配到了直连规则,才应进一步分析模式与规则顺序。

log-level 影响日志详细程度,不改变分流逻辑。日常使用保留 info,复现疑难问题时临时使用 debug,完成后恢复。详细日志可能包含域名、目标地址与访问时间,保存和分享时应控制范围。看到一条超时日志不能直接认定所有流量都失败,应确认它对应的是节点握手、DNS 还是健康检查。

控制接口与持久化状态

external-controller 是控制接口,不是浏览器应该填写的代理端口。它通常用于读取连接、切换策略组或更新运行配置。把应用代理地址填成控制接口,会造成协议不匹配。手动运行内核时可以按需要启用;图形客户端通常会自行生成并管理相关参数,不宜再用覆写强行占用同一地址。

控制接口一旦需要启用,优先绑定回环地址并设置独立密钥,不要直接暴露到公共网络。示例中的密钥只是结构说明,实际使用需自行生成。若客户端已有访问凭据管理功能,应使用客户端入口,而不是把示例值长期保存在公开配置仓库中。

external-controller: "127.0.0.1:9090"
secret: "replace-with-a-local-random-secret"

profile:
  store-selected: true
  store-fake-ip: true

store-selected 用于保留策略组选择,store-fake-ip 用于保留假地址映射状态。持久化不会替代配置本身:策略组改名后,旧名称的选择记录未必能继续应用。修改模式、端口和存储选项后,应分别验证入口、路由与重启行为,不能只凭界面上的开关位置判断所有设置都已经生效。

3. 代理节点字段与节点提供者

代理节点定义一次具体的远程连接能力,策略组负责从这些能力中选择。节点名称只是引用标签,协议、服务器、端口和认证参数才决定能否建立连接。修改名称不会改变节点所在位置,也不会降低网络延迟。来自不同服务的同名节点应先重命名,再放进同一配置,避免策略组引用出现歧义。

按协议填写最小字段

proxies 中的每一项都是一个代理对象,至少需要能被当前协议识别的类型与连接参数。不要把其他协议的字段机械复制过来:Shadowsocks 的加密方法、Trojan 的密码、其他协议的用户标识,承担的角色不同。配置解析成功只说明格式通过,不代表远端会接受这些参数。

proxies:
  - name: "示例 SS"
    type: ss
    server: "proxy.example.com"
    port: 8388
    cipher: chacha20-ietf-poly1305
    password: "your-password"
    udp: true

  - name: "示例 Trojan"
    type: trojan
    server: "gateway.example.net"
    port: 443
    password: "your-password"
    sni: "gateway.example.net"
    skip-cert-verify: false
    udp: true

server 是实际连接的服务器地址,port 是远端服务端口,不能填写本地混合端口。服务器为域名时,节点连接之前需要完成解析,这也是 DNS 配置可能影响所有代理的原因。服务器改用 IP 后,若协议需要 TLS,仍应保留服务端要求的正确域名参数,不能把地址与身份校验混为一谈。

udp: true 表示该节点配置允许相应的 UDP 转发能力,并不保证整条链路支持所有 UDP 应用。还要检查协议实现、服务端设置、网络限制和应用接入方式。浏览器访问正常而语音通信失败时,应先确认实际传输类型,不能仅通过网页打开速度推断 UDP 是否可用。

TLS 身份与传输参数

TLS 连接中,服务端地址与 sni 可以承担不同职责:前者决定连接到哪里,后者用于握手时声明目标名称。证书验证还要求名称、有效期与信任链符合条件。遇到证书错误时,先检查设备时间、节点域名、服务端证书和网络是否被重定向,不应把关闭验证当成常规修复步骤。

skip-cert-verify: false 保留正常验证。设为真会改变连接的信任边界,不会解决服务器不可达、密码错误或协议不匹配。如果服务配置使用 WebSocket、gRPC 等传输,还需要与服务端一致的路径、主机名或服务名;仅凭一个服务器地址和端口,无法推导出这些参数。

节点字段受内核功能支持范围影响。原版 Clash、不同分支与 mihomo 对协议和扩展字段的支持并不完全相同。导入时报出不支持的代理类型,应检查客户端实际使用的内核,而不是反复修改缩进。内核与界面的分工可参阅Clash、mihomo 与客户端关系图谱。

使用 proxy-providers 管理外部节点

节点提供者把外部节点列表作为独立资源加载,适合让策略组引用持续更新的节点集合。它不是任意订阅格式的通用导入器,远端内容需要是内核支持的节点提供者格式,常见结构以 proxies: 为根。客户端能导入的整份订阅,不一定可以直接作为提供者地址使用。

proxy-providers:
  remote-nodes:
    type: http
    url: "https://config.example.com/proxies.yaml"
    path: ./providers/remote-nodes.yaml
    interval: 3600
    health-check:
      enable: true
      url: "https://www.example.com/"
      interval: 600

proxy-groups:
  - name: "订阅选择"
    type: select
    use:
      - remote-nodes
    proxies:
      - DIRECT

interval 在这里控制资源更新频率,单位为秒;健康检查中的同名字段控制检测频率,两者不是一回事。path 用于本地缓存,手动运行时需确认工作目录和写入权限;不同提供者不要共用同一个缓存路径。远程更新失败时,还要区分首次加载没有缓存与已有缓存可继续使用的情况。

提供者地址通常包含访问凭据,不应放进截图或公共仓库。排查时可以保留域名并移除路径中的敏感内容,同时检查更新日志、返回格式和节点数量变化。节点已更新但策略组没有显示新名称时,继续检查组中的 use、筛选条件与当前启用配置,不能只重复点击更新按钮。

4. 策略组类型、测试与选择状态

策略组是规则与节点之间的稳定接口。规则可以始终指向“业务出口”,而组内节点按需要替换,这比在每条规则中写死节点名更易维护。策略组本身不提供远程服务,它最终仍需选择一个节点、另一组或内置出站。组名应表达用途,节点名表达连接对象,二者分开后更容易阅读连接记录。

手动选择与自动测试

select 保留人工决策,适合按业务、网络或地区手动选择。组中的顺序影响列表显示,但启用了选择持久化后,启动时不一定回到第一项。url-test 根据指定测试地址的结果选择候选项,适合在一组相近节点之间自动调整。自动结果取决于测试目标,不能解释为所有网站都具有同样表现。

proxy-groups:
  - name: "业务出口"
    type: select
    proxies:
      - "自动选择"
      - "示例 SS"
      - DIRECT

  - name: "自动选择"
    type: url-test
    proxies:
      - "示例 SS"
      - "示例 Trojan"
    url: "https://www.example.com/"
    interval: 300
    tolerance: 80
    lazy: true

这段配置依赖上一章中同名节点,单独复制会缺少引用。interval 是测试间隔,tolerance 是切换容差,二者不能互换单位。适当容差可以减少结果轻微波动时的频繁切换,但它不负责保证会话连续,也不能让已经失败的节点继续正常传输。数值应结合节点数量、网络稳定性和测试成本调整。

lazy: true 允许组在未被实际使用时减少不必要的检测,因此刚启动时没有完整测试结果并不一定异常。手动触发检测后仍失败,应确认测试地址本身可达、证书正常,以及节点能否完成请求。测试产生的流量也会经过节点,过短的间隔会增加设备、网络与服务端负担。

故障转移与负载分配

fallback 重点是优先级:通常按候选顺序选择可用项,适合保留主要出口和备用出口。它与追求较低测试延迟的 url-test 不同。若第一项长期可用,后面的节点可能很少承载业务,这是优先级策略的正常结果,不意味着它们没有被正确加入组中。

load-balance 用于在多个候选之间分配连接,不是把多个节点的带宽简单叠加给一条下载。不同分配策略会影响同一目标的出口稳定性。需要固定登录地区或保持服务端会话的业务,应先评估出口变化的影响;不能只因为组内节点多,就默认负载分配比手动选择更合适。

已有连接通常不会因为策略组切换而自动迁移到新节点。浏览器长连接、流媒体会话或后台通信可能继续使用旧出口,新建连接才体现新选择。验证组切换时可关闭对应连接或重新发起请求,但应了解这会中断正在传输的任务。把旧连接未变化误判为配置未加载,是常见排错偏差。

提供者引用、筛选与循环依赖

组内的 proxies 引用明确列出的名称,use 引用节点提供者。两种方式可以按需要组合,便于保留直连选项或固定节点,同时载入动态节点集合。筛选通常通过 filter 等字段作用于候选名称;正则表达式应加引号,并先确认筛选后至少有一个预期候选。

proxy-groups:
  - name: "远程出口"
    type: select
    use:
      - remote-nodes
    filter: "(?i)office|backup"
    proxies:
      - DIRECT

提供者中的名称变化会影响筛选结果。若节点列表突然减少,先检查更新后的原始名称与正则,再检查网络。不要通过扩大匹配到所有节点来掩盖命名问题,否则可能把原本不适用于该业务的出口加入组中。修改复杂筛选前,先以无筛选的小配置确认提供者确实加载成功。

策略组可以引用其他策略组,但不能形成循环,例如甲引用乙、乙又引用甲。分层结构应有明确终点,最终落到实际节点或内置出站。自动组再嵌套自动组也会增加解释成本;连接失败时需要逐层确认当前选择,而不是只看最外层组名。关于测试数字与实际体验的差别,可继续阅读Clash 延迟测试原理。

5. 规则语法、匹配顺序与规则提供者

规则模式采用从上到下的匹配顺序,第一条命中的规则决定连接交给哪个出站。后面的规则通常不会再参与同一连接的目标选择。因此,规则是否存在不如规则所在位置重要。精确例外放前面,范围较大的规则放后面,最后用 MATCH 明确兜底,能够让连接记录中的判断路径保持可解释。

域名规则与 IP 规则

DOMAIN 匹配完整域名,DOMAIN-SUFFIX 匹配指定域名及其子域,DOMAIN-KEYWORD 按关键词匹配。关键词规则覆盖范围更宽,容易把不相关域名纳入同一策略;维护业务分流时,优先使用明确域名或后缀。域名规则只处理主机名称,不是完整 URL,不能把协议头、路径或查询参数写进去。

rules:
  - DOMAIN,api.example.com,业务出口
  - DOMAIN-SUFFIX,example.net,业务出口
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - MATCH,业务出口

IP 规则处理目标地址范围,与域名规则关注的对象不同。no-resolve 用于避免该条 IP 规则为了判断域名请求而主动触发解析;若请求本身已有目标 IP,仍可参与匹配。它不等于跳过整条规则,也不表示所有 DNS 请求都被关闭。应结合应用交给内核的是域名还是 IP 来理解命中结果。

一项业务可能涉及登录、接口、静态资源和更新等多个域名。只分流首页域名,页面能打开但登录失败,是规则覆盖不完整的典型情况。应通过连接记录补齐实际依赖,而不是立即改为宽泛关键词或全局模式。若域名已知却只看到 IP,还需检查应用是否自行解析以及 DNS 是否经过内核。

规则目标与数据依赖

规则最后的目标可以是现有代理、策略组或内置出站,例如 DIRECT、REJECT。把目标写成一个不存在的组名,会导致加载错误或配置不可用。建议大多数业务规则指向用途稳定的策略组,避免节点改名时需要逐行修改。拒绝规则应尽可能精确,错误拦截认证或证书相关请求会产生难以直接识别的连锁故障。

GEOIP 等规则依赖相应的地理数据,规则提供者则依赖外部资源。配置文件语法正常,但数据文件缺失、下载失败或缓存路径不可写,仍可能无法完成初始化。排查日志时要区分“规则字符串不合法”和“规则所需资源不可用”,两者应采用不同修复路径。

进程相关规则受操作系统、权限与接入方式限制,不能假定桌面上可用的进程规则在路由器转发场景中也能识别原始应用。尤其当流量来自局域网其他设备时,内核看到的是转发连接,不会天然知道远端设备的进程名。此类场景应优先按域名、目标地址或可识别的来源条件组织策略。

把大列表交给 rule-providers

规则提供者把较长的规则集合从主配置中拆出,主配置保留优先级和出口决策。behavior 声明集合的规则语义,format 声明文件格式,两者必须与远端内容一致。下面采用 YAML 形式的 classical 集合,集合内写规则条件,不在每条条件后附加策略组,由主配置的 RULE-SET 指定目标。

rule-providers:
  work-domains:
    type: http
    behavior: classical
    format: yaml
    url: "https://config.example.com/work-rules.yaml"
    path: ./rules/work-rules.yaml
    interval: 86400

rules:
  - RULE-SET,work-domains,业务出口
  - MATCH,DIRECT

对应的远端文件可以采用下列结构。若提供者声明为域名集合,就不能继续把完整的经典规则字符串当作普通域名填入。格式混用可能表现为解析失败,也可能导致规则没有按预期匹配,应先检查内容样式而不是盲目延长更新间隔。

payload:
  - DOMAIN,api.example.com
  - DOMAIN-SUFFIX,example.net

规则集本身也有信任与维护边界。更新可能扩大或缩小匹配范围,影响同一业务的出口,所以应选择用途明确、内容可检查的集合。调整之前保留缓存和已知正常配置;验证时挑选一个应命中与一个不应命中的目标,分别观察实际规则和最终出站,避免仅测试单个成功案例就认定全部分流正确。

6. DNS 解析、fake-ip 与引导链路

DNS 同时参与目标域名解析、节点服务器解析和某些规则判断。网页无法访问时,问题可能发生在任何一环:应用没有得到解析结果,内核无法解析节点域名,或者解析路径与连接出口不一致。先确认哪个域名、由哪个组件、通过哪条路径解析,再决定修改字段;直接更换所有解析器会让原有问题难以复现。

解析入口与地址增强模式

dns.enable 启用内核 DNS 功能,listen 指定接收 DNS 请求的地址,但这不会自动修改操作系统的 DNS 设置。显式系统代理、应用自带加密 DNS 和 TUN 接入,对 DNS 的处理方式不同。只有请求实际送到内核,相关 DNS 策略才有机会生效,不能仅凭字段存在就判断解析已经被接管。

dns:
  enable: true
  listen: "127.0.0.1:1053"
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "*.local"
  default-nameserver:
    - 1.1.1.1
  nameserver:
    - "https://cloudflare-dns.com/dns-query"

fake-ip 使用虚拟地址建立域名与后续连接之间的关联,内核再依据域名与规则处理请求。该地址不是网站真实服务器地址,看到测试网段不能直接判定解析被污染。需要依赖真实地址进行局域网发现或特定验证的应用,可能需要加入过滤范围,但不应把所有域名都过滤掉来回避兼容性分析。

redir-host 通常返回实际解析地址,适用于不同的兼容需求。它与 fake-ip 的差别主要在于地址关联方式,不是简单的“快”和“慢”。选择哪一种应结合流量入口、应用行为和规则需求;切换后还要考虑系统 DNS 缓存、应用缓存以及旧连接,不能只看开关变化后第一次请求的结果。

引导解析与节点域名解析

default-nameserver 用于解析 DNS 服务器自身的域名等引导需求,不是给所有业务额外增加一个同等优先的普通解析器。使用带域名的加密 DNS 地址时,客户端首先要知道这个解析服务的地址。若引导解析依赖尚未建立的代理,而代理节点又依赖同一个解析服务,就可能形成启动闭环。

proxy-server-nameserver 可以单独规定节点服务器域名的解析路径,减少与普通业务解析混用时的依赖。这里需要的是能在当前网络环境中完成解析的实际服务。不能因为某个地址在其他网络可用,就认为它在当前网络一定可达;防火墙、运营网络和设备 DNS 策略都会影响结果。

respect-rules 让 DNS 连接的路由考虑分流规则,适合确实需要统一出口策略的场景,但也增加了对规则和节点解析的依赖。启用前应先规划节点域名的独立解析方式,避免 DNS 请求等待代理、代理又等待 DNS。初次排错时,先使用结构较简单的解析路径,确认基本连接后再增加策略分流。

按域名选择解析器与定位缓存

nameserver-policy 可为特定域名指定解析器,例如让内网域名询问办公网络的 DNS。内网解析器地址只是环境参数,离开该网络后可能无法访问,因此对应域名策略也应跟随环境调整。把内网名称送到公共解析器,通常不能得到期望地址,还会暴露不必要的内部名称查询。

dns:
  enable: true
  enhanced-mode: fake-ip
  default-nameserver:
    - 1.1.1.1
  proxy-server-nameserver:
    - 1.1.1.1
  nameserver:
    - "https://cloudflare-dns.com/dns-query"
  nameserver-policy:
    "+.corp.example.com":
      - 192.168.1.53

此片段应与实际 DNS 配置合并,不要在同一文件再追加第二个 dns。公司内网示例地址必须换成当前环境的真实解析器。若同时使用 fallback 与过滤条件,还要分别理解主解析结果与备用结果的选择逻辑;增加备用解析器并不自动构成按域名分流,也不保证每次请求都采用同一个来源。

修改后用相同域名、相同应用和相同接入方式复测。终端查询工具可能直接使用系统解析器,与浏览器的加密 DNS 路径不同;两者结果不同并不总是内核异常。确认解析路径后,再清理相关缓存并重建连接。涉及 fake-ip 映射时还应检查持久化状态,避免旧地址与新配置混用造成间歇性失败。

7. TUN 接入、系统路由与平台差异

TUN 在操作系统中建立虚拟网络接口,让一部分原本不使用显式代理的流量进入内核。它处理的是流量接入,不代替策略组、节点或规则。启用后,内核仍需决定每条连接应该直连、拒绝还是通过代理;如果节点本来不可用,TUN 只会让更多应用接触到同一个故障,并不会修复远端连接。

最小配置与权限条件

桌面客户端通常需要安装服务或获得相应权限,才能创建接口并修改路由。手动运行内核时则需要自行处理系统授权。配置中写了 enable: true,但日志显示接口创建失败,就应先解决权限、驱动或服务状态,而不是继续修改规则。图形界面显示开关已打开,也不能代替对实际接口和路由的检查。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - "any:53"

auto-route 请求内核设置接入所需路由,auto-detect-interface 用于辅助选择出站接口。设备同时存在有线、无线、虚拟机或其他隧道接口时,自动选择可能受到默认路由变化影响。若故障只在切换网络后出现,应检查当前默认路由和实际出站接口,而不必先怀疑订阅内容。

stack 决定虚拟接口流量由哪种网络栈处理,具体可用选项与行为应以当前内核为准。不要照搬所谓通用最佳组合:同一应用的 UDP、局域网访问和大流量传输可能表现不同。更换网络栈时保持其他设置不变,用同一组业务复测,才能知道变化是否真正来自该字段。

DNS 劫持与接入范围

dns-hijack 把匹配的常规 DNS 流量交给内核 DNS。它不能天然解密应用自带的 HTTPS DNS,也不能保证接管所有不在 TUN 路由范围内的请求。如果应用继续走自己的解析通道,规则看到的目标信息可能与预期不同,应先确认应用 DNS 设置和实际连接,再判断是否需要调整。

路由接管还需要考虑局域网打印机、网络存储、开发环境和虚拟机网段。规则中的直连决定流量进入内核之后的出口,系统路由排除则决定该流量是否进入内核,两者不是同一种控制。遇到本地服务失联时,应先检查请求有没有进入内核,再检查目的地址规则,避免在错误层级反复加例外。

严格路由之类的设置可能帮助限制旁路路径,但也可能影响系统组件、其他隧道和局域网通信。只有理解其平台行为后才应启用。特别是远程管理设备或服务器时,路由修改可能中断当前管理连接,应保留现场访问或回退办法,不要在缺少恢复路径的情况下直接套用桌面配置。

按平台检查实际生效状态

平台优先检查常见边界
Windows服务权限、虚拟接口、防火墙系统代理与 UWP 应用路径可能不同
macOS系统授权、路由与客户端实现网络扩展或其他隧道可能影响接入
LinuxTUN 设备、权限、策略路由与防火墙桌面与服务器环境需分别检查
Android / iOS客户端 VPN 授权与系统状态桌面 TUN 字段不能视为通用设置入口

Windows 上,先确认显式代理正常,再关闭系统代理并单独测试 TUN,可以更清楚地区分两种接入路径。UWP 应用在显式代理场景中的回环限制,与 TUN 接管不是同一个问题,不能把所有无法联网都归入防火墙。具体安装与服务排错可参阅Clash Verge Rev Windows 安装与 TUN 排错。

Linux 上还要检查转发、防火墙和策略路由是否由其他服务维护,网络管理器重载后可能改变已有设置。macOS 与移动平台则应遵循当前客户端提供的授权入口,不要强行把桌面文件直接覆盖进去。Clash Plus、Clash Verge Rev 与 FlClash 的界面不同,具体入口需以当前平台客户端为准。

出现全局断网时,先关闭 TUN,确认系统原有网络是否恢复,再检查内核启动日志、DNS 与节点。若关闭后仍异常,继续检查残留系统代理和路由,而不是不断切换节点。完成测试后,应只保留当前需要的接入方式;排错期间同时运行多套代理或隧道,会让流量路径难以确认。

8. 客户端覆写、配置合并与验证流程

最终生效配置往往由订阅原文、本地扩展、客户端设置和运行状态共同决定。订阅更新负责刷新来源内容,覆写负责保留本地差异,控制接口则可能修改当前选择。三者同时存在时,单看编辑器里的文件无法解释全部行为。排查的终点应是“内核实际读取了什么,以及连接实际走了哪里”,而不是“某个字段已经保存”。

明确合并规则与持久化位置

映射、列表和标量在合并时可能采用不同策略。映射可能递归覆盖,列表可能整体替换,也可能被客户端追加;这些行为由客户端的扩展机制决定,并不是 YAML 自带的统一标准。尤其是 rules,即使内容全部保留下来,追加位置不同也会改变优先级,所以必须检查合并后的顺序。

例如订阅末尾已有 MATCH,客户端把自定义域名规则追加在它后面,这条规则就没有机会命中。正确处理方式是使用客户端支持的前置规则入口,或在生成时把自定义例外插入兜底之前。不要仅凭界面显示“添加成功”就结束验证,应发起对应请求并查看实际命中的规则。

# 合并后期望得到的规则顺序
rules:
  - DOMAIN,api.example.com,业务出口
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,业务出口

端口、控制接口和 TUN 往往由客户端管理,覆写同名字段后可能被再次替换。应先确定一个字段由哪一层负责,再集中修改,避免界面设置与文件覆写互相覆盖。Clash Plus 可作为选型起点;使用其他客户端时,同样应按其本地扩展机制保存修改,不把某一客户端的脚本语法当成内核通用字段。

订阅更新后丢失修改,通常说明编辑位置选错,或者覆写没有关联到当前配置。先检查更新前后的原始文本,再检查扩展是否启用以及适用范围。有些扩展只作用于单个配置,有些作用于全部配置,选错范围会使测试配置影响日常使用。长期维护时应保留本地差异说明,记录每项覆写的目的与移除条件。

先做静态验证,再做运行验证

手动运行 mihomo 时,可以先对准备启用的文件进行配置测试。下面的命令检查指定文件是否能被当前内核接受,不代表远程节点、外部规则资源和所有业务都已通过端到端测试。图形客户端可能使用自带内核与独立工作目录,终端中的另一个 mihomo 测试成功,也不能证明客户端使用的是同一份文件。

mihomo -t -f ./config.yaml

静态阶段按四类错误依次处理:缩进或类型错误、缺失名称引用、当前内核不支持的字段、外部资源加载问题。报错时保留第一条有实际含义的信息,后续错误可能只是连锁结果。修改一处后重新测试,不要在不清楚含义的情况下同时删除多个字段,否则即使能启动,也可能丢失原有策略。

运行阶段先确认监听成功,再确认测试请求进入内核,然后检查模式、规则、策略组与最终节点。最后才判断出口地址和实际业务结果。建议选择一条明确直连的请求与一条明确代理的请求分别验证,必要时重建连接。首次连接的完整验证步骤可参阅选节点、测延迟与确认代理生效。

按症状回到正确层级

配置测试通过,为什么应用仍然无法上网?

先看连接记录是否出现请求。没有记录时检查系统代理、应用代理或 TUN 接入;有记录但失败时,再检查 DNS、节点握手与规则目标。解析成功和配置通过都只是中间条件,不能替代实际连接验证。

切换策略组后,为什么出口没有立即变化?

确认当前是规则模式还是全局模式,并检查该请求实际指向的组。已有长连接可能继续沿用原出口,需要重新发起连接。若新请求仍未变化,再检查策略组持久化、嵌套选择以及客户端是否加载了预期配置。

订阅更新后,为什么本地规则没有生效?

检查覆写是否仍关联当前配置,以及列表合并采用替换、前置还是追加。重点查看最终文件中是否存在多个同名顶层键,规则是否落在 MATCH 后面,目标策略组是否被订阅更新改名。应修复生成方式,而不是长期手改运行缓存。

恢复操作应与变更同样明确:先回到已知正常配置,再关闭最近增加的覆写或 TUN 设置,确认系统代理和 DNS 状态。不要直接删除整个客户端目录来处理一个字段问题,因为其中可能保存节点选择、缓存和本地扩展。需要重新安装时,先按平台下载入口选择对应安装包,并备份必要的本地配置。