Files
mihomo-up/README.md
T
im0o c756a92ba3 feat: 多订阅、地区分组、回国模式、多入站、GEO 管理
回国模式生成 .mrs 规则集而不是用 GEOIP:国内站挂在境外 CDN 时解析出的
IP 不在本国段,只靠 GEOIP 会整片漏掉,所以域名维度打头、IP 维度兜底。

GEO 菜单列出数据文件的大小和更新时间,因为下载失败是静默的 —— 规则
一条都匹配不上,流量全落到 MATCH,看起来像「配置没生效」。

入站每条写成一行带标记的 YAML 流式映射,增删就是加一行删一行。
2026-08-09 18:36:59 +08:00

296 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# mihomo-up
一个 bash 脚本,在 Linux 服务器上安装好、配置好、管起来 [mihomo](https://github.com/MetaCubeX/mihomo) 内核(Clash.Meta 的继任者,MetaCubeX 维护的代理内核)。
一条命令从零到能用:下载内核 → 写入 systemd 服务 → 用向导生成 `config.yaml` → 启动。之后修改订阅、更换端口、升级、回滚、卸载也都在同一个菜单里。
安装完成后,这台机器上会多出这几样东西——**卸载时它们全都能一键清掉**:
| | 默认位置 |
|---|---|
| 内核二进制 | `/usr/local/bin/mihomo` |
| 配置文件 | `/etc/mihomo/config.yaml` |
| systemd 服务 | `/etc/systemd/system/mihomo.service` |
| 快捷命令 | `/usr/local/bin/mihomo-up` |
| 脚本缓存 | `/var/lib/mihomo-up/` |
| 内核备份 | `/var/backups/mihomo/` |
除此之外它不碰你系统里的任何东西。
## 环境要求
- Linux + bash 4 以上
- 依赖命令:`curl`、`gzip`、`install`、`awk`、`sed`(一般发行版自带)
- 安装、升级、修改配置、卸载都需要 **root**。非 root 也能进菜单,会先提醒一句
- 没有 systemd 的机器(容器等)也能用:脚本跳过服务相关步骤,只管内核和配置,你自己 `mihomo -d /etc/mihomo` 启动起来
交互输入读的是 `/dev/tty` 而不是标准输入,所以 `bash <(curl ...)` 这种 stdin 已被占用的运行方式,菜单照样能按键。
## 快速开始
**交互菜单**(推荐,首次安装和日常维护都用它):
```bash
bash <(curl -fsSL https://git.im0o.top/im0o/mihomo-up/raw/branch/main/mihomo-up.sh)
```
菜单第 1 项就是一键安装。运行完你会拿到:本机的 HTTP/SOCKS5 代理端口、一个 Web 面板地址和它的访问密钥、一个开机自启的 systemd 服务。
还会拿到一个 `mihomo-up` 命令——**以后直接输入它就能进菜单**,不用再翻上面这条 URL。
**命令行**:
```bash
chmod +x mihomo-up.sh
sudo ./mihomo-up.sh install # 一键安装:内核 + systemd + 配置向导 + 启动
./mihomo-up.sh check # 只查询不改动:当前版本 vs 最新版本
sudo ./mihomo-up.sh update # 只更换内核二进制,配置和服务定义不动
sudo ./mihomo-up.sh config # 重新运行配置向导
sudo ./mihomo-up.sh rollback # 内核回滚到上一个备份
sudo ./mihomo-up.sh uninstall # 卸载,会逐项问你配置和备份要不要删除
sudo ./mihomo-up.sh shortcut # 只安装 / 刷新 mihomo-up 快捷命令
```
## 菜单里有什么
```
1. 一键安装 内核 + systemd + 配置,缺哪步补哪步
2. 检查更新 3. 升级内核 4. 安装指定版本内核
5. 回滚内核 6. 查看内核备份
7. 配置管理 订阅 / 端口 / 局域网 / 面板密钥 / 入站端口 / GEO / 导入 / 校验 / 编辑 / 备份
8. 服务控制 启动 / 停止 / 重启 / 状态 / 最近日志 / 开机自启 / 重写服务文件
9. 卸载
```
## 一键安装做了什么
1. **下载内核**:按机器架构从 GitHub Releases 下载对应的 `.gz` 并解压
2. **校验内核**:新二进制必须能执行,且 `-v` 自报的版本号和目标一致,否则不写入磁盘
3. **准备配置**:没有 `config.yaml` 就运行配置向导;已经有了就保持不动,只问一句要不要重做
4. **写入服务**:按 [MetaCubeX 官方文档](https://wiki.metacubex.one/startup/service/)的推荐写 `mihomo.service`。已存在且内容不同的话,旧文件先备份成 `.bak-<时间戳>`
5. **安装快捷命令**:问一句,可以拒绝。它是什么见「快捷命令 `mihomo-up`」一节
6. **启动服务**:`daemon-reload` → `enable`(开机自启)→ `restart`,启动不了就提示你看 `journalctl`
每一步都是「缺什么补什么」:已经安装过的机器再运行一遍,不会覆盖你现有的配置。
安装完成后会打印一段总结:代理端口怎么用、面板地址和密钥是什么、日志怎么看。
## 快捷命令 `mihomo-up`
一键安装会往 `/usr/local/bin/mihomo-up` 放一个启动器。它**不是脚本本体,而是每次执行都去拉取最新脚本再运行**——你更新了仓库,机器上下次输入 `mihomo-up` 就自动用上新版,不需要谁去手动更新。
```bash
mihomo-up # 进菜单,参数原样透传
mihomo-up check --json # 子命令照样能用,退出码也透传
```
和纯粹的"每次重新下载"不同的是,它会把拉到的脚本落一份缓存到 `/var/lib/mihomo-up/`,并在这两种情况下回落到缓存:
- **拉取失败**(网络断了、仓库挂了)。这条对代理管理脚本尤其要紧:你最需要它的时候,往往正是代理挂了、网络不正常的时候,那时候还得能进菜单重启服务、看日志。
- **拉到的东西没通过 `bash -n` 语法检查**(上游推了个坏版本,或者中间设备塞回来一个门户登录页)。宁可用旧的,也不以 root 执行来路不明的半个脚本。
抓取带 5 秒连接 / 20 秒总超时,网络卡住不会让菜单一直转着等。
fork 之后想让快捷命令指向你自己那份,安装的时候加 `--script-url <你的 raw 地址>`,或者设环境变量 `MIHOMO_UP_URL`。
> **cron 里别用它**:每次执行都联网拉取脚本,等于给定时任务多加一个失败点。定时任务直接指向缓存那份 `/var/lib/mihomo-up/mihomo-up.sh`,或者你自己固定的副本。
## 配置向导问什么
向导生成的是一份**最小可用配置**,够用,不臃肿:
| 问题 | 说明 |
|---|---|
| 订阅链接 | 机场给的 http(s) 地址。**可以填多个**,一次一个,回车结束(最多 8 个) |
| 本地代理端口 | `mixed-port`,HTTP 和 SOCKS5 共用,默认 7890 |
| 局域网共享 | `allow-lan`,开了同网段其它设备也能连(还要放行防火墙) |
| 管理接口 | 只允许本机 / 局域网公网可访问 / 不开启。面板和 API 都连这里 |
| 访问密钥 | 回车即自动生成随机串;管理接口开在 `0.0.0.0` 时务必设 |
| Web 面板 | 选是就写 `external-ui-url`,内核首次启动自己去下载 metacubexd |
| 地区分组 | 留空=不拆。填 `HK JP US` 之类就按地区各建一个自动测速组 |
| 分流规则 | 三选一,见下面的表 |
多个订阅的节点会合并进同一组。每个订阅是一条独立的 `proxy-providers`,各自按 24 小时周期更新。
**地区分组**支持 `HK TW JP SG US KR UK DE FR`。每个地区一个 `url-test` 组,靠节点名里的关键词匹配,中英文和旗帜 emoji 都认。
注意:某个地区一个节点都没匹配上的话内核会拒绝启动,紧接着的校验会当场告诉你。
**分流规则**三选一,内网地址在哪种模式下都直连:
| 模式 | 生成的规则 | 用途 |
|---|---|---|
| 1 全部走代理 | `MATCH,PROXY` | 默认 |
| 2 指定地区直连、其余走代理 | `GEOIP,<CC>,DIRECT` + `MATCH,PROXY` | 常见的翻墙用法 |
| 3 指定地区走代理、其余直连 | `RULE-SET,...` + `MATCH,DIRECT` | 回国 / 分区代理 |
地区填两位 ISO 代码(`CN`、`US`、`JP`、`DE`…),小写自动转大写。
生成的分组是 `PROXY`(总开关,手动选,默认跟着 AUTO)、`AUTO`(全部节点里自动测速),加上你要的那几个地区组。
## 回国 / 分区代理
上面的模式 3 是反过来的:命中的地区走代理,其余直连。适合人在境外、只想让国内站点走国内节点。
它不用 `GEOIP`,而是生成两条 `.mrs` 规则集:
```yaml
rules:
- RULE-SET,cn-domain,PROXY # 域名维度
- RULE-SET,cn-ip,PROXY,no-resolve # IP 维度兜底
- MATCH,DIRECT
```
**为什么必须有域名那份**:很多国内站挂着境外 CDN,域名解析出来的 IP 不在国内段,只靠 `GEOIP` 会整片漏掉。域名列表才是主力,IP 那条只兜住「直接连 IP、没有域名」的连接。
`.mrs` 是二进制规则集,只下载你要用的那一两个列表,不用拖整包 `geosite.dat`。下载走 `proxy: DIRECT`,因为你人在境外,直连最快。
有个限制脚本会当场告诉你:**只有 CN 有成体系的域名列表**。换成别的国家代码就只能按 IP 匹配,该地区挂境外 CDN 的站点会漏掉。
## 多开入站端口
一个端口对应一个出站——从 7801 进来的全走香港节点,从 7802 进来的全走日本。菜单「配置管理 → 入站端口」增删,写成 mihomo 的 `listeners`:
```yaml
listeners:
- { name: in-7801, type: mixed, listen: 0.0.0.0, port: 7801, proxy: HK }
- { name: in-7802, type: mixed, listen: 0.0.0.0, port: 7802 }
```
用法就是把代理地址指到不同端口:
```bash
curl -x http://127.0.0.1:7801 https://example.com # 走 HK 组
curl -x http://127.0.0.1:7802 https://example.com # 按 rules 分流
```
出站可以选任意一个已有策略组、`DIRECT`,或者「按 rules 分流」。
**选了具体出站就完全跳过 rules**:这个端口的流量一律走它,包括本该直连的内网以外流量。脚本在你选完之后会提醒一次。想保留分流就选「按 rules」。
类型支持 `mixed`(HTTP + SOCKS5 同口)、`http`、`socks`。端口和主代理端口或其它入站冲突会被当场拒绝。
## GEO 数据和规则集
`GEOIP`、`GEOSITE`、`RULE-SET` 规则都要靠数据文件才能匹配。内核缺文件时会自己去下载,但**下载失败是静默的**。
失败的表现是:规则一条都匹配不上,流量全落到最后的 `MATCH`,看起来就像"配置没生效"——你会先去怀疑节点,而不是怀疑一个几天前静默失败的下载。
菜单「配置管理 → GEO / 规则集」把这件事变可见:列出配置目录里的 `geoip.dat`、`geosite.dat`、`*.mmdb` 和 `rules/*.mrs`,带大小和上次更新时间。几天没变就是没更新成功。
「立即更新」优先走管理接口的 `POST /configs/geo`,**不用重启内核**。管理接口没开、或服务没在运行时,回退到删掉数据文件再重启服务重新下载(动手前会问你)。
「自动更新 开/关」写的是 `geo-auto-update` 和 `geo-update-interval: 24`。
## 改配置的安全网
上面这些改动——换订阅、改端口、加入站、开关自动更新——都不用手写 YAML,也都走同一套保护。
每次动手之前自动备份成 `config.yaml.bak-<时间戳>`,改完立刻用内核 `-t` 校验。**校验不过会问你要不要还原**,服务正在运行的话再问一句要不要重启生效。
需要手写的复杂配置(DNS、TUN、自定义规则)请用菜单里的「手动编辑配置」,或者用「从 URL 导入完整配置」整份换掉——这两条路同样有备份、校验、还原兜底。
## 升级和回滚
`update` 只更换内核二进制,不动你的配置和服务定义。替换前有两道闸门,任一不过就中止:
1. 新二进制能运行起来,且 `-v` 自报的版本号和目标一致
2. 用**新版本**去 `-t` 校验你**现有的**配置
第二道是为了挡住「新内核不认旧配置」这种升完才发现的问题。配置本来就有毛病、但你只想更换内核时,加 `--skip-conf-check` 跳过它。
替换前旧内核备份到 `/var/backups/mihomo/`(保留最近 3 份)。升级后服务启动不了会**自动回滚**到旧版并重启,然后提示你看 `journalctl -u mihomo -n 50`。
任何一步失败都不会留下半个系统:要么没动,要么已回滚。
## 卸载会删什么
```bash
sudo ./mihomo-up.sh uninstall # 逐项确认
sudo ./mihomo-up.sh uninstall --purge # 全部删除,不询问
```
直接删掉:内核二进制、`mihomo.service` 及其备份、`mihomo.service.d/` drop-in 目录、快捷命令和它的缓存。systemd 那边会先 stop 再 disable,然后 `daemon-reload` + `reset-failed` 把状态清干净。
会单独问你的两项:配置目录 `/etc/mihomo`(订阅、节点选择记录、面板文件都在里面)、内核备份目录 `/var/backups/mihomo`。留着的话下次重新安装能直接接上。
## 在 cron / CI 里用
无参数运行时,脚本会看 stdin 是不是终端:是就进菜单,被管道或 cron 调用就安静地运行 `check`。
`check` 的退出码专为脚本化设计:
| 退出码 | 含义 |
|---|---|
| 0 | 已是最新 |
| 10 | 有新版(或还没安装) |
| 1 | 出错 |
例子——有新版就自动升级:
```bash
mihomo-up.sh check && exit 0
[ $? -eq 10 ] && mihomo-up.sh update -y
```
加 `--json` 会额外输出一行机器可读的 JSON:
```json
{"current":"v1.19.27","latest":"v1.19.28","outdated":true}
```
## GitHub 直连不通时
内核、版本号、Web 面板都从 GitHub 下载。机器直连 GitHub 失败或太慢时,用 `--mirror` 指定一个反代前缀,脚本会把它拼在所有 GitHub 地址前面:
```bash
sudo ./mihomo-up.sh install --mirror https://ghfast.top/
```
带 `--mirror` 运行配置向导时,生成的配置里会额外写上走同一个镜像的 `geox-url`,免得内核首次启动下载 GeoIP 数据库时卡住。
## 选项一览
| 选项 | 作用 |
|---|---|
| `-y, --yes` | 非交互确认,所有询问都当作同意 |
| `-n, --dry-run` | 只打印会做什么,不实际改动 |
| `--force` | 版本相同也重新安装 |
| `--version <v>` | 指定内核版本,如 `v1.19.28` |
| `--no-restart` | 安装完成后不启动服务 |
| `--purge` | `uninstall` 时连配置目录和备份一起删除 |
| `--skip-conf-check` | 升级时不用新版本预校验现有配置 |
| `--json` | `check` 时额外输出一行 JSON |
| `--arch <a>` | 覆盖自动识别的架构:`amd64` / `arm64` / `armv7` |
| `--variant <v>` | amd64 微架构变体:`v1` / `v2` / `v3` / `compatible` |
| `--mirror <url>` | GitHub 反代前缀,用法见上一节 |
| `--script-url <u>` | 快捷命令每次去拉的脚本地址(fork 后指到你自己那份) |
| `--bin <path>` | 内核路径,默认 `/usr/local/bin/mihomo` |
| `--conf-dir <dir>` | 配置目录,默认 `/etc/mihomo` |
| `--service <name>` | systemd 服务名,默认 `mihomo` |
| `-v` | 打印脚本自身版本 |
## 默认值与环境变量
命令行选项优先级最高,其次是环境变量,最后是下面这些默认值:
| 默认值 | 环境变量 |
|---|---|
| `/usr/local/bin/mihomo` | `MIHOMO_BIN` |
| `/etc/mihomo` | `MIHOMO_CONF_DIR` |
| `mihomo`(systemd 服务名) | `MIHOMO_SERVICE` |
| `/var/backups/mihomo` | `MIHOMO_BACKUP_DIR` |
| 空(不用镜像) | `MIHOMO_MIRROR` |
| `/usr/local/bin/mihomo-up`(快捷命令) | `MIHOMO_UP_LAUNCHER` |
| `/var/lib/mihomo-up`(脚本缓存) | `MIHOMO_UP_CACHE` |
| 仓库 raw 地址(快捷命令拉取源) | `MIHOMO_UP_URL` |
内核备份最多保留 3 份(脚本内常量 `KEEP=3`)。配置备份不自动清理,积累多了自己删除 `config.yaml.bak-*`。
## 参考
systemd 服务写法来自 [MetaCubeX 官方文档](https://wiki.metacubex.one/startup/service/)。
一键安装和卸载的思路参考了 [ForLoveIcu/mihomo-for-linux-install](https://github.com/ForLoveIcu/mihomo-for-linux-install) 和 [nelvko/clash-for-linux-install](https://github.com/nelvko/clash-for-linux-install)。