之前写过一篇配置服务器代理的博客。当时只是照着网络教程完成了配置,并没有弄清楚其中的原理。后来才发现,那套方法本质上是在服务器上运行代理内核,因此这里重新整理一下在 Linux 服务器上部署 Mihomo 和 MetaCubeXD 的几种方法。
下文统一使用 Mihomo 指代服务器上的代理内核,使用 MetaCubeXD 指代 Mihomo 的 Web 管理界面。
整体技术路线
这套配置包含两条相对独立的访问路径。
服务器上的命令行程序通过本地代理端口访问网络:
服务器上的程序 │ │ HTTP / SOCKS5 ▼127.0.0.1:7890 │ ▼ Mihomo │ ▼ 代理节点 │ ▼ Internet本地浏览器则通过服务器的 9090 端口访问 MetaCubeXD:
本地浏览器 │ │ http://服务器IP:9090/ui/ ▼ MetaCubeXD │ │ Mihomo REST API ▼ MihomoMetaCubeXD 只负责展示状态和切换节点,不负责转发代理流量。即使关闭浏览器,只要 Mihomo 进程仍在运行,服务器上的代理就可以继续工作。
本文记录三种方案:
- 使用本地代理客户端导出的完整
config.yaml。 - 自己编写配置,通过
proxy-providers自动更新订阅。 - 使用基于方案二编写的管理脚本自动完成部署。
方案一和方案二使用相同的目录、Mihomo 内核、MetaCubeXD 文件以及启动方式,区别只在于 config.yaml 的来源和内容。方案三是独立的自动化方案,不要将它的文件结构与前两个手动方案混用。
方案一和方案二的共同准备
下载 Mihomo
先使用下面的命令查看服务器的 CPU 架构:
uname -m然后从 Mihomo Releases 下载与服务器 操作系统和 CPU 架构 对应的版本。将压缩包解压后,把可执行文件命名为 mihomo,并放入 ~/mihomo/:
mkdir -p ~/mihomocd ~/mihomo为 Mihomo 添加执行权限:
chmod +x mihomo如果没有执行这一步,运行 ./mihomo 时通常会看到 Permission denied。方案一和方案二使用的是原生二进制文件,不能通过 bash ./mihomo 启动;出现权限错误时,应使用 chmod +x mihomo 添加执行权限。
下载 MetaCubeXD
进入 ~/mihomo/,将 MetaCubeXD 已经构建好的 gh-pages 分支克隆到 ui/:
cd ~/mihomogit clone -b gh-pages --depth 1 https://github.com/MetaCubeX/metacubexd.git ui这里不需要克隆开发分支,因为 Mihomo 的 external-ui 需要的是已经构建好的静态文件。
准备完成后的目录结构大致如下:
~/mihomo/├── mihomo└── ui/ ├── index.html └── ...接下来只需要根据所选方案准备 config.yaml。
方案一:使用导出的完整配置
这种方法最简单:从本地代理客户端导出一份与 Mihomo 兼容的完整配置,将其命名为 config.yaml,然后上传到 ~/mihomo/。
最终目录结构如下:
~/mihomo/├── mihomo├── config.yaml└── ui/ ├── index.html └── ...打开导出的 config.yaml,确认或修改下面这些配置项:
# 服务器本机使用的代理端口mixed-port: 7890allow-lan: false
# MetaCubeXD 和 Mihomo Web APIexternal-controller: 0.0.0.0:9090secret: "REPLACE_WITH_A_RANDOM_SECRET"external-ui: ui如果配置文件中已经存在同名字段,应修改原字段,不要在 YAML 中重复定义同一个键。
其中,mixed-port: 7890 表示在同一个端口上同时提供 HTTP 和 SOCKS5 代理。allow-lan: false 表示该代理端口只供服务器本机使用,不对其他设备开放。
external-controller: 0.0.0.0:9090 表示控制接口监听服务器上的所有网络接口,以便从其他设备访问 MetaCubeXD。external-ui: ui 则表示使用 Mihomo 工作目录下的 ui/ 作为 Web 页面目录。
可以使用下面的命令生成一个随机 Secret:
od -An -N24 -tx1 /dev/urandom | tr -d ' \n'这个方案能够保留导出配置中的节点、代理组和分流规则,适合临时使用,或者本地已经维护好一套完整配置的情况。缺点是订阅发生变化后,服务器上的配置不会自动同步,通常需要重新导出并上传。
方案二:使用 proxy-providers 管理订阅
如果准备让 Mihomo 在服务器上长期运行,可以将订阅地址写入 proxy-providers,由 Mihomo 定时拉取节点。主配置只负责定义代理端口、代理组和规则,不再直接保存节点信息。
在 ~/mihomo/config.yaml 中写入:
# 基础配置mixed-port: 7890allow-lan: falsemode: rulelog-level: infoipv6: falseunified-delay: truetcp-concurrent: true
# MetaCubeXD 和 Mihomo Web APIexternal-controller: 0.0.0.0:9090secret: "REPLACE_WITH_A_RANDOM_SECRET"external-ui: ui
# 保存代理组的选择结果profile: store-selected: true
# 订阅proxy-providers: subscription: type: http url: "REPLACE_WITH_YOUR_SUBSCRIPTION_URL" path: ./proxy_providers/subscription.yaml interval: 3600 proxy: DIRECT header: User-Agent: - "mihomo" health-check: enable: true url: https://www.gstatic.com/generate_204 interval: 300 timeout: 5000 lazy: true expected-status: 204
# 代理组proxy-groups: - name: PROXY type: select proxies: - AUTO - DIRECT use: - subscription
- name: AUTO type: url-test use: - subscription url: https://www.gstatic.com/generate_204 interval: 300 tolerance: 50 lazy: true
# 所有进入 Mihomo 的流量交给 PROXYrules: - MATCH,PROXY其中有两个地方必须修改。
首先将:
url: "REPLACE_WITH_YOUR_SUBSCRIPTION_URL"替换为与 Mihomo 兼容的订阅地址。订阅地址通常包含账户 Token,不要将真实地址提交到 GitHub 或其他公开仓库。
然后将:
secret: "REPLACE_WITH_A_RANDOM_SECRET"替换为随机生成的 Mihomo Web API 密码。
proxy-providers
下面的配置定义了一个名为 subscription 的 Provider:
proxy-providers: subscription: type: http url: "订阅地址" path: ./proxy_providers/subscription.yaml interval: 3600 proxy: DIRECTinterval: 3600 表示每小时更新一次订阅。由于后面使用 ~/mihomo/ 作为 Mihomo 的工作目录,因此节点缓存的实际位置是:
~/mihomo/proxy_providers/subscription.yamlproxy: DIRECT 表示直接连接订阅服务器,不经过当前代理节点。这样可以避免代理节点异常时影响订阅更新,但前提是服务器能够直连订阅地址。如果订阅地址只能通过代理访问,就需要准备一个不依赖当前 Provider 的独立代理作为下载通道。
proxy-groups 和 rules
PROXY 是最终使用的选择组。Provider 中的节点会通过:
use: - subscription自动加入该组。可以在 MetaCubeXD 中手动选择节点,也可以选择 AUTO 或 DIRECT。
AUTO 使用 url-test 定期测试节点并选择延迟较低的节点。延迟最低不代表所有网站的访问效果都最好,如果遇到出口 IP 受限等情况,仍然可以在 PROXY 中手动切换节点。
当前配置只有一条规则:
rules: - MATCH,PROXY这表示所有进入 Mihomo 的代理流量都会交给 PROXY。proxy-providers 只负责加载节点,不会导入本地客户端中的代理组和分流规则。如果需要国内直连、国外代理等复杂分流,需要在 MATCH 之前继续添加规则。
检查并启动 Mihomo
下面的步骤同时适用于方案一和方案二。
先进入工作目录并检查配置:
cd ~/mihomo./mihomo -t -d .配置检查成功只能说明 YAML 和配置项能够正常解析,并不代表订阅服务器或代理节点一定可以连接。
第一次运行时,建议先在前台启动并观察日志:
./mihomo -d .确认没有配置错误、端口冲突或订阅下载失败后,可以按 Ctrl+C 停止前台进程,再使用 nohup 放到后台:
nohup ./mihomo -d . >mihomo.log 2>&1 &echo $! >mihomo.pid查看日志:
tail -f ~/mihomo/mihomo.log停止 Mihomo:
kill "$(cat ~/mihomo/mihomo.pid)"如果配置了其他端口,应以 config.yaml 中的实际值为准。
访问 MetaCubeXD
当配置为:
external-controller: 0.0.0.0:9090external-ui: ui并且 Mihomo 已经成功启动后,可以在本地浏览器中访问:
http://服务器IP:9090/ui/然后填写 config.yaml 中设置的 Secret,即可查看节点、连接、流量和 Provider 状态,或者切换当前使用的节点。
需要注意,0.0.0.0:9090 会让控制接口监听所有网络接口,而普通 HTTP 不会加密 Secret 和控制流量。因此至少应当:
- 设置足够强的 Secret。
- 使用服务器防火墙或云平台安全组,将
9090限制为可信 IP 访问。 - 需要长期通过公网访问时,使用带 HTTPS 的反向代理保护控制接口。
在服务器终端中使用代理
环境变量应该在 Mihomo 成功启动,并确认实际的 mixed-port 之后再设置。它们控制的是服务器当前 Shell 中的命令行程序,与浏览器访问 MetaCubeXD 的 9090 端口无关。
如果 mixed-port 为 7890,在需要代理的服务器终端中执行:
export http_proxy='http://127.0.0.1:7890'export https_proxy='http://127.0.0.1:7890'export all_proxy='socks5h://127.0.0.1:7890'export HTTP_PROXY='http://127.0.0.1:7890'export HTTPS_PROXY='http://127.0.0.1:7890'export ALL_PROXY='socks5h://127.0.0.1:7890'export no_proxy='localhost,127.0.0.1,::1'export NO_PROXY='localhost,127.0.0.1,::1'同时设置大写和小写变量,是因为不同程序读取的变量名称可能不同。socks5h 中的 h 表示域名解析也通过 SOCKS5 代理完成。
这些环境变量只影响当前 Shell 以及从当前 Shell 启动的子进程,不会自动修改整个服务器的网络路由。可以使用下面的命令测试:
curl -I https://www.google.comcurl https://ipinfo.io如果配置中的端口不是 7890,必须将所有环境变量中的端口改成实际的 mixed-port。
不再需要代理时,可以取消这些变量:
unset http_proxy https_proxy all_proxyunset HTTP_PROXY HTTPS_PROXY ALL_PROXYunset no_proxy NO_PROXY更新 MetaCubeXD
方案一和方案二都使用 Git 管理 ui/,可以通过下面的命令更新:
cd ~/mihomo/uigit pull --ff-onlyMetaCubeXD 只是静态页面,更新后刷新浏览器即可。方案二中的 Provider 会按照 interval 自动更新节点,但 Mihomo 内核本身仍然需要手动下载和替换。
方案三:使用管理脚本
根据方案二的配置思路,我另外写了一个简单的管理脚本。如果不想手动下载内核、编写配置和管理后台进程,可以直接使用 mihomo-metacubexd。
脚本会自动处理内核下载、订阅管理、端口分配、配置生成和后台运行,同时提供 MetaCubeXD 管理界面。具体安装方法和使用命令直接查看项目 README 即可,这里不再重复展开。