跳到主要内容

首页 / 博客 / 部署实战

用 Mihomo 做家庭网关:软路由 / NAS 上的透明代理部署

部署实战2026-06-052253 字约 5 分钟
用 Mihomo 做家庭网关:软路由 / NAS 上的透明代理部署

给每台设备装客户端太麻烦,电视、投影仪、IoT 设备根本装不了。把 Mihomo 部署在软路由或 NAS 上,全家设备接入 Wi-Fi 就自动生效。

三种接入方式

三种方案的取舍旁路由 + 手动指网关在需要的设备风险最低,出问题只影响那台设备需要逐台配置新手推荐TProxy 透明代理在网关上用 i设备零配置配置复杂,出错全家断网TUN + auto-route网关上开 TU配置简单性能开销大,软路由 CPU 可能吃不消
先用旁路由手动指定的方式跑通,再考虑要不要上透明代理

本文以 旁路由 + TProxy 为主线,这是家庭场景最实用的组合。

一、安装 Mihomo

以 Linux amd64 软路由 / NAS 为例:

# 下载并解压(架构按实际情况选)
gunzip mihomo-linux-amd64-v1.19.29.gz
chmod +x mihomo-linux-amd64-v1.19.29
sudo mv mihomo-linux-amd64-v1.19.29 /usr/local/bin/mihomo
mihomo -v

# 准备工作目录
sudo mkdir -p /etc/mihomo

ARM 设备(树莓派、ARM NAS)用 linux-arm64 版本,uname -m 输出 aarch64 就是它。

二、配置文件

/etc/mihomo/config.yaml

# ===== 基础 =====
mixed-port: 7890
tproxy-port: 7895          # TProxy 用
redir-port: 7892           # REDIRECT 用(可选)
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
ipv6: false
unified-delay: true
tcp-concurrent: true

external-controller: 0.0.0.0:9090
secret: "改成一个足够长的随机密码"
external-ui: /etc/mihomo/ui

# ===== DNS =====
dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "*.local"
    - "+.home.arpa"
    - "+.pool.ntp.org"
    - "time.*.com"
    - "+.msftconnecttest.com"
    - "+.msftncsi.com"
    - "captive.apple.com"
  default-nameserver: [223.5.5.5, 119.29.29.29]
  nameserver:
    - https://doh.pub/dns-query
    - https://dns.alidns.com/dns-query
  fallback:
    - https://1.1.1.1/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN

# ===== 节点来源 =====
proxy-providers:
  main:
    type: http
    url: "你的订阅链接"
    interval: 3600
    path: ./providers/main.yaml
    header:
      User-Agent: ["clash.meta"]
    exclude-filter: "(?i)剩余|到期|官网|流量"
    health-check:
      enable: true
      url: http://www.gstatic.com/generate_204
      interval: 300
      lazy: true

# ===== 策略组 =====
proxy-groups:
  - name: "PROXY"
    type: select
    proxies: ["AUTO", "HK", "JP", "SG", DIRECT]
  - name: "AUTO"
    type: url-test
    use: [main]
    url: http://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    lazy: true
  - name: "HK"
    type: url-test
    use: [main]
    filter: "(?i)香港|HK|Hong ?Kong"
    interval: 300
    tolerance: 50
  - name: "JP"
    type: url-test
    use: [main]
    filter: "(?i)日本|JP|Japan"
    interval: 300
    tolerance: 50
  - name: "SG"
    type: url-test
    use: [main]
    filter: "(?i)新加坡|狮城|SG|Singapore"
    interval: 300
    tolerance: 50
  - name: "FINAL"
    type: select
    proxies: ["PROXY", DIRECT]

# ===== 规则 =====
rules:
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR,100.64.0.0/10,DIRECT,no-resolve
  - DOMAIN-SUFFIX,lan,DIRECT
  - DOMAIN-SUFFIX,local,DIRECT
  # 按设备分流(示例)
  - SRC-IP-CIDR,192.168.1.50/32,DIRECT          # 老人的手机全直连
  - SRC-IP-CIDR,192.168.1.60/32,PROXY           # 电视全走代理
  # 常规分流
  - GEOIP,CN,DIRECT
  - MATCH,FINAL

