先确定部署形态:桌面客户端还是独立内核
Linux 上的 Clash 部署通常分成两条路线。桌面环境可以使用带配置管理、代理组切换和日志查看功能的图形客户端;服务器、开发机或长期在线的小主机更适合直接运行 Clash Meta(mihomo) 内核,再由 systemd 管理进程。两种路线底层都需要读取 YAML 配置,但启动方式、权限范围和系统代理接入方法不同。
| 使用环境 | 建议形态 | 主要优点 | 需要关注 |
|---|---|---|---|
| GNOME、KDE Plasma 桌面 | GUI 客户端 | 导入订阅、切换节点和查看日志更直接 | 桌面代理设置、托盘支持、内核权限 |
| 无桌面的云主机 | mihomo + systemd | 资源占用明确,可自动重启 | 配置路径、运行用户、监听地址 |
| 开发工作站 | GUI 或独立内核 | 可为 Git、包管理器和容器单独配置代理 | 环境变量作用域与 DNS 行为 |
| 网关或旁路由 | mihomo TUN 或透明代理 | 可以接管更多应用流量 | 路由表、nftables、DNS 与网络权限 |
如果需求只是让浏览器、Git 和终端命令通过代理,优先从 HTTP、SOCKS 或 mixed 端口开始。TUN 模式会创建虚拟网卡并调整路由,覆盖范围更广,但也会引入 CAP_NET_ADMIN、DNS 接管以及防火墙兼容问题。先验证普通端口稳定,再启用 TUN,排错路径会更短。
安装 mihomo 二进制并规划目录
安装前先确认处理器架构。常见的 x86_64 对应 amd64,树莓派 4、部分云主机和新款开发板通常是 arm64。不要只根据发行版名称判断架构,直接读取系统结果更可靠。
uname -m
getconf LONG_BIT
cat /etc/os-release
当 uname -m 返回 x86_64 时选择 amd64 构建;返回 aarch64 时选择 arm64 构建。下载并解压对应文件后,将实际二进制安装到固定路径。以下示例假设解压后的文件名为 mihomo-linux-amd64:
sudo install -m 0755 ./mihomo-linux-amd64 /usr/local/bin/mihomo
/usr/local/bin/mihomo -v
建议把程序、只读配置和运行数据分开。二进制放在 /usr/local/bin,主配置放在 /etc/mihomo,缓存、Geo 数据、代理提供者文件和运行状态放在 /var/lib/mihomo。这样既方便 systemd 限制写入范围,也能避免更新二进制时覆盖配置。
sudo useradd --system \
--home-dir /var/lib/mihomo \
--shell /usr/sbin/nologin mihomo
sudo install -d -m 0750 -o root -g mihomo /etc/mihomo
sudo install -d -m 0750 -o mihomo -g mihomo /var/lib/mihomo
sudo install -d -m 0750 -o mihomo -g mihomo /var/lib/mihomo/providers
sudo install -m 0640 -o root -g mihomo ./config.yaml /etc/mihomo/config.yaml
先准备可验证的基础配置
一个便于本机使用的基础配置可以监听 mixed 端口 7890,并把外部控制接口限制在回环地址。mixed 端口同时接受 HTTP 和 SOCKS 连接,适合终端工具、浏览器和桌面代理设置共同使用。
mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
secret: "linux-local-controller-2026"
profile:
store-selected: true
store-fake-ip: true
这里没有列出代理节点、代理组和 rules,因为这些内容应来自实际可用的配置或订阅。导入后要确认最终规则包含兜底策略,例如 MATCH,PROXY 或名称与实际代理组一致的规则。代理组名称区分大小写,规则引用了不存在的组时,配置测试会直接报错。
sudo -u mihomo /usr/local/bin/mihomo \
-t \
-f /etc/mihomo/config.yaml \
-d /var/lib/mihomo
测试成功时会看到配置加载完成相关信息;出现 YAML 解析错误时,应先检查缩进、冒号后的空格以及代理组名称。YAML 不允许使用 Tab 代替层级缩进。配置测试通过之前不要创建自动重启循环,否则日志会被重复启动信息淹没。
编写 systemd 服务并设置开机常驻
systemd 单元应明确运行用户、工作目录、重启策略和允许写入的路径。普通 HTTP、SOCKS 代理不需要 root 权限,也不需要网络管理能力。以下单元适用于不启用 TUN 的基础部署。
[Unit]
Description=mihomo proxy service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=mihomo
Group=mihomo
WorkingDirectory=/var/lib/mihomo
ExecStartPre=/usr/local/bin/mihomo -t -f /etc/mihomo/config.yaml -d /var/lib/mihomo
ExecStart=/usr/local/bin/mihomo -f /etc/mihomo/config.yaml -d /var/lib/mihomo
Restart=on-failure
RestartSec=5s
LimitNOFILE=1048576
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
ReadWritePaths=/var/lib/mihomo
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
[Install]
WantedBy=multi-user.target
将内容保存为 /etc/systemd/system/mihomo.service,然后重新载入单元并启动。enable --now 会同时设置开机启动和立即启动,不需要再单独执行一次 start。
sudo systemctl daemon-reload
sudo systemctl enable --now mihomo
systemctl status mihomo --no-pager
journalctl -u mihomo -n 80 --no-pager
检查端口与控制接口
服务显示 active 只代表进程仍在运行,还应确认 7890 和 9090 的监听地址。预期结果应是 127.0.0.1:7890 与 127.0.0.1:9090,而不是对全部网卡开放的 0.0.0.0。
ss -lntp | grep -E '7890|9090'
curl --max-time 5 \
--proxy http://127.0.0.1:7890 \
-I https://www.gstatic.com/generate_204
连接正常时,测试请求通常在 0.4 至 2 秒内返回 204 或代理链可解释的 HTTP 状态。若 5 秒超时,先查看 mihomo 日志中是否选中了代理组,再检查节点连接错误;若立即出现 Connection refused,问题通常发生在本机端口监听,而不是远端代理。
终端代理变量:当前会话、长期配置与单个命令
Linux 终端程序不会因为 mihomo 已经运行就自动走代理。curl、wget、Git、语言包管理器是否读取系统桌面代理,取决于各自实现。最通用的方法是在当前 Shell 设置 HTTP_PROXY、HTTPS_PROXY 和 ALL_PROXY。
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,.local
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export no_proxy="$NO_PROXY"
socks5h 中的 h 表示域名交给 SOCKS 代理端解析,可减少本地 DNS 解析与代理路径不一致的情况。大小写变量同时设置,是因为不同工具读取的变量名并不统一。变量仅对当前 Shell 及其子进程生效,已经打开的终端标签页不会自动获得后续修改。
按作用范围选择写法
- 只代理一个命令:
HTTPS_PROXY=http://127.0.0.1:7890 curl https://example.com。 - 只代理当前终端:直接执行 export,关闭会话后失效。
- Bash 长期生效:写入
~/.bashrc,再执行source ~/.bashrc。 - Zsh 长期生效:写入
~/.zshrc,重新打开终端或执行source ~/.zshrc。 - Git 单独设置:使用
git config --global http.proxy http://127.0.0.1:7890。
需要取消当前会话代理时,应同时删除大小写变量,避免某个工具继续读取遗留值。
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
unset http_proxy https_proxy all_proxy no_proxy
git config --global --unset http.proxy
git config --global --unset https.proxy
sudo 默认可能过滤代理环境变量,systemd 服务也不会继承交互式 Shell 的 ~/.bashrc。如果某个后台服务确实需要代理,应为该服务创建独立 drop-in,在 [Service] 下设置 Environment=,而不是修改全局系统环境。这样可以把代理影响限制在目标服务内。
Linux 桌面客户端与系统代理接入
图形客户端适合需要频繁导入订阅、切换代理组和观察连接记录的桌面用户。选择时应确认客户端提供 Linux 构建、内核路径可识别、配置存储位置明确,并支持当前桌面环境。常见发行格式包括 AppImage、Deb、RPM 和压缩包。
不同安装格式的处理重点
- AppImage:先执行
chmod +x,再以普通桌面用户启动。部分精简系统需要安装 FUSE 兼容组件。 - Deb:适用于 Debian、Ubuntu 及其衍生发行版,可用
sudo apt install ./客户端文件.deb安装并处理依赖。 - RPM:适用于 Fedora、Rocky Linux、openSUSE 等环境,具体使用 dnf 或 zypper。
- 压缩包:需要自行维护桌面入口、更新路径与可执行权限,适合希望固定版本的环境。
桌面客户端通常包含「系统代理」「TUN 模式」「开机启动」等开关。只需要浏览器和遵循桌面代理设置的软件时,开启系统代理即可。以 GNOME 为例,对应设置位于「设置」→「网络」→「网络代理」;KDE Plasma 6 通常位于「系统设置」→「网络」→「代理」。手动配置时,HTTP、HTTPS 和 SOCKS 主机均可填写 127.0.0.1,端口填写客户端显示的实际 mixed 端口,例如 7890。
不要同时启动 GUI 客户端内核和前文的 systemd 内核并让它们都监听 7890。出现端口冲突时,后启动的实例通常会报告 address already in use。如果需要保留两套环境,应给其中一套改用 17890、17891 等不同端口,并分别检查外部控制端口。
启用 TUN 模式时的权限与 DNS 设置
TUN 模式可以接管不读取 HTTP 代理变量的应用,例如部分游戏启动器、封闭式桌面程序以及使用自定义网络栈的软件。mihomo 会创建虚拟网络设备并调整路由,因此至少需要 CAP_NET_ADMIN。某些网络操作还会使用 CAP_NET_RAW。应只为服务授予所需能力,不必把整个进程改成 root 用户。
可通过 sudo systemctl edit mihomo 创建覆盖配置:
[Service]
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
PrivateDevices=false
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
保存后执行以下命令使覆盖配置生效:
sudo systemctl daemon-reload
sudo systemctl restart mihomo
systemctl show mihomo -p AmbientCapabilities
ip address show
ip route show table all
TUN 配置的关键字段
tun:
enable: true
stack: mixed
auto-route: true
auto-redirect: true
strict-route: true
dns-hijack:
- any:53
auto-route 用于自动写入路由,auto-redirect 可在支持的 Linux 环境利用 nftables 改善流量接管,strict-route 用于减少流量绕过。具体字段是否适合当前系统,要结合 NetworkManager、systemd-networkd、Docker 和已有防火墙规则判断。容器网络、公司 VPN 与 TUN 都可能写入策略路由,冲突时应对比启用前后的 ip rule 和 ip route show table all。
DNS 是 TUN 排错的重点。请求能连接 IP、却无法访问域名时,先运行 resolvectl status 和 resolvectl query example.com。如果系统已有 systemd-resolved 占用本机 53 端口,不要再让 mihomo 的普通 DNS 监听直接绑定同一地址与端口。可以使用高位端口,例如 127.0.0.1:1053,再由明确的系统配置转发;也可以让 TUN 的 DNS 劫持处理经过虚拟网卡的 53 端口请求。
高频故障定位:从进程、端口到规则结果
服务反复重启
先读取当前启动周期日志,而不是连续重启:
systemctl status mihomo --no-pager
journalctl -u mihomo -b -n 120 --no-pager
sudo -u mihomo /usr/local/bin/mihomo \
-t \
-f /etc/mihomo/config.yaml \
-d /var/lib/mihomo
常见原因包括 YAML 缩进错误、代理组引用不存在、配置文件权限不足、Geo 数据目录不可写,以及监听端口已被另一个客户端占用。
7890 已监听,但终端仍然直连
检查当前进程实际获得的变量,而不是只查看配置文件:
env | grep -i proxy
curl --max-time 5 -I https://example.com
curl --max-time 5 --proxy http://127.0.0.1:7890 -I https://example.com
如果第二条失败而第三条成功,说明 mihomo 工作正常,问题在终端代理变量或应用自身设置。如果两条都失败,再查看日志中的 DNS、握手或节点超时信息。
订阅已更新,但节点列表没有变化
代理提供者文件应放在 mihomo 用户可写的目录,例如 /var/lib/mihomo/providers。检查文件更新时间、provider 的健康检查结果和订阅返回内容。systemd 的 ProtectSystem=strict 会阻止服务写入未列入 ReadWritePaths 的目录,因此不要把动态 provider 文件放到只读的 /etc/mihomo。
TUN 开启后局域网或容器失联
先关闭 TUN,确认 mixed 端口仍能工作,再比较 TUN 启用前后的路由与规则。局域网网段通常需要直连规则,例如 192.168.0.0/16、10.0.0.0/8 和 172.16.0.0/12。Docker 常使用 172.17.0.0/16,但实际网段应以 docker network inspect 输出为准,不能假设所有主机都相同。
更新与回滚:保持配置和程序相互独立
更新内核前先记录当前版本,并保留正在工作的二进制。由于配置与程序已经分离,回滚只需要恢复旧二进制并重启服务,不必覆盖 /etc/mihomo/config.yaml 或 provider 数据。
/usr/local/bin/mihomo -v
sudo cp /usr/local/bin/mihomo /usr/local/bin/mihomo.previous
sudo systemctl stop mihomo
sudo install -m 0755 ./mihomo-linux-amd64 /usr/local/bin/mihomo
sudo -u mihomo /usr/local/bin/mihomo \
-t \
-f /etc/mihomo/config.yaml \
-d /var/lib/mihomo
sudo systemctl start mihomo
如果新版本无法启动,可执行 sudo install -m 0755 /usr/local/bin/mihomo.previous /usr/local/bin/mihomo 后重新启动。升级完成后还应检查日志、端口、代理组选择和一条实际网络请求。只看到版本号变化,不能替代完整的运行验证。