为什么桌面「能跑」还不够,要用 systemd 做常驻

在 Linux 上,很多人习惯解压一个 Mihomo(Clash Meta)二进制,终端里 ./mihomo -d ./config 一把梭,能用就关终端走人。问题是:SSH 断开、终端关闭、偶发崩溃或 OOM 都会让进程悄悄消失;重启后还要记得手动起一次。对「长期当网关或本机出口」的场景,这等于把稳定性交给运气。

systemd 的价值在于把 Mihomo 变成标准系统服务:开机进入目标运行级别时自动启动;进程异常退出时按策略自动重启;日志统一进 journal,便于和内核、防火墙、其它服务的记录对照。你仍然可以用自己喜欢的 GUI 或 Web 面板去改配置,但进程生命周期交给 init 系统,更符合服务器与长期桌面使用的预期。

本文假设你已经能手动启动 Mihomo 并加载 config.yaml。若你刚换内核或字段名对不上,建议先对照《Clash Meta(Mihomo)升级完整指南》核对配置与启动参数,再服务化,避免把「配置不兼容」误判成「systemd 坏了」。

前置:二进制路径、配置目录与运行用户

做 unit 之前,先固定三件事:可执行文件绝对路径配置目录(或单文件)以哪个用户运行。常见做法是二进制放到 /usr/local/bin/mihomo,配置放在 /etc/mihomo,目录内包含 config.yaml 以及 rulesetprovider 等子目录(具体依你的订阅与规则结构而定)。

运行用户上,尽量避免「默认 root 跑代理内核」。更稳妥的是专用系统用户(如 clash),目录归属 chown 给该用户,只开放写订阅缓存、Geo 数据库等必要路径。只有在你必须使用 TUN 且发行版对非 root 建 tun 设备限制较多时,才需要在能力与权限上做额外设计,下文单独说明。

手动试跑时,请用与未来 systemd 相同的用户执行一次 mihomo -d /etc/mihomo(或你的等价路径),确认无报错后再写入 service,能显著减少「一 enable 就 failed」的折腾。

编写 mihomo.service:最小可用模板

/etc/systemd/system/mihomo.service(路径因发行版略有差异,以你系统为准)新建 unit,下面是一份最小可用示例,请按实际路径与用户替换:

[Unit]
Description=Mihomo (Clash Meta) proxy daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=clash
Group=clash
WorkingDirectory=/etc/mihomo
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=5s
LimitNOFILE=1048576

# Hardening (adjust if your setup writes outside these paths)
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

要点说明:Type=simple 适合前台运行的主进程;Restart=on-failure非零退出时重启,能覆盖多数崩溃场景。若你希望「任何退出都拉起」,可改为 Restart=always,但要小心配置错误导致无限快速重启——此时应先看 journal 修配置。After=network-online.target 减少「起得太早、DNS 尚不可用」一类竞态,并不能替代你在 YAML 里把 DNS 与规则写稳。

若你的可执行文件名是 clash-meta 或发行版包名不同,只需改 ExecStart 指向真实路径;若使用单文件配置,可改用内核支持的 -f /path/to/config.yaml 形式,并保持 WorkingDirectory 与相对路径引用一致。

启用、启动与日常命令

写入 unit 后执行:sudo systemctl daemon-reload,然后 sudo systemctl enable --now mihomo.serviceenable 负责开机自启,--now 立即启动。日常检查可用 systemctl status mihomo 看是否 active,systemctl restart mihomo 在改完配置后reload 前重启(是否支持热重载取决于你如何更新配置与是否调用 API)。

若状态里出现 failed,优先看下文日志章节;同时核对 mixed-portsocks-port 等是否被其它服务占用——这类问题在 systemd 里表现为启动瞬间退出,和《Clash 日志:端口占用与节点超时》中的「本机监听失败」是同一条排查链。

日志:用 journalctl 与内核日志对齐

