NetBird's default STUN port 3478/udp conflicts with Headscale on 192.168.42.126, which DNAT'd it first. Reconfigure NetBird to use 3479/udp end-to-end (server config + docker-compose + OpenWrt DNAT). Updates server config: - /opt/netbird/config.yaml: stunPorts: [3479] - /opt/netbird/docker-compose.yml: 3479:3479/udp OpenWrt DNAT rule added separately (42_10 repo commit 9cc6141).
104 lines
2.8 KiB
Markdown
104 lines
2.8 KiB
Markdown
# NetBird STUN Port 衝突:改用 3479/udp
|
||
|
||
## 情境
|
||
|
||
家用 infra 同時跑 **Headscale (`192.168.42.126`)** 跟 **NetBird (`192.168.42.127`)** 兩套 mesh VPN。兩者都想用標準 STUN port **`3478/udp`**,但單一 WAN port 只能 DNAT 到一個內網 host。
|
||
|
||
Headscale 比較早部署,已經占用了 WAN `:3478/udp → .126`。NetBird 因此必須改用其他 port 對外。
|
||
|
||
## 決策
|
||
|
||
採用「**NetBird 全面改用 3479/udp**」:
|
||
|
||
- 內部 netbird-server 的 STUN 監聽改為 `3479`
|
||
- Docker 容器對外 expose `3479:3479/udp`
|
||
- OpenWrt 新增 DNAT `WAN :3479/udp → 192.168.42.127:3479`
|
||
- 客戶端收到的 STUN URL 會是 `stun:netbird.timmy.us.kg:3479`
|
||
|
||
Headscale 那條 `3478/udp → .126` 完全不動。
|
||
|
||
## 實施步驟
|
||
|
||
### 1. 修改 `/opt/netbird/config.yaml`
|
||
|
||
```yaml
|
||
server:
|
||
# ...
|
||
stunPorts:
|
||
- 3479 # 原本是 3478
|
||
```
|
||
|
||
### 2. 修改 `/opt/netbird/docker-compose.yml`
|
||
|
||
```yaml
|
||
netbird-server:
|
||
# ...
|
||
ports:
|
||
- "3479:3479/udp" # 原本是 "3478:3478/udp"
|
||
```
|
||
|
||
### 3. 重新建立容器
|
||
|
||
```bash
|
||
cd /opt/netbird
|
||
docker compose up -d
|
||
```
|
||
|
||
`docker compose up -d` 會偵測到 port 變更、重建 `netbird-server` 容器。其他兩個(caddy、dashboard)不動。
|
||
|
||
### 4. OpenWrt 加 DNAT
|
||
|
||
在 `192.168.42.10` 上加 UCI redirect(詳見 `42_10` repo):
|
||
|
||
```
|
||
name: NetBird-STUN
|
||
src: wan → dest: lan
|
||
src_dport: 3479 → dest_ip: 192.168.42.127, dest_port: 3479
|
||
proto: udp
|
||
target: DNAT
|
||
```
|
||
|
||
### 5. 驗證
|
||
|
||
外部 UDP 連通性:
|
||
|
||
```bash
|
||
nc -zvu -w 3 125.229.110.50 3479
|
||
# Connection to 125.229.110.50 port 3479 [udp/...] succeeded!
|
||
```
|
||
|
||
客戶端 STUN 正確指向新 port:
|
||
|
||
```bash
|
||
netbird status --detail | grep stun:
|
||
# [stun:netbird.timmy.us.kg:3479] is Available
|
||
```
|
||
|
||
## 既有客戶端要重連
|
||
|
||
已連線的 NetBird 客戶端會在啟動時向 management server 拿一次 STUN URL,**變更後舊客戶端仍握著舊 URL**。每台已註冊裝置需:
|
||
|
||
```
|
||
Disconnect → Connect
|
||
```
|
||
|
||
或重啟 App / daemon 讓它重新抓設定。沒重連前仍會走 Relay,不會斷線但無法 P2P。
|
||
|
||
## 疑難排解
|
||
|
||
| 症狀 | 可能原因 |
|
||
|------|---------|
|
||
| `[stun:...:3479] is Checking...` 長時間沒變 Available | OpenWrt DNAT 未生效或 NetBird 容器沒在新 port 監聽 |
|
||
| Available 但 `Connection type: Relayed` 不變 | 客戶端沒重連 / 兩邊都在嚴格 NAT 後 / iOS 省電模式阻擋 ICE |
|
||
| iPhone App 重連後仍是 Relay | 檢查 iOS 的 Low Data Mode 或 WiFi/行動網路切換;P2P 對稱 NAT 時無解,保持 Relay 正常運作 |
|
||
|
||
## 相關檔案
|
||
|
||
- `/opt/netbird/config.yaml`(伺服器)
|
||
- `/opt/netbird/docker-compose.yml`(伺服器)
|
||
- `42_10` repo README(OpenWrt port 表,3479 在這裡記錄)
|
||
|
||
## 為什麼不關掉 Headscale?
|
||
|
||
使用者仍在使用 Headscale,沒有遷移計畫。兩套 overlay 網路並存是有意的安排。
|