Photo by Unsplash
911 字
5 分钟
Linux本机代理防死循环设置:Mihomo透明代理实践
Linux 本机代理防死循环设置:Mihomo 透明代理实践
在 Linux 服务器上配置全局代理时,仅靠环境变量往往不够彻底。更好的方案是用 Mihomo (原 Clash Meta) 搭建基于 Redir 的透明代理。但这里有个坑:代理死循环。
什么是代理死循环?
当你用 iptables 把本机 TCP 流量劫持到 Mihomo 的代理端口(比如 7892)时,Mihomo 自己发出的连接请求也会被再次劫持。流量在本机无限打转,网络直接瘫痪。
我第一次尝试时就踩了这个坑——规则一跑,SSH 瞬间断开,只能强制重启服务器。
解决方案:按用户名绕过
最稳妥的办法是给 Mihomo 创建一个专用系统用户,然后在防火墙规则里放行该用户的所有流量。
1. 创建专用用户
sudo useradd -r -M -s /usr/sbin/nologin mihomo2. 完整的 Systemd 配置
把防火墙规则直接集成到服务文件里,启动时自动劫持网络,停止时自动清理:
[Unit]Description=mihomo Daemon, Another Clash Kernel.After=network.target
[Service]Type=simpleUser=mihomoGroup=mihomo
# 资源限制LimitNPROC=500LimitNOFILE=1000000
# 网络权限CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICEAmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
# 启动前:设置 iptables(+号表示以root权限执行)ExecStartPre=+/bin/bash -c '\ PROXY_PORT=7892; \ PROXY_USER=mihomo; \ SSH_PORT=22; \ \ # IPv4 规则 \ iptables -t nat -D OUTPUT -j MIHOMO 2>/dev/null || true; \ iptables -t nat -F MIHOMO 2>/dev/null || true; \ iptables -t nat -X MIHOMO 2>/dev/null || true; \ iptables -t nat -N MIHOMO; \ \ # 1. mihomo用户流量直接放行(防死循环)\ iptables -t nat -A MIHOMO -m owner --uid-owner $PROXY_USER -j RETURN; \ # 2. SSH端口回包放行(防断连)\ iptables -t nat -A MIHOMO -p tcp --sport $SSH_PORT -j RETURN; \ # 3. 排除内网地址 \ 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 172.16.0.0/12 -j RETURN; \ iptables -t nat -A MIHOMO -d 192.168.0.0/16 -j RETURN; \ # 4. 重定向其余流量 \ iptables -t nat -A MIHOMO -p tcp -j REDIRECT --to-ports $PROXY_PORT; \ # 5. 挂载到OUTPUT链 \ iptables -t nat -A OUTPUT -j MIHOMO; \ \ # IPv6 规则(同上)\ ip6tables -t nat -D OUTPUT -j MIHOMO6 2>/dev/null || true; \ ip6tables -t nat -F MIHOMO6 2>/dev/null || true; \ ip6tables -t nat -X MIHOMO6 2>/dev/null || true; \ ip6tables -t nat -N MIHOMO6; \ ip6tables -t nat -A MIHOMO6 -m owner --uid-owner $PROXY_USER -j RETURN; \ ip6tables -t nat -A MIHOMO6 -p tcp --sport $SSH_PORT -j RETURN; \ ip6tables -t nat -A MIHOMO6 -d ::1/128 -j RETURN; \ ip6tables -t nat -A MIHOMO6 -d fe80::/10 -j RETURN; \ ip6tables -t nat -A MIHOMO6 -p tcp -j REDIRECT --to-ports $PROXY_PORT; \ ip6tables -t nat -A OUTPUT -j MIHOMO6; \ '
ExecStartPre=/usr/bin/sleep 1sExecStart=/home/mihomo/mihomo -d /home/mihomo
# 停止后:清理 iptablesExecStopPost=+/bin/bash -c '\ iptables -t nat -D OUTPUT -j MIHOMO 2>/dev/null || true; \ iptables -t nat -F MIHOMO 2>/dev/null || true; \ iptables -t nat -X MIHOMO 2>/dev/null || true; \ ip6tables -t nat -D OUTPUT -j MIHOMO6 2>/dev/null || true; \ ip6tables -t nat -F MIHOMO6 2>/dev/null || true; \ ip6tables -t nat -X MIHOMO6 2>/dev/null || true; \ '
Restart=always
[Install]WantedBy=multi-user.target关键点
+前缀让命令以 root 身份执行,即使 Service 里指定了User=mihomo|| true确保清理失败时服务也能正常启动- SSH_PORT 默认是 22,如果你改了端口记得同步修改
3. Mihomo 配置
确保 config.yaml 开启了 redir-port:
redir-port: 7892ipv6: true
dns: enable: true listen: 0.0.0.0:1053 enhanced-mode: fake-ip nameserver: - 8.8.8.8 - 1.1.1.14. 应用配置
sudo systemctl daemon-reloadsudo systemctl enable mihomosudo systemctl start mihomo安全测试方法
第一次配置时建议用”后悔药”机制,防止配置错误导致失联:
# 5分钟后自动清空规则sudo ./enable_proxy.sh && nohup bash -c "sleep 300; iptables -t nat -F; ip6tables -t nat -F;" &这样即使断连了,5分钟后规则会自动清除,网络恢复。
验证是否生效
# 查看 iptables 规则sudo iptables -t nat -nvL OUTPUT
# 测试是否走代理curl https://ip.sb参考链接
- Mihomo 文档:https://wiki.metacubex.one/
- iptables 手册:https://linux.die.net/man/8/iptables
Linux本机代理防死循环设置:Mihomo透明代理实践
https://im.awsl.app/posts/networking/036-mihomo-loopback/