Skip to content

OpenClash 与 Mihomo 配置文件流程及核心配置详解

本文用于建立一套完整的 OpenClash/Mihomo 配置心智模型:先理解 OpenClash 如何处理 YAML,再理解 Mihomo 如何把节点、策略组、规则和 DNS 组合成实际运行时对象。

很多配置问题并不是某一个字段写错,而是没有区分以下几个层次:

  1. OpenClash 是 OpenWrt 上的管理和透明代理集成层;
  2. Mihomo 是真正读取 YAML、匹配规则并建立代理连接的内核;
  3. 主配置 YAML、Provider 文件和内核运行时对象不是同一个东西;
  4. DIRECT 只表示由 Mihomo 直连,不等于流量完全没有经过 Mihomo;
  5. DNS 不只负责域名解析,还参与域名恢复、规则匹配和直连/代理出口决策。

本文按实际运行链路展开,先说明配置文件如何从 OpenClash 进入 Mihomo,然后分别讲解各个核心配置模块。


一、OpenClash 与 Mihomo 各自负责什么

1. OpenClash 是管理层

OpenClash 是运行在 OpenWrt 上的 LuCI 插件和脚本集合。它主要负责:

  • 管理订阅与配置文件;
  • 提供 LuCI Web 配置界面;
  • 将 UCI 设置写入或覆写到 YAML;
  • 管理 Mihomo 内核文件;
  • 创建 nftables/iptables 透明代理规则;
  • 配置 DNS 劫持、dnsmasq 转发与访问控制;
  • 启动、停止、监控 Mihomo 进程;
  • 更新 GEO、规则集和 Provider 文件;
  • 将指定设备、端口或网段在防火墙层提前绕过。

OpenClash 本身并不负责逐条执行 Mihomo YAML 中的 rules。它负责准备环境和配置,再把配置交给 Mihomo。

2. Mihomo 是执行层

Mihomo 原名 Clash.Meta,是当前 OpenClash 主要使用的 Clash 兼容内核。它负责:

  • 解析主 YAML;
  • 加载静态代理节点;
  • 下载并解析 Proxy Provider;
  • 下载并解析 Rule Provider;
  • 构建策略组;
  • 运行 DNS 服务;
  • 执行域名嗅探;
  • 按顺序匹配规则;
  • 选择 DIRECTREJECT、节点或策略组;
  • 建立真实的 TCP、UDP、代理和 TUN 连接。

可以把两者理解为:

text
OpenClash
  ├─ 管理配置
  ├─ 修改 YAML
  ├─ 配置防火墙
  ├─ 配置 DNS 劫持
  └─ 启动 Mihomo

Mihomo
  ├─ 读取 YAML
  ├─ 加载 Provider
  ├─ 构建运行时对象
  ├─ 匹配 rules
  └─ 建立连接

二、OpenClash 使用配置文件的完整流程

1. 原始配置文件

用户导入、订阅或手工维护的配置文件通常保存在:

text
/etc/openclash/config/

例如:

text
/etc/openclash/config/home.yaml

这份文件可以称为“原始配置”或“源配置”。它可能来自:

  • 机场订阅转换结果;
  • 手工编写的 Mihomo YAML;
  • OpenClash 配置订阅;
  • 本地上传的配置文件。

原始配置不一定会被原样交给 Mihomo,因为 OpenClash 还要根据 LuCI/UCI 设置进行覆写。

2. OpenClash 读取 UCI 设置

OpenClash 自身的插件设置主要保存在:

text
/etc/config/openclash

这里记录的不是完整 Mihomo YAML,而是 OpenClash 的管理状态,例如:

  • 当前启用哪个配置文件;
  • Fake-IP 或 Redir-Host 模式;
  • 是否启用 TUN;
  • TCP/UDP 透明代理端口;
  • DNS 劫持方式;
  • IPv6 开关;
  • 局域网访问控制;
  • 配置覆写模块;
  • 自动更新与自动重启设置。

启动时,OpenClash 会把这些管理设置转换成 Mihomo 能理解的 YAML 字段,或者转换成 OpenWrt 防火墙与 dnsmasq 配置。

3. 生成工作配置

OpenClash 启动时通常会执行以下流程:

text
原始配置
/etc/openclash/config/home.yaml


复制或加载到临时处理文件


应用 OpenClash 内置覆写
  - 端口
  - DNS
  - TUN
  - 控制器
  - IPv6
  - Sniffer
  - 策略组管理


应用用户自定义覆写


生成工作配置
/etc/openclash/<配置文件名>

常见工作配置路径是:

text
/etc/openclash/config.yaml

