911 字
5 分钟
Linux本机代理防死循环设置:Mihomo透明代理实践

Linux 本机代理防死循环设置:Mihomo 透明代理实践#

在 Linux 服务器上配置全局代理时,仅靠环境变量往往不够彻底。更好的方案是用 Mihomo (原 Clash Meta) 搭建基于 Redir 的透明代理。但这里有个坑:代理死循环

什么是代理死循环?#

当你用 iptables 把本机 TCP 流量劫持到 Mihomo 的代理端口(比如 7892)时,Mihomo 自己发出的连接请求也会被再次劫持。流量在本机无限打转,网络直接瘫痪。

我第一次尝试时就踩了这个坑——规则一跑,SSH 瞬间断开,只能强制重启服务器。

解决方案:按用户名绕过#

最稳妥的办法是给 Mihomo 创建一个专用系统用户,然后在防火墙规则里放行该用户的所有流量。

1. 创建专用用户#

Terminal window
sudo useradd -r -M -s /usr/sbin/nologin mihomo

2. 完整的 Systemd 配置#

把防火墙规则直接集成到服务文件里,启动时自动劫持网络,停止时自动清理:

/etc/systemd/system/mihomo.service
[Unit]
Description=mihomo Daemon, Another Clash Kernel.
After=network.target
[Service]
Type=simple
User=mihomo
Group=mihomo
# 资源限制
LimitNPROC=500
LimitNOFILE=1000000
# 网络权限
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
AmbientCapabilities=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 1s
ExecStart=/home/mihomo/mihomo -d /home/mihomo
# 停止后:清理 iptables
ExecStopPost=+/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: 7892
ipv6: true
dns:
enable: true
listen: 0.0.0.0:1053
enhanced-mode: fake-ip
nameserver:
- 8.8.8.8
- 1.1.1.1

4. 应用配置#

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable mihomo
sudo systemctl start mihomo

安全测试方法#

第一次配置时建议用”后悔药”机制,防止配置错误导致失联:

Terminal window
# 5分钟后自动清空规则
sudo ./enable_proxy.sh && nohup bash -c "sleep 300; iptables -t nat -F; ip6tables -t nat -F;" &

这样即使断连了,5分钟后规则会自动清除,网络恢复。

验证是否生效#

Terminal window
# 查看 iptables 规则
sudo iptables -t nat -nvL OUTPUT
# 测试是否走代理
curl https://ip.sb

参考链接#

Linux本机代理防死循环设置:Mihomo透明代理实践
https://im.awsl.app/posts/networking/036-mihomo-loopback/
作者
uu
发布于
2026-01-08
许可协议
CC0 1.0