服务化之后,不建议再依赖「终端里滚屏」。用 journalctl -u mihomo -e 跟随单元日志,或用 journalctl -u mihomo --since "10 min ago" 截取一段时间。若你同时在排网络栈问题,可把 dmesg、防火墙拒绝日志与 Mihomo 日志放在同一时间轴上看,更容易判断是本机策略还是出口链路

当你看到大量 dial tcp 与超时关键字时,先别急着改 unit,而应回到规则、DNS 与节点质量;单元本身只负责「把进程养住」。若你希望日志更细,可在 config.yaml 里调整日志级别,但注意长期 debug 会撑爆 journal 与磁盘,生产环境建议按需临时打开。

与订阅、规则提供方更新衔接

systemd 只管进程,不会替你「定时拉订阅」。实务上有两条常见路径:其一,依赖 Mihomo 内置的 proxy-providers / rule-providers 周期更新(你在 YAML 里配置间隔);其二,用外部脚本或 .timer 单元在固定时刻触发更新,再通过外部控制器 REST API请求重载配置或刷新提供方。

使用 API 时务必设置强密钥、限制监听地址(例如只绑 127.0.0.1),避免把控制面暴露到局域网或公网。更系统的规则提供方写法可参考《Clash 规则提供方(Rule Providers)配置指南》,把「拉取失败、格式不兼容、路径不可写」等问题在配置层解决,而不是反复重启服务碰运气。

TUN、能力与「能不能不用 root」

开启 TUN 时,进程通常需要创建虚拟网卡、改路由表,这对非特权用户是敏感操作。不同发行版对 CAP_NET_ADMIN、设备节点权限的策略不同:有的场景给单元加 AmbientCapabilities=CAP_NET_ADMIN 再配合 CapabilityBoundingSet 即可;有的环境仍要求以 root 运行或额外配置 udev。若你暂时搞不定能力集,务必缩小暴露面:控制 API 仅本机、防火墙默认拒绝入站、敏感配置权限收紧。

若你不需要全局 TUN,仅本机应用走 mixed-port / socks-port,通常专用用户 + 上述 hardening 就够用,也更易审计。

再谈安全边界与文件权限

代理配置里往往含订阅 URL、节点凭证与个人隐私相关策略。/etc/mihomo 建议目录权限 0750、配置 0640,属主为运行用户;避免 world-readable。若你用 Git 管理规则仓库,注意不要把带 token 的 URL 提交进公开 remote。PrivateTmp=true 等选项能隔离临时目录,但若你的脚本必须写固定路径,要在单元里显式放行对应 ReadWritePaths

常见坑:WorkingDirectory、相对路径与双实例

一类典型失败是 YAML 里写了相对路径,而 WorkingDirectory 与手动 cd 的起始目录不一致,导致 ruleset 文件找不到,进程立刻退出。另一类是双实例:桌面客户端与 systemd 各起了一个 Mihomo,端口互抢,表象是「随机断连」。服务化后请明确:只保留一条启动路径,GUI 若自带内核,应选择「连接外部内核」或关闭其内置进程,避免打架。

合规与边界

本文仅介绍在 Linux 上使用开源代理内核与 systemd 的通用技术,不构成对任何地区法律法规的规避建议。请在你所在地法律允许的范围内使用网络技术,并尊重服务提供商条款与他人权益。

小结

把 Mihomo 交给 systemd,本质是补齐进程管理这一层:开机自启、失败恢复、统一日志。配置本身仍要遵循 DNS、规则与订阅的最佳实践;排障时把 journal 与日志关键词对照结合,能更快区分本机端口与出口链路问题。

相比只在终端里临时启动,一款与 Mihomo 同步迭代、带清晰图形界面与下载渠道的 Clash 系客户端,往往能把「写配置、看日志、升级内核」连成闭环。若你更习惯图形环境而非纯命令行,也可先到本站下载页选择适合自己平台的版本,再在 Linux 服务器侧用本文思路做无头常驻。→ 立即免费下载 Clash,开启流畅上网新体验