具体文件名取决于当前配置名称和 OpenClash 版本。判断内核实际读取哪一份文件,最可靠的方法是查看 OpenClash 启动日志中的 Mihomo 命令行参数。

OpenClash 启动内核时会指定:

text
-d /etc/openclash
-f /etc/openclash/某个配置文件.yaml

其中:

  • -d /etc/openclash 指定 Mihomo HomeDir;
  • -f ... 指定真正交给 Mihomo 的主配置文件。

4. HomeDir 决定相对路径

当主配置中写:

yaml
proxy-providers:
  airport:
    type: http
    path: ./proxy_provider/airport.yaml

由于 Mihomo HomeDir 通常是:

text
/etc/openclash

所以实际文件路径是:

text
/etc/openclash/proxy_provider/airport.yaml

同理:

yaml
rule-providers:
  cn-domain:
    type: http
    path: ./rule_provider/cn-domain.yaml

对应:

text
/etc/openclash/rule_provider/cn-domain.yaml

相对路径应位于 Mihomo 允许的安全目录内。OpenClash 中优先使用 ./proxy_provider/./rule_provider/,可以减少路径安全限制和升级迁移问题。

5. Mihomo 读取主 YAML

Mihomo 收到主配置后,首先解析顶层字段,例如:

yaml
mode: rule
mixed-port: 7890
ipv6: false

dns:
  enable: true

proxies: []
proxy-providers: {}
proxy-groups: []
rule-providers: {}
rules: []

然后把 YAML 转换成内存对象:

text
主配置 YAML
  ├─ General 配置对象
  ├─ DNS 配置对象
  ├─ 入站监听器
  ├─ 静态代理节点对象
  ├─ Proxy Provider 对象
  ├─ Proxy Group 对象
  ├─ Rule Provider 对象
  └─ Rules 规则树/规则列表

6. Mihomo 再加载 Provider

如果主配置包含:

yaml
proxy-providers:
  airport:
    type: http
    url: https://example.com/subscription
    path: ./proxy_provider/airport.yaml
    interval: 21600

Mihomo 会继续执行:

text
读取主 YAML

发现 type: http

请求订阅 URL

解析 YAML / URI / Base64 节点内容

保存 Provider 文件

在内存中创建节点对象

注入引用该 Provider 的策略组

因此,磁盘上通常不是只有一个“所有内容完全展开”的 YAML,而是:

text
/etc/openclash/config.yaml
/etc/openclash/proxy_provider/airport.yaml
/etc/openclash/rule_provider/cn-domain.yaml
/etc/openclash/GeoSite.dat
/etc/openclash/GeoIP.dat
/etc/openclash/cache.db

真正完全准备好的配置存在 Mihomo 内存中,而不是另一个自动生成的单体 YAML。

7. 配置文件流程总结

text
订阅或手工 YAML

