Document the 'Force relay connection' switch that silently disables ICE gathering on iOS NetBird (and similar on macOS), which was the real cause of all peers showing Connection type: Relayed despite STUN being correctly configured. Also document bufferbloat diagnosis via macOS networkQuality, which was a red herring during the P2P investigation (large RTT spikes were the WiFi/ISP, not NetBird).
148 lines
4.4 KiB
Markdown
148 lines
4.4 KiB
Markdown
# NetBird 客戶端 Troubleshooting
|
||
|
||
記錄一些不容易猜到的客戶端問題與解法。
|
||
|
||
## P2P 永遠打不通:先檢查 `Force Relay Connection`
|
||
|
||
### 症狀
|
||
|
||
`netbird status --detail` 顯示:
|
||
|
||
```
|
||
Connection type: Relayed
|
||
ICE candidate (Local/Remote): -/-
|
||
ICE candidate endpoints (Local/Remote): -/-
|
||
Relay server address: rels://...
|
||
```
|
||
|
||
兩端 ICE candidate 都是 `-/-`、長時間不變,連線可用但永遠走 Relay。
|
||
|
||
### 容易猜錯的方向
|
||
|
||
- 怪 STUN(DNAT、port 衝突、防火牆)
|
||
- 怪「Block Inbound Connections」
|
||
- 怪 iOS 平台限制(NetworkExtension 不支援 P2P UDP)
|
||
- 怪同 WiFi 下的 hairpin NAT
|
||
- 怪 Mac 防火牆
|
||
|
||
以上都檢查無誤後仍然 `Relayed` → **檢查客戶端的 `Force Relay Connection`**。
|
||
|
||
### 真正原因
|
||
|
||
NetBird 客戶端有一個 **「Force relay connection」** 開關。打開後 NetBird 完全跳過 ICE gathering,直接走 Relay。
|
||
|
||
#### 各平台位置
|
||
|
||
| 平台 | 路徑 |
|
||
|------|------|
|
||
| iOS | App → Settings → Advanced → 最下方「Force relay connection」 |
|
||
| macOS | 選單列 NetBird → Settings → Advanced Settings(或 menu 內找 Force Relay) |
|
||
| CLI / daemon | `netbird up` 沒有對應 flag;以 daemon 設定檔方式存在 |
|
||
|
||
#### 修復
|
||
|
||
1. 把開關關掉
|
||
2. App 內 Disconnect → Connect(或 `netbird down && netbird up`)
|
||
3. 等 5-10 秒讓 ICE gathering 完成
|
||
|
||
### 驗證 P2P 成功
|
||
|
||
`netbird status --detail` 應顯示:
|
||
|
||
```
|
||
Connection type: P2P
|
||
ICE candidate (Local/Remote): host/prflx ← 或 srflx/srflx 等組合
|
||
ICE candidate endpoints (Local/Remote): 192.168.x.x:51820/192.168.x.x:51820
|
||
Latency: ~25 ms ← 同 LAN 應該 <50ms
|
||
```
|
||
|
||
`Connection type` 從 `Relayed` 變成 `P2P` 就成功。
|
||
|
||
## 高 RTT 大幅波動:先排除 bufferbloat
|
||
|
||
### 症狀
|
||
|
||
`ping <peer-ip>` 結果像這樣:
|
||
|
||
```
|
||
round-trip min/avg/max/stddev = 220.423/2230.078/4238.380/1420.726 ms
|
||
```
|
||
|
||
平均 2 秒、尖峰 4 秒。看起來像 NetBird 出問題。
|
||
|
||
### 診斷
|
||
|
||
在 macOS 跑:
|
||
|
||
```bash
|
||
networkQuality -v
|
||
```
|
||
|
||
如果輸出:
|
||
|
||
```
|
||
Responsiveness: Low (703 milliseconds | 85 RPM)
|
||
```
|
||
|
||
→ **這是你連的 WiFi/ISP 有 bufferbloat**,跟 NetBird 無關。
|
||
RPM (Round-trips Per Minute) 應該 >500,<100 算很糟。Bufferbloat 在路由器/modem 有大量佇列堆積時會讓任何流量延遲爆衝。
|
||
|
||
### 修復方向
|
||
|
||
- 換更好的 WiFi AP(支援 SQM / fq_codel / cake)
|
||
- ISP modem 啟用 SQM(OpenWrt 上裝 `luci-app-sqm`)
|
||
- 短期:避免在背景下載大檔時測 NetBird 延遲
|
||
|
||
## 客戶端配置驗證 checklist
|
||
|
||
當你覺得「明明設定都對,但 NetBird 行為怪怪的」,依序檢查:
|
||
|
||
```bash
|
||
# 1. 客戶端有連到正確的 management server?
|
||
netbird status | grep Management
|
||
|
||
# 2. STUN 是 Available?(這個案例的 STUN port 是 3479)
|
||
netbird status --detail | grep -E 'stun:|Relays:'
|
||
|
||
# 3. 看到對方 peer?
|
||
netbird status --detail | grep -A 1 <peer-fqdn>
|
||
|
||
# 4. Connection type 是 P2P 還是 Relayed?
|
||
netbird status --detail | grep 'Connection type'
|
||
|
||
# 5. ICE candidate 是什麼類型?(host/srflx/prflx/relay)
|
||
netbird status --detail | grep 'ICE candidate'
|
||
|
||
# 6. WireGuard 真的有 handshake?
|
||
netbird status --detail | grep 'Last WireGuard handshake'
|
||
|
||
# 7. 真的能 ping?
|
||
ping -c 5 <peer-netbird-ip>
|
||
```
|
||
|
||
如果 7 通但 4 是 `Relayed` 且 5 是 `-/-` → 99% 是 Force Relay 開著(見上)。
|
||
|
||
## 各平台 NetBird Settings 裡會踩雷的開關
|
||
|
||
| 開關 | 開啟後果 |
|
||
|------|---------|
|
||
| **Force relay connection** | 永遠走 Relay,P2P 失效 |
|
||
| Block Inbound Connections | 對方主動連入會被擋,可能逼成單向 Relay |
|
||
| Disable Client Routes | 此 peer 不路由到其他 peer |
|
||
| Disable Server Routes | 此 peer 無法當別人的 router |
|
||
| Disable LAN Access | 當 exit node 時不能存取 exit node 的本地網路 |
|
||
| Lazy Connections | 連線延遲建立直到有流量才協商 |
|
||
| Enable Rosenpass | 量子抗性握手(實驗性,可能與舊 peer 不相容) |
|
||
|
||
預設值通常是「全部關閉」 — 如果你或別人不小心開了某個,行為就會變得難解釋。
|
||
|
||
## 為什麼客戶端版的 docs 不直接寫死「永遠關 Force Relay」
|
||
|
||
某些情境下強制 Relay 是合理的:
|
||
|
||
- P2P 隱私顧慮(不想暴露真實 IP 給對方 peer)
|
||
- 對方所在網路有 IDS 會偵測 P2P UDP 流量
|
||
- Debug 時希望流量都過 Relay 方便抓 log
|
||
|
||
所以 NetBird 把它做成可選。**自宅 mesh / 個人裝置之間互通,沒理由開**。
|