Linux 下解决 Netbird 和 Mihomo(Tun Mode) 共存问题
目录
在 Linux 上同时跑 NetBird(组网)和 Mihomo(Tun Mode)时,两个工具都会接管路由。结果是 NetBird 能连接,但一直停在中继(Relayed)模式,无法建立点对点(P2P)直连。有时甚至连中继也连不上。
问题背景
- OS: Arch Linux
- NetBird: 使用默认的内核模式 (Kernel Mode)
- Mihomo: 开启 TUN 模式,接管系统流量
- 现象:
netbird status -d显示连接类型为Relayed,ICE 协商失败,延迟高且无法打洞。
关键信息的获取
在实施方案前,必须确认 NetBird 实际监听的 WireGuard 端口。
获取 NetBird 监听端口的方法:
sudo cat /var/lib/netbird/default.json | grep WgPort通常默认是 51820。如果显示为 0 或其他,建议手动修改该文件固定为 51820 并重启服务。
如果你安装了 wireguard-tools,也可以通过以下命令验证内核接口的实际端口:
sudo wg show wt0 listen-port最终解决方案
核心路由思路
- Mark: 在 Output 链识别源端口为
51820的 UDP 包,打上标记0x100。 - Route: 通过策略路由,强制带有
0x100标记的包走主路由表 (main),绕过 Mihomo。 - Masquerade: 在 Postrouting 链对标记包做源地址伪装,修复被 Mihomo 改过的源 IP,让包看起来是从物理网卡发出的。
操作步骤
使用 Systemd 配置来持久化这些规则,执行下方命令。
sudo mkdir -p /etc/systemd/system/netbird.service.d/
echo "[Service]
# --- 1. 基础环境 ---
# 既然用了内核模式,这里不需要任何 Environment 变量 (如 NB_WG_KERNEL_DISABLED)
# --- 2. 核心修复:给 NetBird 流量打标记 (Mangle Output) ---
# 作用:识别出从 51820 端口发出的所有加密包,打上 0x100 标记
ExecStartPost=/usr/bin/iptables -t mangle -A OUTPUT -p udp --sport 51820 -j MARK --set-mark 0x100
ExecStartPost=/usr/bin/ip6tables -t mangle -A OUTPUT -p udp --sport 51820 -j MARK --set-mark 0x100
# --- 3. 核心修复:策略路由 (Policy Routing) ---
# 作用:看到 0x100 标记的包,强制走物理网卡 (main 表),直接绕过 Mihomo
ExecStartPost=/usr/bin/ip rule add fwmark 0x100 lookup main prio 50
ExecStartPost=/usr/bin/ip -6 rule add fwmark 0x100 lookup main prio 50
# --- 4. 核心修复:源地址伪装 (NAT Masquerade) ---
# 作用:修复被 Mihomo 改写的源 IP (198.18...),将其改回物理网卡真实 IP,确保 P2P 回包能收到
ExecStartPost=/usr/bin/iptables -t nat -A POSTROUTING -m mark --mark 0x100 -j MASQUERADE
ExecStartPost=/usr/bin/ip6tables -t nat -A POSTROUTING -m mark --mark 0x100 -j MASQUERADE
# --- 5. 停止后清理 (Cleanup) ---
# 作用:保持系统整洁,防止规则堆积
ExecStopPost=/usr/bin/iptables -t mangle -D OUTPUT -p udp --sport 51820 -j MARK --set-mark 0x100
ExecStopPost=/usr/bin/ip6tables -t mangle -D OUTPUT -p udp --sport 51820 -j MARK --set-mark 0x100
ExecStopPost=/usr/bin/ip rule del fwmark 0x100 lookup main prio 50
ExecStopPost=/usr/bin/ip -6 rule del fwmark 0x100 lookup main prio 50
ExecStopPost=/usr/bin/iptables -t nat -D POSTROUTING -m mark --mark 0x100 -j MASQUERADE
ExecStopPost=/usr/bin/ip6tables -t nat -D POSTROUTING -m mark --mark 0x100 -j MASQUERADE
" | sudo tee /etc/systemd/system/netbird.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart netbird还需要配置 Mihomo,在 tun 部分增加如下配置
tun:
exclude-interface:
- wt0
endpoint-independent-nat: true
inet4-route-exclude-address:
- 100.64.0.0/10
inet6-route-exclude-address:
- fd00::/8重启 mihomo
验证结果
稍等片刻,运行状态检查:
sudo netbird status -d此时你应该能看到:
- Interface type:
Kernel - Connection type:
P2P(不再是 Relayed)