Skip to content

Clash.Meta(mihomo) 杂谈

架构

Clash.Meta(mihomo) 内核架构如下图所示 (由 DeepSeek-R1 生成)

+-----------------------+
|    User Interface     |  # 用户配置入口(YAML 文件、API 等)
+-----------------------+
           |
           v
+-----------------------+
|     Core Engine       |  # 核心引擎,负责流量调度和规则匹配
|-----------------------|
|  - Rule Matcher       |  # 根据规则(DOMAIN/IP/GEOIP 等)匹配流量
|  - Traffic Router     |  # 将流量路由至指定代理组或策略
|  - Connection Manager |  # 管理 TCP/UDP 连接和复用
+-----------------------+
           |
           v
+-----------------------+
|   Protocol Handlers   |  # 协议支持模块
|-----------------------|
|  - HTTP/Socks5        |  # 基础代理协议
|  - VMess/VLESS        |  # V2Ray 系列协议
|  - Trojan/SS/SSR      |  # 常见代理协议
|  - WireGuard/Tuic     |  # 高性能协议(UDP 优化)
|  - Hysteria/ShadowTLS |  # 特殊协议(抗干扰/伪装)
+-----------------------+
           |
           v
+-----------------------+
|    Transport Layer    |  # 底层传输模块
|-----------------------|
|  - TLS 封装/混淆       |  # 流量加密和伪装
|  - UDP 中继/转发       |  # 支持 QUIC 等 UDP 协议
|  - 网络栈优化          |  # 多路复用、拥塞控制等
+-----------------------+
           |
           v
+-----------------------+
|   Platform Adapters   |  # 平台适配层
|-----------------------|
|  - Linux/macOS/Windows|  # 各平台网络栈适配
|  - Android/iOS        |  # 移动端支持(TUN 模式)
|  - 路由器/嵌入式设备    |  # 跨平台兼容
+-----------------------+

你说得对,但是和 Clash For Windows/ClashX/Clash Meta For Android/Clash Verge/Clash Nyanpasu/Mihomo Party/... 有什么关系?🤔

以上应用都是基于 clash/mihomo 二次开发的 GUI,其中大部分只做了基础的前端(甚至适配度不及 metacubex 等 WebUI)。

NOTE: Clash For Windows/Clash Meta For Android 均以平台命名,实际都支持多平台 (CFW - Windows/Linux, CMFA - Android/Windows),唉文字游戏!

Clash For Windows(CFW) 因不可抗力事件已经停更多年,缺少新内核/协议支持,不推荐继续使用。

基于 Tauri 的 Clash Verge 同样停更,后续衍生出 Clash Verge Rev/Clash Nyanpasu 两个分支,另外还有若干 Electron GUI。(和这些浏览器套壳虫豸在一起,怎么能搞好系统呢 😠)

客观上部分 GUI 提供了 mixin 等功能,方便管理多配置文件同时 overlay,但这些功能往往存在问题,相对 mihomo 内核而言维护不力;前端配置自由度受限,甚至和实际运行配置不符 (mihomo 自动回滚);TUN mode 等功能要求提权,被系统拦截时使用不便,另外也导致前端存在安全隐患......

对于想要摆脱 GUI 依赖,精细化控制配置文件的进阶用户,可以只启用 mihomo service,通过编辑 config.yaml 控制配置。

bash
# 获取订阅链接下发配置作为参考
# UA clash.meta 版本可以瞎填,因为大概率 UA 只匹配 ^clash\.meta
curl -X GET --user-agent "clash.meta/1.19.1" "<subscription-link>"

# 之后可以结合几个配置文件修改出个人配置
# 标准配置(GeoX) https://wiki.metacubex.one/example/geox
# 标准配置(Rule-Set) https://wiki.metacubex.one/example/mrs
# 完整配置 https://github.com/MetaCubeX/mihomo/blob/Meta/docs/config.yaml

以下是部分个人推荐设置 (mixed-port + TUN):

yaml
# Clash.Meta (mihomo)
# 省略 proxy 相关配置

ipv6: true
allow-lan: true # 允许局域网其他设备访问
mixed-port: 7890 # http/https/socks 混合端口
external-controller: 127.0.0.1:9090 # 不知道 127.0.0.1 和 0.0.0.0 区别的请自行搜索,IPv6 [::] 和 [::1] 同理
external-ui: dashboard

profile:
  store-selected: true # 持久化节点选择
  store-fake-ip: true # 持久化解析记录