/etc/openclash/config/*.yaml

OpenClash 读取 UCI 设置

应用内置覆写与自定义覆写

/etc/openclash/*.yaml 工作配置

Mihomo -d /etc/openclash -f 工作配置

下载 Proxy Provider / Rule Provider

加载 GEO 数据与缓存

构建运行时对象

开始接收流量并执行规则

三、主配置中的基础字段

1. mode

yaml
mode: rule

常见模式:

  • rule:按 rules 逐条匹配;
  • global:所有流量统一进入全局策略;
  • direct:所有流量直接连接。

日常 OpenClash 分流应使用:

yaml
mode: rule

2. 监听端口

yaml
port: 7890
socks-port: 7891
mixed-port: 7893
redir-port: 7892
tproxy-port: 7895

作用分别是:

字段作用
portHTTP 代理端口
socks-portSOCKS5 代理端口
mixed-port同时支持 HTTP 和 SOCKS5
redir-portTCP REDIRECT 透明代理入口
tproxy-portTPROXY 透明代理入口,常用于 UDP

这些端口往往会被 OpenClash 根据插件设置覆写,不建议只看原始订阅判断实际端口。

3. 顶层 ipv6

yaml
ipv6: false

顶层 ipv6 控制 Mihomo 内核是否接受和处理 IPv6 流量。

它与 dns.ipv6 不同:

yaml
ipv6: false

dns:
  ipv6: false
  • 顶层 ipv6: false:内核层关闭 IPv6 流量处理;
  • dns.ipv6: false:DNS 层对 AAAA 查询返回空结果。

如果完全不使用 IPv6,应同时关闭 OpenClash、Mihomo DNS 和 OpenWrt 系统层的 IPv6。


四、proxies:静态代理节点

proxies 用于直接在主 YAML 中定义节点:

yaml
proxies:
  - name: HK-01
    type: ss
    server: hk.example.com
    port: 443
    cipher: aes-128-gcm
    password: password
    udp: true

它适合:

  • 节点数量很少;
  • 节点信息固定;
  • 不需要独立更新订阅;
  • 希望所有内容集中在一个主 YAML 中。

缺点是节点更新必须修改或重新生成主配置。节点较多、需要定时更新时,更适合使用 proxy-providers


五、proxy-providers:代理节点数据源

1. 复数与单数

Mihomo YAML 顶层字段必须写:

yaml
proxy-providers:

不能写:

yaml
proxy-provider:

proxy-provider 是“一个 Provider”的概念,也是 OpenClash UCI/LuCI 中可能使用的内部 section 名称;真正生成到 Mihomo YAML 中时,顶层键是复数 proxy-providers

2. HTTP Provider

yaml
proxy-providers:
  airport:
    type: http
    url: "https://example.com/sub?token=xxx"
    path: ./proxy_provider/airport.yaml
    interval: 21600
    proxy: DIRECT
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 600
      timeout: 5000
      lazy: true

字段说明:

字段作用
typeProvider 类型,常用 httpfileinline
urlHTTP 订阅地址
path下载后的本地保存路径
interval更新周期,单位秒
proxy下载 Provider 时使用的出口
health-checkProvider 节点健康检查

第一次启动时通常使用:

yaml
proxy: DIRECT

避免下载 Provider 依赖一个尚未加载的代理组而形成循环。

3. File Provider

yaml
proxy-providers:
  local-nodes:
    type: file
    path: ./proxy_provider/local-nodes.yaml
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 600

对应文件:

text
/etc/openclash/proxy_provider/local-nodes.yaml

文件内容:

yaml
proxies:
  - name: HK-01
    type: ss
    server: hk.example.com
    port: 443
    cipher: aes-128-gcm
    password: password

4. Inline Provider

yaml
proxy-providers:
  built-in:
    type: inline
    payload:
      - name: HK-01
        type: ss
        server: hk.example.com
        port: 443
        cipher: aes-128-gcm
        password: password

Inline Provider 适合少量节点,同时保留 Provider 的 use 引用结构。

5. 过滤与覆写

yaml
proxy-providers:
  airport:
    type: http
    url: "https://example.com/sub"
    path: ./proxy_provider/airport.yaml
    filter: "(?i)香港|HK|Hong Kong"
    exclude-filter: "(?i)剩余|到期|流量|官网|客服"
    override:
      udp: true
      additional-prefix: "[机场A] "

注意:Provider 级过滤会影响所有引用它的策略组。如果只是创建“香港自动选择”策略组,通常更适合在策略组中写 filter,避免破坏 Provider 原始节点集合。

6. Provider 本身不是出口

错误:

yaml
rules:
  - MATCH,airport

airport 只是节点数据源,不应该直接作为规则出口。正确做法是先创建策略组:

yaml
proxy-groups:
  - name: PROXY
    type: select
    use:
      - airport

rules:
  - MATCH,PROXY

六、proxy-groups:策略组与节点选择

策略组负责回答:

当规则决定走某一类出口时,具体使用哪个节点?

1. proxiesuse

yaml
proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - AUTO
      - DIRECT
    use:
      - airport
  • proxies:引用具体节点、其他策略组或内置出口;
  • use:引用 proxy-providers

常见错误是把 Provider 名称写进 proxies

yaml
proxies:
  - airport

如果没有一个具体节点或策略组名为 airport,这不会加载 Provider。Provider 应通过:

yaml
use:
  - airport

引用。

2. select

yaml
- name: PROXY
  type: select
  proxies:
    - AUTO
    - HK
    - JP
    - DIRECT

由用户手工选择出口。

3. url-test

yaml
- name: AUTO
  type: url-test
  use:
    - airport
  filter: "(?i)香港|日本|新加坡|HK|JP|SG"
  url: https://www.gstatic.com/generate_204
  interval: 300
  tolerance: 50
  timeout: 5000
  lazy: true

定期测试延迟,选择满足条件的低延迟节点。

4. fallback

yaml
- name: FAILOVER
  type: fallback
  use:
    - airport
  url: https://www.gstatic.com/generate_204
  interval: 300
  timeout: 5000

按顺序使用可用节点,当前节点失效后切换到下一个。

5. load-balance

yaml
- name: BALANCE
  type: load-balance
  use:
    - airport
  url: https://www.gstatic.com/generate_204
  interval: 300
  strategy: consistent-hashing

在多个节点间分配连接。是否适合使用取决于业务对源 IP 稳定性、会话保持和风控的要求。


七、rule-providers:规则数据源

1. 与 Proxy Provider 的区别

text
proxy-providers
  └─ 提供代理节点

rule-providers
  └─ 提供匹配条件

Rule Provider 不提供出口,它只描述哪些域名、IP 或条件属于某个集合。

2. 顶层字段仍然是复数

正确:

yaml
rule-providers:

错误:

yaml
rule-provider:

3. behavior: domain

yaml
rule-providers:
  cn-domain:
    type: http
    behavior: domain
    format: yaml
    url: https://example.com/cn-domain.yaml
    path: ./rule_provider/cn-domain.yaml
    interval: 86400

Provider 内容:

yaml
payload:
  - ".baidu.com"
  - ".bilibili.com"
  - ".taobao.com"

引用:

yaml
rules:
  - RULE-SET,cn-domain,DIRECT

4. behavior: ipcidr

yaml
rule-providers:
  private-ip:
    type: inline
    behavior: ipcidr
    payload:
      - 10.0.0.0/8
      - 172.16.0.0/12
      - 192.168.0.0/16

引用:

yaml
rules:
  - RULE-SET,private-ip,DIRECT,no-resolve

5. behavior: classical

yaml
rule-providers:
  special:
    type: file
    behavior: classical
    format: yaml
    path: ./rule_provider/special.yaml

Provider 内容:

yaml
payload:
  - DOMAIN-SUFFIX,google.com
  - DOMAIN-KEYWORD,youtube
  - IP-CIDR,8.8.8.8/32
  - DST-PORT,443

主规则统一指定出口:

yaml
rules:
  - RULE-SET,special,PROXY

Rule Provider 中一般只写匹配条件,不写最终策略名称。这样同一份规则集可以在不同配置中复用。


八、rules:最终流量决策表

1. 第一条命中规则生效

yaml
rules:
  - DOMAIN-SUFFIX,baidu.com,DIRECT
  - DOMAIN-SUFFIX,google.com,PROXY
  - GEOSITE,CN,DIRECT
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,PROXY

Mihomo 严格从上到下执行,不会先把所有域名规则执行完再执行 IP 规则。

第一条命中后立即停止,不再检查后续规则。

2. 域名规则

常见域名规则:

yaml
- DOMAIN,www.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,DIRECT
- DOMAIN-KEYWORD,google,PROXY
- GEOSITE,CN,DIRECT
- RULE-SET,cn-domain,DIRECT

这些规则需要 Mihomo 知道原始域名。

3. IP 规则

常见 IP 规则:

yaml
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR6,fd00::/8,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- IP-ASN,4134,DIRECT,no-resolve
- RULE-SET,cn-ip,DIRECT,no-resolve

这些规则根据目标真实 IP 判断。

4. no-resolve

yaml
- GEOIP,CN,DIRECT,no-resolve

含义不是“禁止所有 DNS”,而是:

不要为了判断这一条 IP 规则而主动把域名解析成真实 IP。

如果当前连接已经带有真实 IP,该规则仍然可以正常判断。

5. Baidu 和 Google 如何匹配

假设:

yaml
rules:
  - GEOSITE,CN,DIRECT
  - DOMAIN-SUFFIX,google.com,PROXY
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,PROXY

访问 www.baidu.com

text
恢复域名 www.baidu.com

检查 GEOSITE,CN

命中中国域名集合

DIRECT

访问 www.google.com

text
恢复域名 www.google.com

GEOSITE,CN 不命中

DOMAIN-SUFFIX,google.com 命中

PROXY

规则顺序必须体现优先级。特殊域名和私网规则通常放在前面,大范围 GEO 规则放在中间,MATCH 放在最后。


九、Mihomo 如何知道原始域名

透明代理拿到的数据包可能只有目标 IP。域名信息通常来自四种渠道。

1. HTTP/SOCKS 显式代理

应用直接把目标域名交给代理服务器,因此 Mihomo 天然知道域名。

2. Fake-IP 映射

yaml
dns:
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16

客户端查询:

text
www.google.com

Mihomo 返回:

text
198.18.0.10

并在内部记录:

text
198.18.0.10 ↔ www.google.com

客户端随后连接 198.18.0.10,Mihomo 就能恢复原始域名并执行域名规则。

3. DNS 映射缓存

如果 DNS 查询经过 Mihomo,它可以建立域名与真实 IP 的关联,在后续透明代理连接中尝试恢复域名。

4. Sniffer 嗅探

yaml
sniffer:
  enable: true
  parse-pure-ip: true
  sniff:
    HTTP:
      ports:
        - 80
        - 8080-8880
      override-destination: true
    TLS:
      ports:
        - 443
    QUIC:
      ports:
        - 443

Sniffer 可以从:

  • HTTP Host;
  • TLS SNI;
  • QUIC 握手信息;

恢复域名。

Sniffer 是补充机制,不应替代正确的 DNS 劫持和 Fake-IP 配置。


十、DNS 在 Mihomo 中的作用

DNS 在 Mihomo 中不仅是:

text
域名 → IP

它还负责:

  1. 保存域名信息供域名规则匹配;
  2. 为 Fake-IP 建立域名映射;
  3. 为直连流量获得真实 IP;
  4. 为代理节点服务器解析地址;
  5. 按国内外域名选择不同 DNS;
  6. 降低 DNS 污染和错误 CDN 解析;
  7. 控制 AAAA/IPv6 解析结果;
  8. 决定 DNS 请求本身是直连还是通过代理。

十一、Fake-IP 与 Redir-Host

1. Fake-IP

yaml
dns:
  enable: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16

优点:

  • 域名恢复稳定;
  • 域名规则命中率高;
  • 不依赖 CDN IP 是否变化;
  • 适合透明代理和 TUN;
  • 可以减少部分真实 DNS 查询。

缺点:

  • 某些局域网、游戏、IoT、时间同步和特殊协议不兼容;
  • 防火墙看到的是 Fake-IP,难以提前按中国真实 IP 绕过;
  • 设备流量绕过核心时,必须同步处理它的 DNS,否则会拿着 Fake-IP 直连失败。

2. Redir-Host

yaml
dns:
  enable: true
  enhanced-mode: redir-host

优点:

  • 客户端得到真实 IP;
  • 传统网络协议兼容性更好;
  • 防火墙可以使用 nftset/ipset/Chnroute 按真实 IP 提前绕过;
  • 更适合“国内流量不进核心”的设计。

缺点:

  • 域名关联能力弱于 Fake-IP;
  • 更依赖 DNS 缓存和 Sniffer;
  • CDN 共用 IP 场景下,纯 IP 分流可能不够精确。

十二、DNS 上游字段详解

1. default-nameserver

yaml
default-nameserver:
  - 223.5.5.5
  - 119.29.29.29

作用:解析 DNS 上游服务器自身的域名。

例如:

yaml
nameserver:
  - https://dns.alidns.com/dns-query

要连接 dns.alidns.com,Mihomo 必须先知道它的 IP。这个启动解析由 default-nameserver 完成。

可以理解为:

text
default-nameserver = DNS 的启动 DNS

推荐使用稳定、可直连的 IP DNS,不依赖代理。

2. nameserver

yaml
nameserver:
  - https://dns.alidns.com/dns-query
  - https://doh.pub/dns-query

作用:普通业务域名的默认上游 DNS。

如果域名没有命中更具体的 nameserver-policy,通常使用这里的服务器。

3. nameserver-policy

yaml
nameserver-policy:
  "geosite:private,cn":
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query

  "geosite:geolocation-!cn":
    - "https://1.1.1.1/dns-query#PROXY"
    - "https://8.8.8.8/dns-query#PROXY"

作用:根据域名选择不同 DNS 上游。

text
中国域名
  → 国内 DoH

非中国域名
  → 境外 DoH,经 PROXY

nameserver-policy 通常优先于普通 nameserver

4. proxy-server-nameserver

yaml
proxy-server-nameserver:
  - 223.5.5.5
  - 119.29.29.29

作用:专门解析代理节点服务器域名。

节点:

yaml
server: hk-node.example.com

Mihomo 必须先解析这个域名才能建立代理连接。

这里不能依赖尚未建立的代理,否则会形成:

text
需要代理才能解析节点

需要解析节点才能建立代理

循环依赖

5. direct-nameserver

yaml
direct-nameserver:
  - https://dns.alidns.com/dns-query
  - https://doh.pub/dns-query

作用:解析最终命中 DIRECT 的目标域名。

国内网站通常应该使用国内 DNS,以获得更适合当前地区和运营商的 CDN 地址。

6. direct-nameserver-follow-policy

yaml
direct-nameserver-follow-policy: true

开启后,DIRECT 目标仍然可以先检查 nameserver-policy;未命中时再使用 direct-nameserver

如果希望所有 DIRECT 目标无条件使用国内 DNS,可以设为:

yaml
direct-nameserver-follow-policy: false

十三、普通 DNS 与 DoH 如何选择

1. 普通 UDP DNS

yaml
- 223.5.5.5
- 119.29.29.29

优点:

  • 启动简单;
  • 首次查询开销低;
  • 不需要 TLS 握手;
  • 适合 Bootstrap 和节点域名解析。

缺点:

  • 查询明文;
  • UDP/53 可能被运营商重定向或篡改;
  • 隐私性较弱。

2. DoH

yaml
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query

优点:

  • DNS 查询在 HTTPS 中加密;
  • 不容易被简单的 UDP/53 劫持;
  • 可以通过策略组代理到境外 DNS;
  • 连接复用后日常开销通常可控。

缺点:

  • 首次建立需要 TCP/TLS;
  • DoH 域名本身需要 Bootstrap DNS;
  • 路由与代理依赖配置错误时更难排查。

推荐组合:

yaml
default-nameserver:
  - 223.5.5.5
  - 119.29.29.29

nameserver:
  - https://dns.alidns.com/dns-query
  - https://doh.pub/dns-query

proxy-server-nameserver:
  - 223.5.5.5
  - 119.29.29.29

direct-nameserver:
  - https://dns.alidns.com/dns-query
  - https://doh.pub/dns-query

也就是:

text
普通 IP DNS负责启动和节点解析
DoH 负责主要业务解析

十四、DNS 中的 IPv6

1. 顶层 IPv6

yaml
ipv6: false

控制 Mihomo 是否接受 IPv6 流量。

2. DNS IPv6

yaml
dns:
  ipv6: false

控制 Mihomo DNS 是否返回 AAAA 记录。

当它为 false 时:

text
A 查询
  → 正常返回 IPv4

AAAA 查询
  → 返回空结果

3. 完全不需要 IPv6

建议:

yaml
ipv6: false

dns:
  ipv6: false

同时在 OpenClash 的 IPv6 设置中关闭相关功能,并在 OpenWrt 中处理:

  • WAN6;
  • LAN RA;
  • DHCPv6;
  • NDP 代理;
  • IPv6 默认路由。

只关闭 YAML 不能关闭 OpenWrt 操作系统的 IPv6 协议栈。

不要配置:

yaml
fake-ip-range6: fdfe:dcba:9876::1/64

并确保代理节点不是仅有 IPv6 地址或仅有 AAAA 记录。


十五、DIRECT 与完全绕过 Mihomo 的区别

1. 规则中的 DIRECT

yaml
rules:
  - GEOSITE,CN,DIRECT

流程:

text
客户端流量

OpenClash 防火墙截获

进入 Mihomo

执行 rules

命中 DIRECT

由 Mihomo 建立直连

这仍然经过 Mihomo,仍然会产生规则判断、DNS 和连接记录。

2. 防火墙层绕过

真正不经过 Mihomo:

text
客户端流量

OpenWrt nftables/iptables

命中 RETURN/ACCEPT 绕过规则

直接由 OpenWrt 路由

Mihomo 看不到这种连接,也不会执行 YAML 中的 rules

3. 局域网流量

同一二层网段的设备通信通常通过交换机或 Wi-Fi Bridge 完成:

text
192.168.1.10 → 192.168.1.20

它不经过路由器三层转发,自然不会进入 OpenClash。

跨 VLAN 或跨子网:

text
192.168.10.10 → 192.168.20.20

必须经过路由器,应在防火墙层排除私网地址:

text
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16

4. 国内流量是否可以不进核心

Redir-Host 模式下,客户端得到真实 IP,防火墙可以根据中国 IP 集合提前 RETURN

text
baidu.com
  ↓ DNS 返回真实中国 IP
  ↓ nftset/ipset/Chnroute 判断
  ↓ 直接绕过 Mihomo

Fake-IP 模式下,防火墙看到的是 198.18.0.0/16,无法提前判断它对应百度还是 Google。因此域名连接通常必须进入 Mihomo,再恢复域名并执行规则。

对于局域网域名,应加入:

yaml
fake-ip-filter:
  - "*.lan"
  - "*.local"
  - localhost
  - router.local
  - nas.lan

这样局域网域名返回真实私网 IP,防火墙才能直接绕过。


十六、一份完整的参考配置

下面的配置用于说明各模块如何组合。实际部署时还需要结合订阅中的节点名称、OpenClash 覆写和本地网络结构调整。

yaml
mode: rule
log-level: info
ipv6: false

mixed-port: 7890
allow-lan: true
bind-address: "*"

external-controller: 0.0.0.0:9090
secret: "replace-this-secret"

proxy-providers:
  airport:
    type: http
    url: "https://example.com/subscription?token=replace-me"
    path: ./proxy_provider/airport.yaml
    interval: 21600
    proxy: DIRECT
    exclude-filter: "(?i)剩余|到期|流量|官网|客服"
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 600
      timeout: 5000
      lazy: true

proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - AUTO
      - FAILOVER
      - DIRECT
    use:
      - airport

  - name: AUTO
    type: url-test
    use:
      - airport
    filter: "(?i)香港|日本|新加坡|HK|JP|SG"
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    timeout: 5000
    lazy: true

  - name: FAILOVER
    type: fallback
    use:
      - airport
    url: https://www.gstatic.com/generate_204
    interval: 300
    timeout: 5000
    lazy: true

rule-providers:
  private-ip:
    type: inline
    behavior: ipcidr
    payload:
      - 10.0.0.0/8
      - 172.16.0.0/12
      - 192.168.0.0/16

  cn-domain:
    type: http
    behavior: domain
    format: yaml
    url: https://example.com/cn-domain.yaml
    path: ./rule_provider/cn-domain.yaml
    interval: 86400

  cn-ip:
    type: http
    behavior: ipcidr
    format: yaml
    url: https://example.com/cn-ip.yaml
    path: ./rule_provider/cn-ip.yaml
    interval: 86400

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false

  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16

  use-hosts: true
  use-system-hosts: true

  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29

  nameserver:
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query

  nameserver-policy:
    "geosite:private,cn":
      - https://dns.alidns.com/dns-query
      - https://doh.pub/dns-query

    "geosite:geolocation-!cn":
      - "https://1.1.1.1/dns-query#PROXY"
      - "https://8.8.8.8/dns-query#PROXY"

  proxy-server-nameserver:
    - 223.5.5.5
    - 119.29.29.29

  direct-nameserver:
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query

  direct-nameserver-follow-policy: true

  fake-ip-filter:
    - "*.lan"
    - "*.local"
    - localhost
    - router.local

sniffer:
  enable: true
  parse-pure-ip: true
  sniff:
    HTTP:
      ports:
        - 80
        - 8080-8880
      override-destination: true
    TLS:
      ports:
        - 443
    QUIC:
      ports:
        - 443

rules:
  - RULE-SET,private-ip,DIRECT,no-resolve
  - DOMAIN-SUFFIX,router.local,DIRECT
  - RULE-SET,cn-domain,DIRECT
  - DOMAIN-SUFFIX,google.com,PROXY
  - DOMAIN-SUFFIX,youtube.com,PROXY
  - RULE-SET,cn-ip,DIRECT,no-resolve
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,PROXY

这份示例的逻辑是:

text
私网地址
  → DIRECT

中国域名
  → 国内 DNS
  → DIRECT

Google/YouTube
  → 境外 DNS 经 PROXY
  → PROXY

已知中国 IP
  → DIRECT

其他流量
  → PROXY

十七、常见配置错误

1. 顶层字段写成单数

错误:

yaml
proxy-provider:
rule-provider:

正确:

yaml
proxy-providers:
rule-providers:

2. 规则直接引用 Proxy Provider

错误:

yaml
rules:
  - MATCH,airport

正确:

yaml
proxy-groups:
  - name: PROXY
    type: select
    use:
      - airport

rules:
  - MATCH,PROXY

3. 使用 proxies 引用 Provider

错误:

yaml
proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - airport

正确:

yaml
use:
  - airport

4. Proxy Provider 写 behavior

错误:

yaml
proxy-providers:
  airport:
    behavior: classical

behavior 属于 Rule Provider。

5. Provider 路径越过 HomeDir

推荐:

yaml
path: ./proxy_provider/airport.yaml

避免随意写 /tmp/root 或其他不在安全路径范围的目录。

6. 代理节点 DNS 经过代理自身

不推荐:

yaml
proxy-server-nameserver:
  - "https://1.1.1.1/dns-query#PROXY"

节点尚未解析时,PROXY 可能无法建立,造成循环依赖。

7. Fake-IP 设备绕过但 DNS 未绕过

错误流程:

text
设备获得 baidu.com = 198.18.0.10

设备数据流量被防火墙绕过 Mihomo

直接连接 198.18.0.10

失败

Fake-IP 模式做客户端访问控制时,DNS 劫持和流量绕过必须保持一致。

8. 把 DIRECT 理解成完全不经过核心

DIRECT 仍然经过 Mihomo。只有防火墙层 RETURN/ACCEPT 才是真正绕过核心。

9. 只关闭 dns.ipv6

yaml
dns:
  ipv6: false

只会阻止 AAAA 结果。完全关闭还应配置:

yaml
ipv6: false

并关闭 OpenWrt 系统 IPv6。


十八、排查顺序

当 OpenClash 启动或分流异常时,建议按以下顺序检查。

1. 确认真正运行的配置文件

查看 OpenClash 运行日志,确认 Mihomo 的 -f 参数,而不是只查看订阅源文件。

2. 检查 YAML 语法

重点检查:

  • 缩进;
  • URL 是否加引号;
  • Provider 名称是否一致;
  • 策略组名称是否一致;
  • useproxies 是否混用;
  • RULE-SET 是否引用存在的 Rule Provider;
  • rules 的最终出口是否存在。

3. 检查 Provider 文件

text
/etc/openclash/proxy_provider/
/etc/openclash/rule_provider/

确认文件存在、内容非空、格式正确。

4. 检查节点域名解析

如果日志显示节点连接失败,先检查:

  • proxy-server-nameserver
  • 节点域名是否有 A 记录;
  • 节点是否仅支持 IPv6;
  • 国内 DNS 是否能解析节点域名。

5. 检查 DNS 劫持

浏览器安全 DNS、Android Private DNS、应用内置 DoH 都可能绕过 OpenClash DNS,导致域名映射和分流异常。

6. 检查 Fake-IP 过滤

局域网设备、NAS、打印机、时间同步、游戏和 IoT 异常时,检查 fake-ip-filter

7. 区分内核规则与防火墙绕过

  • Dashboard 能看到连接:流量进入了 Mihomo;
  • Dashboard 看不到连接:可能在防火墙层绕过,或者根本没有被透明代理捕获。

8. 检查最终匹配规则

在 Dashboard 连接详情中查看:

  • Host;
  • Destination IP;
  • Rule;
  • Rule Payload;
  • Chain;
  • Outbound。

这些信息可以判断是域名规则、IP 规则还是兜底规则命中。


十九、配置设计建议

1. 先明确要不要让国内流量进入核心

追求域名级精确分流:

text
Fake-IP
  + 域名规则
  + 国内流量进入核心后 DIRECT

追求减少内核负担:

text
Redir-Host
  + 国内 DNS
  + Chnroute/nftset 防火墙提前绕过

2. 私网地址优先在防火墙层绕过

局域网、跨 VLAN、NAS 和管理地址最好不要依赖远端规则集,避免规则更新或内核异常影响本地网络。

3. 特殊规则放前面

推荐顺序:

text
私网与本地服务

广告/拒绝规则

特殊代理域名

中国域名

中国 IP 补充

MATCH 兜底

4. DNS 不要全部依赖代理

保留可直连的:

yaml
default-nameserver:
proxy-server-nameserver:

保证即使代理尚未启动,也能解析 DNS 上游和节点服务器域名。

5. 查看最终配置而不是只看订阅

OpenClash 可能覆写:

  • DNS;
  • IPv6;
  • 监听端口;
  • TUN;
  • Sniffer;
  • Controller;
  • 规则和策略组。

排查时必须以 Mihomo 实际加载的工作配置为准。


二十、总结

OpenClash/Mihomo 的完整逻辑可以压缩成四条链路。

配置链路

text
原始 YAML
  → OpenClash UCI/覆写
  → 工作 YAML
  → Mihomo 解析
  → Provider 与 GEO 数据
  → 运行时对象

节点链路

text
proxy-providers
  → use
  → proxy-groups
  → 具体代理节点

规则链路

text
rule-providers
  → RULE-SET
  → rules
  → DIRECT / REJECT / proxy-group

DNS 链路

text
default-nameserver
  → 启动 DNS

nameserver / nameserver-policy
  → 普通业务域名

proxy-server-nameserver
  → 代理节点服务器域名

direct-nameserver
  → 最终走 DIRECT 的目标域名

最重要的几个结论:

  1. OpenClash 管理和改写配置,Mihomo 执行配置;
  2. 最终主 YAML 不等于所有 Provider 完全展开后的单体文件;
  3. proxy-providers 提供节点,proxy-groups 选择节点;
  4. rule-providers 提供匹配条件,rules 决定出口;
  5. 规则严格从上到下,第一条命中即停止;
  6. Fake-IP 通过虚拟 IP 保存域名信息;
  7. DIRECT 仍然经过 Mihomo;
  8. 防火墙层 RETURN 才是真正不进入核心;
  9. DNS 是透明代理分流链路的组成部分,不是附属功能;
  10. 完全不用 IPv6 时,应同时关闭内核、DNS、OpenClash 和 OpenWrt 系统 IPv6。

参考资料

Last updated:

基于 VitePress 构建 · 工程、交易与系统研究日志