Linux 与系统

mihomo / Clash:裸核部署、规则进阶与订阅管理

从裸核出发完成 mihomo 双平台部署,先接订阅管理(proxy-providers 或自建 Sub-Store 聚合转换),再配好 fake-ip、DNS 分流与 no-resolve 的零泄漏规则,最后挂上 Web 面板对外管理。

很多人接触 Clash 都是从 Clash for Windows / ClashX / Stash 这种带 GUI 的客户端开始的。但当你想在 VPS 上跑代理网关给家里几台机器共用、在 Linux 服务器上做链式代理或落地机、或者完全自定义订阅规则和面板,就需要直接玩 mihomo(Clash Meta)的裸核——一个二进制、一份 YAML 配置、一个 systemd 单元,齐活。

本文按真实依赖顺序拆成三段:先部署(含订阅管理),再配规则与 DNS,最后挂 Web 面板。

一、mihomo 的运行模型

先看整体数据流:

mermaid14 行
graph LR
subgraph 客户端
B[浏览器 / app] -->|HTTP / SOCKS5| L[本机 7890/7891]
end
L --> M[mihomo 进程
裸核]
M --> D{DNS / 规则匹配}
D -->|国内站| DR[DIRECT 直连]
D -->|国外站| P[代理节点
VLESS / VMess / SS]
M --> U[external-controller
9090 面板 API]
U --> UI[zashboard / metacubexd
Web UI]

核心三件套:

文件 / 路径 作用
/usr/bin/mihomo 主程序二进制
/etc/mihomo/config.yaml 配置(节点 + 规则 + DNS)
~/.config/mihomo/ 运行时数据(缓存 / Geo 数据 / UI)
/etc/systemd/system/mihomo.service systemd 单元

工作目录 ~/.config/mihomo/ 里通常有这些东西:

文件 / 目录 说明
ui/ 外部面板的静态文件
proxies/ 订阅 provider 缓存
ruleset/ rule-provider 缓存
cache.db 运行缓存(fake-ip、选择记录)
GeoIP.dat / GeoSite.dat Geo 数据
系统 路径
Linux root /root/.config/mihomo
Linux 普通用户 /home/<用户名>/.config/mihomo
Windows C:\Users\<用户名>\.config\mihomo

二、Linux 部署裸核

下面以 Debian/Ubuntu 为例,其它发行版把包格式换成对应的即可。

2.1 装包

去官方 release 拉对应架构的 .deb:

plaintext1 行
https://github.com/MetaCubeX/mihomo/releases

服务器拉不动 GitHub 是常态。可以先在本地下载好再 scp 上去,或者用 jsdelivr / ghproxy 这类镜像。

假设 .deb 已经在当前目录,安装并确认:

plaintext6 行
sudo dpkg -i mihomo-*.deb
sudo apt -f install -y

# 确认安装结果
which mihomo
mihomo -v

2.2 端口与监听规划

代理服务要占几个端口,先规划好:

plaintext4 行
port: 7890           # HTTP
socks-port: 7891     # SOCKS5
mixed-port: 7893     # 混合(推荐应用都走这个)
tproxy-port: 7894    # 透明代理(TUN 用)

应用配置代理时统一用 mixed-port: 7893,不用区分协议。

局域网访问要单独控制,VPS 上建议收紧:

plaintext9 行
allow-lan: false             # 是否允许局域网设备使用
bind-address: "127.0.0.1"    # 只监听本机
authentication:
  - "username:password"      # HTTP/SOCKS 代理需要认证

lan-allowed-ips:
  - "127.0.0.1/8"
  - "::1/128"
  - "172.16.0.0/12"          # Docker 桥接子网

VPS 上allow-lan: false + bind-address: 127.0.0.1 是基本操作:代理端口只对本机开放,外部访问走 nginx 反代或 SSH 隧道。

2.3 放最小可用配置

/etc/mihomo/config.yaml 是核心。先给一个最小可用模板(完整版后面给):

plaintext23 行
# 监听端口
port: 7890           # HTTP 代理
socks-port: 7891     # SOCKS5
mixed-port: 7893     # 混合(HTTP/SOCKS5)

allow-lan: false
bind-address: "127.0.0.1"

# Web 面板
external-controller: 0.0.0.0:9090
secret: "your_strong_secret_here"
external-ui: /root/.config/mihomo/ui