tun:
  enable: true
  stack: mixed
  # device: Meta # MacOS TUN device name 仅为 "utun"
  dns-hijack:
    - "any:53"
    - "tcp://any:53"
  # 自动设置 `ip route` 路由全局流量经过 TUN device
  # 设置后须手动设置系统 DNS 为非局域网 DNS 或 Clash.Meta DNS,否则会导致 DNS 泄露
  auto-route: true
  auto-redirect: true # 仅 Linux/Android,自动配置 iptables/nftables 重定向 TCP (依赖 auto-route)
  auto-detect-interface: true # 多网络连接时自动设置出站接口
  # strict-route: true
  # 排除路由对应接口,可解决 docker/podman 容器内网络回环问题
  exclude-interface:
    - "docker*"
    - "podman*"
  # 排除网段,可解决 WireGuard/Tailscale 冲突
  route-exclude-address:
    - 192.168.0.0/16
    - fc00::/7

dns:
  enable: true
  listen: :1053
  ipv6: true
  ipv6-timeout: 200
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*"
    - "+.lan"
    - "+.local"
  nameserver:
    - https://dns.google/dns-query
    - https://doh.pub/dns-query
    - https://dns.alidns.com/dns-query

一般发行版启用 systemd 服务参考 https://wiki.metacubex.one/startup/service/

NixOS 配置如下

nix
{ config, ... }:
  services.mihomo = {
    enable = true;
    tunMode = true;
    configFile = "path/to/config.yaml";
    # (optional) 使用 sops-nix 加密
    # configFile = config.sops.templates.mihomo.path;
  };

  ## add sub entry in secrets.yaml through `sops /path/to/secrets.yaml` ##
  # sops.secrets.sub = { };
  # sops.templates.mihomo.content = ''
      # same as config.yaml
      # ...
      proxy-providers:
        my-sub:
          url: ${config.sops.placeholder.sub}
      # ...
  '';

通过 http://<external-controller>/ui 即可访问 WebUI。

Troubleshooting

开启 TUN mode 时 Docker/Podman/WireGuard/... 网络不可用?

启用 TUN mode 并设置 excluded-interface (容器服务) / route-exclude-address (VPN 服务)。

不想使用 mihomo 内置 DNS 解析?

首先在 config.yaml 设置 dns.enable: false 使用系统 DNS。

以 Linux 为例,修改 /etc/resolv.conf 内容 (语法参考 resolv.conf)

NOTE: 启用 NetworkManager 可能会自动修改设置内容 (参考 NetworkManager dns 以及 rc-manager 部分)。

大部分发行版默认启用 systemd-resolved 自动管理 DNS 设置,此时 NetworkManager 会推送 DNS 设置到 systemd-resolved。

更改系统 DNS manager 流程:

NetworkManager set dns=none -> 禁用 systemd-resolved -> 启用 dnsproxy/dnscrypt/smartdns/... -> 设置 /etc/resolv.conf 到 DNS manager bind port

个人建议使用 smartdns,配置可参考 我有特别的 DNS 配置和使用技巧 文档

NixOS 参考配置:

nix
{ ... }:
{
  services.resolved.enable = false;
  services.smartdns = {
    enable = true;
    settings = {
      # Basic
      bind = "[::]:53";
      # Upstream
      server = [
        "202.120.2.100 -group domestic -exclude-default-group" # SJTU fallback
      ];
      server-tls = [
        "223.5.5.5 -b -group domestic -exclude-default-group"
        "223.6.6.6 -group domestic -exclude-default-group"
        "one.one.one.one -proxy mihomo"
        "dns.google -proxy mihomo"
      ];
      server-https = [
        "https://dns.google/dns-query -proxy mihomo"
        "https://doh.pub/dns-query -group domestic"
      ];
      # Cache
      serve-expired = true;
      serve-expired-ttl = 259200;
      serve-expired-reply-ttl = 3;
      prefetch-domain = true;
      serve-expired-prefetch-time = 21600;
      cache-size = 32768;
      cache-checkpoint-time = 86400;
      # Dual stack (v4/v6)
      dualstack-ip-selection = "yes";
      # Speedtest
      speed-check-mode = "none";
      # Proxy (assuming that mihomo listen socks5 at port 7890)
      proxy-server = "socks5://127.0.0.1:7890 -name mihomo";
      # Other config
      conf-file = [
        # Ref: https://blog.skk.moe/post/i-have-my-unique-dns-setup#%E5%9C%A8-SmartDNS-%E4%B8%AD%E4%BD%BF%E7%94%A8-dnsmasq-china-list-%E8%BF%9B%E8%A1%8C%E5%88%86%E6%B5%81
        (toString /path/to/dnsmasq-china-list/accelerated-domains.china.domain.smartdns.conf)
        (toString /path/to/dnsmasq-china-list/apple.china.domain.smartdns.conf)
      ];
    };
  };

  networking = {
    networkmanager = {
      enable = true;
      dns = "none";
    };
    nameservers =
      if (config.networking.networkmanager.dns == "none") then
        [ "127.0.0.1:53" ]
      else
        [
          "8.8.8.8"
          "1.1.1.1"
          "119.29.29.29"
        ];
  };
}