# Resolving Netbird and Mihomo (Tun Mode) Coexistence Issues on Linux


Running **NetBird** (mesh networking) and **Mihomo** (Tun Mode) on Linux means both tools try to control routing. NetBird may connect but stay in `Relayed` mode, unable to establish point-to-point (P2P) direct connections. In some cases, even the relay connection fails.

## Problem Background

- **OS**: Arch Linux
- **NetBird**: Using default Kernel Mode
- **Mihomo**: TUN mode enabled, hijacking system traffic
- **Symptoms**: `netbird status -d` shows the connection type as `Relayed`, ICE negotiation fails, resulting in high latency and failed NAT hole punching.

## Gathering Key Information

Before implementing the solution, you must confirm the actual WireGuard port NetBird is listening on.

To find the NetBird listening port:

```bash
sudo cat /var/lib/netbird/default.json | grep WgPort

```

The default is usually `51820`. If it shows `0` or another value, it is recommended to manually edit this file, fix it to `51820`, and restart the service.

Additionally, if you have `wireguard-tools` installed, you can verify the actual port of the kernel interface:

```bash
sudo wg show wt0 listen-port

```

## The Final Solution

### Core Routing Logic

1. **Mark**: Identify UDP packets originating from source port `51820` in the `OUTPUT` chain and tag them with mark `0x100`.
2. **Route**: Use policy routing to force packets marked with `0x100` to use the `main` routing table, effectively bypassing Mihomo.
3. **Masquerade**: (The most critical step) Perform source address masquerading in the `POSTROUTING` chain for marked packets. This fixes the source IP (which might have been altered by Mihomo) and ensures the packet appears to originate from the physical network interface.

### Implementation Steps

Use a Systemd override to persist these rules. Execute the following command:

```bash
sudo mkdir -p /etc/systemd/system/netbird.service.d/
echo "[Service]
# --- 1. Environment ---
# Since we are using kernel mode, no specific environment variables (like NB_WG_KERNEL_DISABLED) are needed here.

# --- 2. Core Fix: Mark NetBird Traffic (Mangle Output) ---
# Purpose: Identify all encrypted packets sent from port 51820 and apply the 0x100 mark.
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. Core Fix: Policy Routing ---
# Purpose: Force packets with the 0x100 mark to use the physical interface (main table), bypassing 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. Core Fix: NAT Masquerade ---
# Purpose: Fix the source IP modified by Mihomo (e.g., 198.18...), reverting it to the physical interface's real IP to ensure P2P return packets are received.
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 on Stop ---
# Purpose: Maintain system cleanliness and prevent rule accumulation.
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

```

Additionally, you need to configure **Mihomo**. Add the following to your `tun` section:

```yaml
tun:
  exclude-interface:
    - wt0
  endpoint-independent-nat: true
  inet4-route-exclude-address:
    - 100.64.0.0/10
  inet6-route-exclude-address:
    - fd00::/8
```

Restart Mihomo to apply changes.

## Verification

Wait a moment and check the status:

```bash
sudo netbird status -d

```

You should now see:

- **Interface type**: `Kernel`
- **Connection type**: `P2P` (no longer Relayed)


---

> Author: Nite  
> URL: https://www.nite07.com/en/posts/netbird-mihomo/  