三、systemd 服务

/etc/systemd/system/mihomo.service

[Unit]
Description=Mihomo Daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
LimitNOFILE=1000000
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
Restart=always
RestartSec=5
ExecStartPre=/usr/local/bin/mihomo -t -d /etc/mihomo
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo

[Install]
WantedBy=multi-user.target

ExecStartPre 里的 -t 是配置检查——配置写错时服务不会带着坏配置启动,这个细节能省掉很多麻烦。

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo
sudo systemctl status mihomo
journalctl -u mihomo -f

四、方式 A:手动指定网关(推荐先用这个)

不动任何防火墙规则,在需要代理的设备上手动改:

  • 网关:改成软路由的 IP(比如 192.168.1.2
  • DNS:同样改成 192.168.1.2
旁路由的位置设备网关指向旁路由旁路由 Mihomo按规则处理主路由负责拨号上网外网不改设置的设备走原路,完全不受影响
最大的好处:出问题时其他设备照常上网

这种方式的优点是容错性极好——Mihomo 挂了只影响手动改过设置的设备,家里其他人无感。

五、方式 B:TProxy 透明代理

设备零配置,但需要在网关上配防火墙规则。

开启内核转发

sudo tee /etc/sysctl.d/99-mihomo.conf > /dev/null <<'EOF'
net.ipv4.ip_forward = 1
net.ipv4.conf.all.route_localnet = 1
EOF
sudo sysctl --system

iptables 规则

#!/bin/bash
# /etc/mihomo/tproxy.sh
TPROXY_PORT=7895
ROUTE_TABLE=100
FWMARK=1

# 策略路由:打了标记的包走本地
ip rule add fwmark $FWMARK table $ROUTE_TABLE 2>/dev/null
ip route add local default dev lo table $ROUTE_TABLE 2>/dev/null

# 自定义链
iptables -t mangle -N MIHOMO 2>/dev/null
iptables -t mangle -F MIHOMO

# 内网与保留地址直接放行
for net in 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
           172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4; do
  iptables -t mangle -A MIHOMO -d $net -j RETURN
done

# 其余 TCP/UDP 打标记并转给 TProxy 端口
iptables -t mangle -A MIHOMO -p tcp -j TPROXY --on-port $TPROXY_PORT --tproxy-mark $FWMARK
iptables -t mangle -A MIHOMO -p udp -j TPROXY --on-port $TPROXY_PORT --tproxy-mark $FWMARK

# 应用到转发流量(来自其他设备)
iptables -t mangle -A PREROUTING -j MIHOMO

# DNS 劫持:把设备发出的 53 端口查询转给 Mihomo
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 1053
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 1053

清理脚本:

#!/bin/bash
# /etc/mihomo/tproxy-clear.sh
iptables -t mangle -D PREROUTING -j MIHOMO 2>/dev/null
iptables -t mangle -F MIHOMO 2>/dev/null
iptables -t mangle -X MIHOMO 2>/dev/null
iptables -t nat -F PREROUTING 2>/dev/null
ip rule del fwmark 1 table 100 2>/dev/null
ip route del local default dev lo table 100 2>/dev/null

把规则挂到 systemd 上,随服务启停:

[Service]
ExecStartPost=/etc/mihomo/tproxy.sh
ExecStopPost=/etc/mihomo/tproxy-clear.sh

让设备用上它

主路由的 DHCP 设置里,把「默认网关」和「DNS 服务器」都改成软路由的 IP。设备重新连一次 Wi-Fi 即可生效。

六、容错设计:别让家人骂你

这是家庭部署最重要的一节。

必做的容错措施systemd 加 Restart=always,进程挂了自动拉起ExecStartPre 用 -t 检查配置,坏配置不启动订阅更新脚本先下载到临时文件、校验通过再替换保留一台不经过旁路由的设备,出问题时能上网查资料主路由 DHCP 里配两个 DNS:旁路由 + 公共 DNS 作为备份重要设备(老人手机、工作电脑)用 SRC-IP-CIDR 规则设为 DIRECT

安全的订阅更新脚本

#!/bin/bash
# /usr/local/bin/update-mihomo.sh
set -euo pipefail
CONF=/etc/mihomo/config.yaml
TMP=$(mktemp)
trap 'rm -f "$TMP"' EXIT

curl -fsSL --max-time 30 -A "clash.meta" -o "$TMP" "你的订阅链接"

# 基本校验
grep -q "^proxies:\|^proxy-providers:" "$TMP" || { echo "订阅内容异常"; exit 1; }

# 让 mihomo 自己验一遍
cp "$CONF" "${CONF}.bak"
cp "$TMP" "$CONF"
if mihomo -t -d /etc/mihomo; then
  systemctl restart mihomo
  echo "更新成功"
else
  cp "${CONF}.bak" "$CONF"
  echo "配置校验失败,已回滚"
  exit 1
fi

加到 cron:

0 4 * * * /usr/local/bin/update-mihomo.sh >> /var/log/mihomo-update.log 2>&1

用 proxy-provider 的话其实不需要这个脚本——内核会自己定期拉取节点,主配置不用动。这是推荐 provider 而不是整份订阅的重要原因

七、Web 面板

external-ui: /etc/mihomo/ui
external-ui-name: metacubexd

把面板文件放进 /etc/mihomo/ui,然后浏览器访问 http://软路由IP:9090/ui,输入 secret 就能在网页上切换节点、看连接、查日志。

家里其他人也能用这个页面自己切节点,不用找你。

八、性能与资源

不同硬件的大致承载能力(参考量级)树莓派 4B百兆级别,家庭够用J4125 软路由千兆基本跑满N100 软路由千兆无压力老旧单核设备规则集大时会明显吃力实际取决于规则集规模、连接数与协议类型,仅作选型参考

性能吃紧时的优化顺序:

  1. 精简规则集(删掉用不到的流媒体、广告列表)
  2. 规则集换成 mrs 二进制格式
  3. log-level 设为 warning,别用 debug
  4. 减少 health-check 的频率
  5. TProxy 比 TUN 省资源,优先用 TProxy

九、排查

# 服务状态
systemctl status mihomo
journalctl -u mihomo -n 100 --no-pager

# 端口监听
ss -tulnp | grep mihomo

# API 是否响应
curl -H "Authorization: Bearer 你的secret" http://127.0.0.1:9090/version

# 从另一台设备测试代理端口
curl -x http://192.168.1.2:7890 -I https://www.google.com

# 看 iptables 规则命中计数
iptables -t mangle -L MIHOMO -v -n

小结

  • 先用「旁路由 + 手动指网关」跑通,确认稳定了再上 TProxy
  • secret 必须设0.0.0.0:9090 是对整个局域网开放的
  • 用 proxy-provider 而不是整份订阅,内核自己更新,主配置永远不动
  • ExecStartPre 加 -t 检查配置,坏配置不会顶掉正在运行的服务
  • 给重要设备配 SRC-IP-CIDR 直连规则,别让家人受影响
  • 改 TProxy 前先设一个自动清理的定时任务,给自己留后路

相关:外部控制 API 与面板多订阅管理


相关文档

让 Docker 和 WSL2 用上宿主机的 Clash 代理
部署实战 让 Docker 和 WSL2 用上宿主机的 Clash 代理

容器里的 127.0.0.1 不是宿主机。这篇给出 Docker 构建期、运行期、daemon 拉取镜像三种场景的配置方法,以及 WSL2 网络模式差异下的两套方案。

2026-06-141716 字约 4 分钟