mode: rule
log-level: info

proxies: []
proxy-groups:
  - name: PROXY
    type: select
    proxies: [DIRECT]
rules:
  - MATCH,PROXY

secret 是 Web 面板的 API 密码,务必改成 16 位以上随机字符串,否则等于把代理控制权暴露到公网。放入到位并收紧权限:

plaintext4 行
sudo cp config.yaml /etc/mihomo/config.yaml

# 订阅链接里通常带 token,配置权限设成 600
sudo chmod 600 /etc/mihomo/config.yaml

2.4 下载 Geo 数据

第一次启动 mihomo 会自动拉 Geo 数据,但服务器从 GitHub 拉经常超时。手动下载:

plaintext16 行
cd /root/.config/mihomo/

# 先清旧的
sudo rm -f GeoSite.dat GeoIP.dat Country.mmdb GeoLite2-ASN.mmdb

sudo curl -L --retry 5 --connect-timeout 20 \
  -o GeoSite.dat \
  https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat

sudo curl -L --retry 5 --connect-timeout 20 \
  -o GeoIP.dat \
  https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat

sudo curl -L --retry 5 --connect-timeout 20 \
  -o Country.mmdb \
  https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb

下载失败可以走 jsdelivr 镜像,在 config.yaml 里加:

plaintext5 行
geox-url:
  geoip: https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat
  geosite: https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat
  mmdb: https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/country.mmdb
  asn: https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/GeoLite2-ASN.mmdb

2.5 前台验证

先不建服务,前台跑一次看有没有报错:

plaintext1 行
sudo mihomo -f /etc/mihomo/config.yaml

看到没有报错、监听端口出现,浏览器能打开面板说明基本通了(首次访问如果加载不出来,按 Ctrl+Shift+R 强刷绕过旧缓存):

plaintext1 行
http://<你的服务器 IP>:9090/ui/

2.6 systemd 服务化

验证 OK 之后 Ctrl+C 停掉,写 service 文件:

plaintext21 行
sudo tee /etc/systemd/system/mihomo.service >/dev/null <<'EOF'
[Unit]
Description=Mihomo Proxy Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/mihomo -f /etc/mihomo/config.yaml
Restart=on-failure
RestartSec=2
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable mihomo
sudo systemctl start mihomo
sudo systemctl status mihomo

查日志确认运行:

plaintext1 行
journalctl -u mihomo -f

2.7 开放防火墙端口

端口 用途 公网是否开放
9090 Web 面板 / API 建议只对白名单 IP 开放
7890–7893 HTTP / SOCKS5 代理 不要开,只给本机用

面板端口放行:

plaintext2 行
sudo ufw allow 9090
sudo ufw status

千万别把 7890 这类代理端口直接开到公网,否则 VPS 会变成所有人的免费代理,很快被滥用、被商家封号。

2.8 本机使用代理

导出环境变量走代理,并测试:

plaintext6 行
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export all_proxy=socks5://127.0.0.1:7891

# 测试
curl https://www.google.com -I

取消代理:

plaintext1 行
unset http_proxy https_proxy all_proxy

三、Windows 裸核部署

Windows 上一般直接用 Clash Verge / FlClash 这类 GUI 客户端,但也能跑裸核:

plaintext5 行
# 1. 下载 mihomo-windows-amd64.zip 解压到 C:\mihomo
# 2. 配置文件放到 C:\Users\<你的用户>\.config\mihomo\config.yaml
# 3. 前台运行
cd C:\mihomo
.\mihomo.exe -d $env:USERPROFILE\.config\mihomo

做成开机自启:

方案 推荐度 说明
任务计划程序 最简 开机触发执行
NSSM 注册服务 推荐 跑成 Windows 服务
WSL2 跑 Linux 版 可选 折腾,但有人喜欢

四、订阅管理

4.1 直接在 mihomo 里挂订阅

不写一堆 proxies:,直接挂订阅 URL:

plaintext7 行
proxy-providers:
  Airport1:
    url: "https://your-subscription-link"
    type: http
    interval: 86400
    health-check: { enable: true, url: https://www.gstatic.com/generate_204, interval: 300 }
    override: { udp: true, additional-prefix: "[A1]" }

配置好之后,proxy-groups 里可以用 use: [Airport1] 引用这个 provider 的节点。订阅链接里通常带 token,记得把配置文件权限设成 600(见 2.3)。

4.2 Sub-Store:聚合并转换多个订阅

机场一多,每个链接格式还不一样——有的 Clash YAML、有的 base64、有的 share link。手动管理几条还行,多了之后要聚合、过滤、重命名、一键导出多客户端格式,Sub-Store 是社区里功能较完整的工具。

订阅工具分 3 类:

工具 重点 适合
subconverter 格式转换 在线一次性转换
Sub-Store 节点聚合 + 过滤 + 编排 长期管理多个机场
surgio 规则集生成 高度自定义需求

Sub-Store 的主要能力:

  • 多机场聚合到一个订阅链接
  • 节点筛选(正则 / 国家 / 协议 / 倍率)
  • 节点改名(去广告 + 加标识)
  • 格式输出:Clash / V2rayN / Shadowrocket / Surge / Loon 全支持
  • 定时备份到 WebDAV / S3
  • 有 iOS / Android / Web 三端 UI

整体架构:

mermaid11 行
graph LR
A1[机场 A 订阅] --> SS[Sub-Store
聚合/筛选/改名]
A2[机场 B 订阅] --> SS
A3[自建节点] --> SS
SS --> O1[Clash 客户端]
SS --> O2[Shadowrocket]
SS --> O3[Surge / Loon]
SS --> O4[V2rayN]
N[Nginx 反代
HTTPS] --> SS

部署后客户端只填一个 Sub-Store 生成的 URL,所有机场节点都聚合进来。

Docker Compose 部署

先建数据目录:

plaintext1 行
mkdir -p /opt/sub-store/data

/opt/sub-store/docker-compose.yml:

plaintext14 行
services:
  sub-store:
    image: xream/sub-store:http-meta
    container_name: sub-store
    restart: always
    environment:
      # 定时备份到自定义存储(可选)
      - SUB_STORE_BACKEND_UPLOAD_CRON=55 23 * * *
      # 自定义后端路径(关键,防扫)
      - SUB_STORE_FRONTEND_BACKEND_PATH=/your_secret_path
    volumes:
      - /opt/sub-store/data:/opt/app/data
    ports:
      - "127.0.0.1:3001:3001"        # 只绑本机,外网走 nginx 反代

关键环境变量:

变量 说明
SUB_STORE_FRONTEND_BACKEND_PATH 必设:自定义后端路径,相当于密码
SUB_STORE_BACKEND_UPLOAD_CRON 定时备份的 cron 表达式(可选)
SUB_STORE_BACKEND_API_HOST API 域名(自动检测,一般不设)
SUB_STORE_DATA_BASE_PATH 数据目录(一般用默认)
SUB_STORE_BACKEND_DEFAULT_FLOW_USER_AGENT 拉机场订阅时的 UA

SUB_STORE_FRONTEND_BACKEND_PATH 是唯一防护——这个路径就是 Sub-Store 后端的“密码”,设一个长一点的随机字符串。

启动并确认:

plaintext5 行
cd /opt/sub-store
docker compose up -d

# 看日志确认启动
docker compose logs -f

端口为什么要绑 127.0.0.1:3001,明明 3001:3001 更省事:Sub-Store 默认不强制认证,任何能访问端口的人都能改配置。127.0.0.1 绑定意味着只有本机 nginx 反代能访问,必须通过反代 + 自定义路径 + HTTPS 把它保护起来。

Nginx 反代 + HTTPS

用 1Panel 的话,网站 → 创建网站 → 反向代理:

字段 值
主域名 substore.your-domain.com
代理地址 http://127.0.0.1:3001
HTTPS 开启 + 用 DNS 自动签

完成后浏览器访问 https://substore.your-domain.com 就能看到 Sub-Store 的 Web UI。

不用 1Panel 的话,手动 nginx 配置:

plaintext25 行
server {
    listen 443 ssl http2;
    server_name substore.your-domain.com;

    ssl_certificate     /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

server {
    listen 80;
    server_name substore.your-domain.com;
    return 301 https://$host$request_uri;
}

首次访问 Web UI

访问 https://substore.your-domain.com,第一次需要填后端路径:

字段 值
后端地址 https://substore.your-domain.com
后端路径 /your_secret_path(和 docker compose 里的一致)

填对进 UI 即可。界面字段随版本会变,入口以当前版本 UI 为准。

核心功能

订阅 → 添加:

字段 值
名称 随便,如 机场A
类型 单条 / 组合订阅
链接 机场提供的订阅 URL
用户代理 通常 clash.meta 或 clashx.pro

填完保存,Sub-Store 会自动拉机场节点。

在订阅上右键 → 编辑预处理,能加节点操作脚本:

操作 用途
节点过滤器 按关键词/正则筛节点(去广告)
节点重命名 加标识 / 国家旗 / 删多余信息
节点类型过滤 只保留 vless / 排除 trojan
节点排序 按延迟 / 按国家排
去重 删重复节点

社区有大量现成脚本,搜「Sub-Store 脚本」就有。

组合订阅把多个机场聚合成一条:订阅 → 添加 → 组合订阅 → 勾选多个子订阅 → 保存,输出一条包含所有勾选机场节点的 URL。

文件 → 添加可以上传自己的节点列表、规则集、mihomo / Clash 模板,之后在订阅里引用这些文件。

生成订阅 URL

在订阅列表点订阅 → 下载 → 选目标格式:

客户端 格式
Clash / Clash Verge / mihomo Clash
Shadowrocket Shadowrocket
Surge Surge
Loon Loon
V2rayN V2ray
sing-box sing-box

每种都会生成一个 URL,这个 URL 就是客户端要填的东西。

订阅格式扫盲

不同的客户端吃不同的格式:

格式 内容 客户端
Share Links 每行一个 vmess:// / ss:// / trojan:// / vless:// V2rayN、Shadowrocket、Clash Meta 都支持
Base64 Share Links 整体 Base64 编码 几乎所有客户端
Clash YAML 完整 YAML 配置(节点+策略组+规则) 仅 Clash 系列

机场给出的订阅 99% 都是 base64 编码的 Share Links。Sub-Store 拉回来之后,按你要的格式重新输出。

定时备份

Sub-Store 的所有数据在 Docker 卷里,容器重建数据就丢,一定要配备份。每周 cron 打包卷目录:

plaintext2 行
0 4 * * 0 tar -czf /backup/sub-store-$(date +\%Y\%m\%d).tar.gz \
  /opt/sub-store/data

设置 → 应用同步可以在 Sub-Store 内部做配置同步,可选 WebDAV(InfiniCLOUD / Koofr / 自建 Alist)、GitHub Gist、自定义 HTTP 同步接口。配好之后每天自动备份配置 + 数据。

五、规则与 DNS

裸核跑起来、订阅也进来了,接下来最可能翻车的是 DNS 这块:fake-ip 是什么?nameserver-policy 怎么写?no-resolve 加不加?看似都对实际却 DNS 泄漏、国内访问变慢。用“老板和秘书”的类比把这三个概念讲透。

5.1 DNS 泄漏是什么

当网页流量走了代理,但 DNS 查询请求却走了本地未加密网络——ISP 仍然能看到你访问了哪些域名,甚至返回错误 IP(DNS 污染)。

mermaid5 行
graph LR
B[浏览器] -.加密代理.-> P[国外节点]
B -.明文 DNS.-> L[本地 ISP DNS]
L -.被劫持/记录.-> ISP[运营商]
P --> T[目标网站]

代理通了不说有安全。DNS 这条路才是真正的隐私问题。

5.2 Fake-IP:核心比喻

把 Clash 当秘书,浏览器当老板。老板要打电话给“谷歌先生”:

没有 Fake-IP(Real-IP / Redir-Host 模式)

  1. 老板:「秘书,查一下谷歌先生的电话。」
  2. 秘书:「您先挂断等着,我去翻电话簿。」
  3. 秘书翻 DNS(可能 50-200ms)。
  4. 秘书:「号码是 142.250.x.x。」
  5. 老板拨号 → 连接代理。

缺点是老板必须等秘书查完才能拨,白屏时间长。

开启 Fake-IP 模式

  1. 老板:「秘书,查一下谷歌先生的电话。」
  2. 秘书直接编一个假号码 198.18.0.1:「号码是 198.18.0.1,快打!」
  3. 老板秒拨。
  4. 秘书拦截这个拨向假 IP 的电话,心里记得“这是谷歌”。
  5. 秘书直接告诉国外的代理节点:「帮我接通谷歌,号码你自己解析。」
  6. 国外节点解析 + 连接谷歌。

优点是 DNS 查询零延迟、真实 DNS 在国外节点解析、浏览器拿到假 IP 时本地完全不查 DNS。

5.3 DNS 分流:国内站走真实 IP

有些站给不了假 IP。比如百度——CDN 会根据你的 IP 给你最近的服务器,给假 IP 会让百度以为你在某个奇怪的地方,分到慢的节点。国内站要禁用 Fake-IP 走真实 IP,这就是 fake-ip-filter:

plaintext7 行
dns:
  fake-ip-filter:
    - "+.lan"
    - "+.local"
    - "geosite:private"
    - "geosite:connectivity-check"   # 微软/安卓的网络连通性检测
    - "geosite:cn"                   # 国内域名走真实 IP

走真实 IP 又要解决该用哪个 DNS 查的问题——国内站走国内 DNS(否则被分到海外 CDN),国外站走国外 DNS(否则被 GFW 污染)。这就是 nameserver-policy:

plaintext8 行
dns:
  nameserver-policy:
    "geosite:cn,private":
      - https://223.5.5.5/dns-query
      - https://doh.pub/dns-query
    "geosite:geolocation-!cn":
      - https://1.1.1.1/dns-query
      - https://dns.google/dns-query

整体流程:

mermaid7 行
graph TD
Q[查询域名] --> F{命中 fake-ip-filter?}
F -->|是 国内域名| R{命中 nameserver-policy?}
F -->|否 国外域名| FK[返回假 IP
真实解析延后到节点]
R -->|geosite:cn| RD[阿里/腾讯 DoH]
R -->|geosite:!cn| RD2[Cloudflare/Google DoH]

5.4 no-resolve:避免本地多余解析

即使开了 Fake-IP,规则匹配阶段 Clash 还可能做一次本地 DNS 查询。举例规则:

plaintext4 行
rules:
  - RULE-SET, youtube, PROXY
  - GEOIP, CN, DIRECT
  - MATCH, PROXY

没有 no-resolve

  1. Fake-IP 给假 IP,浏览器秒连。
  2. Clash 匹配规则:
    • RULE-SET, youtube → 没命中
    • GEOIP, CN → 这是 IP 规则,Clash 必须知道真 IP 才能判断是否 CN
  3. Clash 在本地发起一次 DNS 查询(200ms)
  4. 拿到美国 IP → 走 PROXY → 代理节点再解析一次

白等 200ms 的本地解析。

加上 no-resolve

plaintext4 行
rules:
  - RULE-SET, youtube, PROXY
  - GEOIP, CN, DIRECT, no-resolve
  - MATCH, PROXY
  1. Fake-IP 给假 IP。
  2. 匹配 GEOIP, CN:
    • 看到 no-resolve:「没真实 IP 就别查了,跳过这条」
  3. 没匹配 → 走 MATCH → 代理节点解析 + 连接

本地解析消失,所有解析推迟到节点。

只对 IP 类规则(GEOIP / IP-CIDR)加 no-resolve,对域名类规则(DOMAIN-SUFFIX 等)加了没意义:

规则类型 加 no-resolve?
DOMAIN-SUFFIX 不用
DOMAIN-KEYWORD 不用
RULE-SET(域名集合) 不用
GEOIP 要加
IP-CIDR 要加
IP-CIDR6 要加
GEOSITE 不用

5.5 DoH (DNS over HTTPS)

上面配置里 https://1.1.1.1/dns-query 是 DoH:

DNS 类型 端口 加密 速度
普通 DNS 53 / UDP 否 快但明文
DoT (DNS over TLS) 853 / TCP 是 慢一点
DoH (DNS over HTTPS) 443 / TCP 是 中等
DoQ (DNS over QUIC) 853 / UDP 是 快(HTTP/3)

DoH 的优势是查询内容加密、防污染(GFW 看不到也改不了)、全球可用(Cloudflare / Google 都有 anycast 节点)。国内 DoH 也要用,纯 UDP 的 223.5.5.5:53 仍可能被中间人投毒,用 https://223.5.5.5/dns-query 即可。

5.6 推荐的完整 DNS 配置

plaintext49 行
dns:
  enable: true
  ipv6: false
  listen: 0.0.0.0:1053
  prefer-h3: false
  respect-rules: true              # 让 DNS 解析参考分流规则
  cache-algorithm: arc
  cache-size: 2048
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16

  # Fake-IP 过滤:返回真实 IP 的域名
  fake-ip-filter:
    - "+.lan"
    - "+.local"
    - "geosite:private"
    - "geosite:connectivity-check"
    - "geosite:cn"

  # 用于解析 DoH 域名自身(先有 IP 才能访问 DoH)
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
    - 1.1.1.1
    - 8.8.8.8

  # 代理节点的 DNS(必须国外,防止节点域名被污染连不上)
  proxy-server-nameserver:
    - https://1.1.1.1/dns-query
    - https://dns.google/dns-query

  # 默认 nameserver(视为国外/未知流量,走国外加密 DNS)
  nameserver:
    - https://1.1.1.1/dns-query
    - https://dns.google/dns-query

  # 备用 fallback
  fallback:
    - https://1.1.1.1/dns-query
    - https://8.8.8.8/dns-query

  # 分流策略(核心)
  nameserver-policy:
    "geosite:cn,private":
      - https://223.5.5.5/dns-query
      - https://doh.pub/dns-query
    "geosite:geolocation-!cn":
      - https://1.1.1.1/dns-query
      - https://dns.google/dns-query

配合规则的写法:

plaintext11 行
rules:
  # 域名规则(不需要 no-resolve)
  - DOMAIN-SUFFIX,google.com,PROXY
  - GEOSITE,youtube,PROXY
  - GEOSITE,cn,DIRECT

  # IP 规则(必须加 no-resolve)
  - GEOIP,CN,DIRECT,no-resolve
  - GEOIP,private,DIRECT,no-resolve

  - MATCH,PROXY

5.7 常见配置选项的含义

选项 作用
enable 启用内置 DNS
listen 监听端口(系统 DNS 指向这里能用)
enhanced-mode fake-ip / redir-host 二选一,推荐 fake-ip
fake-ip-range 假 IP 段,默认 198.18.0.1/16 别动
respect-rules DNS 解析时是否走代理规则(推荐 true)
default-nameserver 引导 DNS:解析 DoH 域名本身用
nameserver 主 DNS:默认走它
proxy-server-nameserver 解析代理节点用的 DNS(强烈建议国外)
fallback 主 DNS 全部失败时的备用
nameserver-policy 按域名匹配走不同 DNS(核心)
fake-ip-filter 哪些域名不要假 IP(走真实解析)

5.8 智能选节点与端口分流

mihomo 内置了 smart 类型的代理组,可以自动选最快节点:

plaintext8 行
proxy-groups:
  - name: 香港智能
    type: smart
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    include-all: true
    filter: "(?=.*(港|HK|(?i)Hong))^((?!(台|日|韩|新|深|美|英)).)*$"

filter 是节点名的正则筛选,正向匹配 + 负向排除配合用,能精准抓你想要的国家节点。

也可以把不同端口对应不同国家,应用直接通过端口选地区,不用切换:

plaintext13 行
listeners:
  - name: port-hk
    type: mixed
    port: 42000
    udp: true
  - name: port-jp
    type: mixed
    port: 42002
    udp: true

rules:
  - "IN-PORT,42000,香港智能"
  - "IN-PORT,42002,日本手动"

浏览器扩展配端口 42000 走香港,配 42002 走日本,零延迟切换。

5.9 验证 DNS 没泄漏

跑代理 + 配完上面这套之后,用这几个站验证:

plaintext3 行
https://dnsleaktest.com
https://browserleaks.com/dns
https://ipleak.net

正确的结果是 DNS 服务器全部显示国外(Cloudflare / Google)、IP 显示节点 IP、没有任何国内 ISP 的 DNS 出现。

5.10 常见误配

5.10.1 写了 nameserver-policy 但没生效

可能是规则匹配触发了 IP 类规则解析(没加 no-resolve)。补 no-resolve。

5.10.2 国内站打开很慢

fake-ip-filter 漏了 geosite:cn。

5.10.3 节点显示离线 / 测速不通

proxy-server-nameserver 没设国外 DoH,节点域名被国内 DNS 污染。

5.10.4 微信 / QQ 不能用

fake-ip-filter 漏了 geosite:connectivity-check,或者腾讯系域名误走代理。

5.10.5 fake-ip-range 改成别的段

不要改。默认 198.18.0.1/16 是 RFC 保留段,改别的可能撞真实公网 IP。

六、Web 面板

mihomo 不带 UI,需要放静态文件(zashboard / metacubexd 任选其一)。以 metacubexd 为例:

6.1 安装 UI

plaintext13 行
# 创建 UI 目录
sudo mkdir -p /root/.config/mihomo/ui

cd /tmp
curl -L -o metacubexd.zip \
  https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip
unzip -q metacubexd.zip

sudo rm -rf /root/.config/mihomo/ui/*
sudo cp -a metacubexd-gh-pages/. /root/.config/mihomo/ui/

# 确认
test -f /root/.config/mihomo/ui/index.html && echo "UI OK"

配置里的 external-ui 路径必须和这里的目录完全一致。面板打不开最常见的起因就是路径不一致。external-controller 负责暴露面板 API,和 secret 一对组合要在配置里配好(见 2.3 的最小模板)。

6.2 面板安全

  • secret 用 16 位以上随机字符串,避免公网暴力探测。
  • 9090 端口只对白名单 IP 放行(见 2.7),或干脆用 SSH 隧道访问。
  • external-ui 路径和实际目录保持完全一致。

6.3 验证

plaintext1 行
sudo systemctl restart mihomo

浏览器打开面板:

plaintext1 行
http://<你的服务器 IP>:9090/ui/

第一次访问如果加载不出来,按 Ctrl+Shift+R 强刷绕过浏览器旧缓存,Ctrl+R 不够。

七、常见问题

现象 原因 解决
面板加载不出来 浏览器缓存 / external-ui 路径不一致 先 Ctrl+Shift+R,再核对路径
拉订阅失败 mihomo 拉订阅时不走自己的代理 国内 VPS 拉国外订阅先配 http_proxy
sudo mihomo 看不到环境变量 环境变量没继承 用 sudo -E mihomo ...
Geo 数据下不动 服务器从 GitHub 拉超时 换 jsdelivr 镜像,或手动 scp 上去
DNS 污染导致直连站打不开 dns.fake-ip-filter 没覆盖国内服务 把 NTP、音乐、游戏等国内服务放进去
systemd 起来但本机 curl 不通 bind-address 是 127.0.0.1 却从外网访问 核对监听地址
Sub-Store 访问 UI 显示空白 后端路径不一致 检查 docker env 和 UI 填的
Sub-Store 拉机场 403 UA 触发机场风控 改 UA 为 clash.meta 或别的常见值
Sub-Store 拉机场超时 VPS 在国内 / 机场在国外 给 Docker 配代理
重启 Docker 后 Sub-Store 数据消失 没挂卷 检查 volumes 配置
多人能匿名访问 Sub-Store UI 后端路径太短 改成 32 位随机字符串

八、实用经验

  • fake-ip-filter 必加 geosite:cn + geosite:connectivity-check + geosite:private,少一个国内站都不顺。
  • proxy-server-nameserver 必用国外 DoH,否则节点域名被污染,你以为是机场跑路了。
  • 所有 IP 规则(GEOIP / IP-CIDR)都加 no-resolve,实现零本地解析。
  • 国内 DoH 也要用(https://223.5.5.5/dns-query),纯 UDP 仍可能被投毒。
  • respect-rules: true 让 DNS 解析也走代理规则。
  • prefer-h3: false:网络不稳定时 HTTP/3 偶尔会出怪问题。
  • Sub-Store 的 SUB_STORE_FRONTEND_BACKEND_PATH 必设强密码,端口绑 127.0.0.1,HTTPS 必上(Sub-Store 走 HTTP 明文,所有订阅 token 都在 URL 里)。
  • 预处理脚本是核心生产力:一次写好“去广告 + 改名 + 去重”,永久受益。
  • iOS / Android 端也有 Sub-Store app,能扫码同步配置。

九、之后还能接什么

  • 链式代理 / 落地机:本机 mihomo → 中转 VPS → 落地 VPS
  • TUN 模式接管全局流量:不依赖应用层代理设置

mihomo 的玩法深度比想象中大,把裸核 + systemd 这套跑通之后,后面所有功能都是在这基础上叠加的。

← 返回文章