树莓派安装mihomo并配置透明代理

配图:甘肃博物馆铜奔马(马踏飞燕)

之前我一直在小米AX3000T路由器上跑OpenClash,用着倒也稳定。但时间一长OpenClash太吃内存,某天一看占用直接飙到233MB,路由器直接OOM,SSH都连不上,只能断电重启。路由器那点内存实在扛不住,我把目光转向了吃灰已久的树莓派,闲置也是闲置,不如让它来干这个活。

官方一键脚本安装docker:

curl -fsSL https://get.docker.com | sh

装完把当前用户加到docker组,免得每次都要sudo:

sudo usermod -aG docker $USER

然后退出重新登录。因为国内访问Docker Hub不太稳定,我配了镜像加速:

sudo tee /etc/docker/daemon.json << 'EOF'
{
  "registry-mirrors": ["https://docker.1ms.run"]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

Docker准备好了,接下来部署mihomo。创建目录放配置和数据:

mkdir -p ~/mihomo && cd ~/mihomo

先把配置文件准备好放到~/mihomo/config.yaml,然后用Docker跑起来:

docker run -d   --name mihomo   --restart=always   --network=host   --cap-add=NET_ADMIN   -v ./config.yaml:/root/.config/mihomo/config.yaml   -v ./cache.db:/root/.config/mihomo/cache.db   metacubex/mihomo:latest

–network=host用宿主机网络直接用端口,–cap-add=NET_ADMIN给iptables操作权限,–restart=always开机自启挂了自动重启。

如果你之前用的是OpenClash的配置,不能直接拿来用!得删掉OpenClash特有的字段,比如experimental、dns.enhanced-mode: redir-host这类扩展字段。关键配置项大概长这样:

mixed-port: 7893
port: 7890
socks-port: 7891
redir-port: 7892
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
external-controller: 0.0.0.0:9090

dns:
  enable: true
  listen: 0.0.0.0:53
  enhanced-mode: fake-ip
  nameserver:
    - 223.5.5.5
    - 119.29.29.29

也可以用订阅方式:

proxy-providers:
  my-provider:
    type: http
    url: "你的订阅链接"
    interval: 3600
    path: ./providers/my-provider.yaml
    health-check:
      enable: true
      interval: 600
      url: http://www.gstatic.com/generate_204

端口分配:7890是HTTP代理,7891是SOCKS5,7892是REDIRECT透明代理给iptables用,7893是Mixed混合代理,53是DNS,9090是API和Web面板。配置改好后docker restart mihomo重启一下。

接下来是最关键的iptables透明代理。思路是用iptables把局域网流量劫持到mihomo的7892端口。创建脚本~/transparent-proxy.sh:

#!/bin/bash

MIHOMO_REDIR_PORT=7892
LOCAL_SUBNET="192.168.0.0/16"

iptables -t nat -N MIHOMO

iptables -t nat -A MIHOMO -d 0.0.0.0/8 -j RETURN
iptables -t nat -A MIHOMO -d 10.0.0.0/8 -j RETURN
iptables -t nat -A MIHOMO -d 127.0.0.0/8 -j RETURN
iptables -t nat -A MIHOMO -d 169.254.0.0/16 -j RETURN
iptables -t nat -A MIHOMO -d 172.16.0.0/12 -j RETURN
iptables -t nat -A MIHOMO -d 192.168.0.0/16 -j RETURN
iptables -t nat -A MIHOMO -d 224.0.0.0/4 -j RETURN
iptables -t nat -A MIHOMO -d 240.0.0.0/4 -j RETURN

iptables -t nat -A MIHOMO -m owner --uid-owner root -j RETURN

iptables -t nat -A MIHOMO -p tcp -j REDIRECT --to-ports $MIHOMO_REDIR_PORT

iptables -t nat -A PREROUTING -p tcp -s $LOCAL_SUBNET -j MIHOMO

echo "透明代理规则已设置"

取消透明代理的脚本:

#!/bin/bash
LOCAL_SUBNET="192.168.0.0/16"
iptables -t nat -D PREROUTING -p tcp -s $LOCAL_SUBNET -j MIHOMO
iptables -t nat -F MIHOMO
iptables -t nat -X MIHOMO
echo "透明代理规则已清除"

chmod +x ~/transparent-proxy.sh ~/transparent-proxy-stop.sh

为了开机自动设置iptables规则,创建systemd服务:

sudo tee /etc/systemd/system/mihomo-proxy.service << 'EOF'
[Unit]
Description=mihomo transparent proxy iptables rules
After=network.target docker.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/home/sry/transparent-proxy.sh
ExecStop=/home/sry/transparent-proxy-stop.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable mihomo-proxy.service
sudo systemctl start mihomo-proxy.service

为了让命令行工具也能走代理,在/etc/profile.d/proxy.sh里设置环境变量:

sudo tee /etc/profile.d/proxy.sh << 'EOF'
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export all_proxy=socks5://127.0.0.1:7891
export no_proxy=localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
EOF

source /etc/profile.d/proxy.sh

注意!/etc/profile.d/proxy.sh只对登录shell(bash -l)生效!systemd service、cron任务、非登录shell都不会自动source这个文件。如果你有systemd服务需要走代理,必须在service unit文件里显式添加Environment=行,不然进程会直连,国内网络直接被墙!这个坑我踩过,排查了好久才发现是环境变量的问题。

测试一下代理是否工作:

curl -x http://127.0.0.1:7890 https://www.google.com -I
curl --socks5 127.0.0.1:7891 https://www.google.com -I

能正常返回200就说明配置成功。Web面板访问http://树莓派IP:9090/ui,推荐用Yacd或Metacubexd。

最后说我踩的最大的坑。一开始我想用TProxy模式而不是REDIRECT,因为TProxy能代理UDP流量理论上更好。结果折腾了大半天TProxy死活不工作。排查发现树莓派的内核在收到带有fwmark标记的包后会直接丢弃而不是正确路由,标记过的包直接被丢。网上查了一圈不少人遇到同样的问题,基本确认是树莓派内核的锅。所以如果你也用树莓派,老老实实用REDIRECT模式吧,虽然只能代理TCP但胜在稳定可靠。

整个流程下来mihomo跑在Docker里非常稳定,内存占用比路由器上跑OpenClash小得多,局域网内所有设备自动走透明代理无需单独配置,用起来非常爽。

参考资料:

mihomo 官方文档

Docker 官方安装文档

metacubex/mihomo Docker 镜像

iptables REDIRECT 透明代理原理

 

发布于2026/08/22。

船长

发表评论