Files
42_10/README.md
Timmy 7023430f00 docs: document Tailscale (Headscale) client on edge router
新增 Tailscale 一節:安裝/連線(強制 --accept-routes=false)、邊界路由器
禁用 accept-routes 的警告與根因、split-DNS 覆寫、WireGuard 救援步驟,以及
從 tailnet 管理 .10 需納入 fw4 zone 的註記。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 08:43:09 +08:00

497 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenWrt 管理指令
**目標設備**`192.168.42.10`OpenWrt 24.10.4
**WAN IP**`125.229.110.50`PPPoE / HiNet
---
## 整體架構圖
### 網路拓撲
```
Internet (HiNet)
PPPoE 125.229.110.50
┌────────────────────▼────────────────────┐
│ OpenWrt 24.10.4 │
│ 192.168.42.10 │
│ │
│ ┌─ 服務 ──────────────────────────┐ │
│ │ dnsmasq odhcpd sqm banip │ │
│ │ miniupnpd dropbear uhttpd │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─ 防火牆 (nftables / fw4) ────────┐ │
│ │ taiwan_ips set每週一 04:00 更新)│ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─ WireGuard wg0 ──────────────────┐ │
│ │ 10.0.0.1/24 port 51820/UDP │ │
│ └─────────────────────────────────┘ │
└────────────────┬────────────────────────┘
│ br-lan 192.168.42.0/24
┌─────────┬───────────┼───────────┬─────────────┐
▼ ▼ ▼ ▼ ▼
.100 .101 .115 .117 .124 / .126
Jump Box RustDesk SQL Server SQL Server 反代 / Headscale
```
---
### 防火牆區域Firewall Zones
```
┌──────────┐ REJECT in ┌──────────┐ ACCEPT in
│ wan │ ──────────────▶ │ lan │ ◀────────────
│(pppoe_wan│ REJECT fwd │192.168.42│ ACCEPT fwd
│ wan6) │ │ .0/24 │
└──────────┘ └──────────┘
ACCEPT in
ACCEPT fwd
┌──────────┐
│ vpn │
│ (wg0) │
│10.0.0/24 │
└──────────┘
```
---
### 對外開放的 PortWAN → LAN
| WAN Port | 協定 | 目標 | 服務 | Taiwan IP 限制 |
|---|---|---|---|:---:|
| `22` | TCP | `192.168.42.100:22` | SSH Jump Box | ✅ |
| `80` | TCP | `192.168.42.124:80` | Nginx Proxy Manager | — |
| `443` | TCP | `192.168.42.124:443` | Nginx Proxy Manager | — |
| `3478` | UDP | `192.168.42.126:3478` | Headscale DERP STUN | — |
| `3479` | UDP | `192.168.42.127:3479` | NetBird STUN | — |
| `7835` | TCP | `192.168.42.100:7835` | Bore Tunnel | ✅ |
| `8080` | TCP | `192.168.42.126:8080` | Headscale HTTP API | — |
| `9090` | TCP | `192.168.42.126:9090` | Headscale Metrics | — |
| `900010000` | TCP | `192.168.42.100:900010000` | Bore Range | — |
| `2111521119` | TCP/UDP | `192.168.42.101:2111521119` | RustDesk HBBS/HBBR | — |
| `30022` | TCP | `192.168.42.115:22` | SSH → .115 | — |
| `50022` | TCP | `192.168.42.117:22` | SSH → .117 | — |
| `50443` | TCP | `192.168.42.126:50443` | Headscale gRPC | — |
| `51433` | TCP | `192.168.42.115:1433` | SQL Server (.115) | — |
| `31433` | TCP | `192.168.42.117:1433` | SQL Server (.117) | — |
| `51820` | UDP | router wg0 | WireGuard | — |
> **STUN port 說明**:標準 STUN port 為 `3478/udp`,已由 Headscale DERP`.126`佔用。NetBird`.127`)後上線,為避免衝突改用 `3479/udp``stunPorts: [3479]`,對應 `/opt/netbird/config.yaml`。Client 設定的 STUN URI 需指向 `stun:<wan_ip>:3479`。
---
### LAN 裝置
| IP | 主機名稱 / 用途 |
|---|---|
| `192.168.42.10` | OpenWrt 路由器 |
| `192.168.42.100` | Jump BoxSSH、Bore|
| `192.168.42.101` | RustDesk Server |
| `192.168.42.115` | SQL Server A |
| `192.168.42.117` | SQL Server B |
| `192.168.42.124` | Nginx Proxy Manager + Gitea:31337|
| `192.168.42.126` | Headscale |
| `192.168.42.127` | NetBirdManagement + Signal + STUN/TURN|
| `192.168.42.220` | TimmydeMBP |
---
### WireGuard VPN 拓撲
```
外部(任意網路)
│ UDP 51820
192.168.42.10 ←→ wg0: 10.0.0.1/24
├── 10.0.0.2 Workstation
└── 10.0.0.3 iPhone 15 Pro Max
VPN client 加入後可存取:
├── 192.168.42.0/24 (整個 LAN
└── 10.0.0.0/24 (其他 VPN peer
```
---
### Taiwan IP 過濾機制
```
外部請求
nftables 檢查 source IP 是否在 taiwan_ips set
├── 是 → 允許通過SSH Jump Box、Bore Tunnel
└── 否 → REJECT
```
- IP 清單來源:`https://www.ipdeny.com/ipblocks/data/countries/tw.zone`
- 自動更新:每週一 04:00`crontab`
- 手動更新:`sh /root/42_10/update_tw_ip.sh`
---
## 系統狀態確認
```sh
# 開機時間與負載
uptime
# 記憶體用量
free -m
# 磁碟空間
df -h
# 近期系統紀錄
logread -l 50
# 即時追蹤紀錄
logread -f
```
---
## 套件管理
```sh
# 更新套件列表
opkg update
# 安裝套件
opkg install <package_name>
# 移除套件
opkg remove <package_name>
# 列出已安裝套件
opkg list-installed
# 升級所有套件
opkg list-upgradable | cut -f 1 -d ' ' | xargs -r opkg upgrade
```
---
## 防火牆nftables / fw4
```sh
# 列出所有規則
nft list ruleset
# 列出特定 table
nft list table inet fw4
# 重新載入防火牆設定
fw4 restart
# 備份目前規則
nft list ruleset > /etc/nftables.backup
# 清除特定集合
nft flush set inet fw4 taiwan_ips
# 查看 Taiwan IP 集合(元素數量)
nft list set inet fw4 taiwan_ips | grep -c elements
```
---
## 網路診斷
```sh
# 介面清單與狀態
ip -br addr
# 路由表
ip route show
# 測試對外網路
ping -c 4 8.8.8.8
# DNS 查詢
nslookup google.com
# 查看監聽 Port
netstat -tuln
# 測試指定 Port 是否可到達
nc -zv -w 5 <target_ip> <port>
```
---
## 日誌
```sh
# 查看系統紀錄
logread
# 即時監控
logread -f
# 最近 50 筆
logread -l 50
# 過濾防火牆相關
logread | grep -i firewall
```
---
## 服務管理
```sh
# 啟動 / 停止 / 重啟
/etc/init.d/<service> start
/etc/init.d/<service> stop
/etc/init.d/<service> restart
# 查看狀態
/etc/init.d/<service> status
# 開機自動啟動 / 停用
/etc/init.d/<service> enable
/etc/init.d/<service> disable
```
---
## 設定備份與還原
```sh
# 備份整個系統設定
sysupgrade -b /tmp/backup-$(date +%Y%m%d).tar.gz
# 還原設定
sysupgrade -r /tmp/backup-YYYYMMDD.tar.gz
# 備份防火牆設定
cp /etc/config/firewall /etc/config/firewall.bak
# 編輯設定檔
vi /etc/config/firewall
```
---
## Taiwan IP 集合管理
```sh
# 重新抓取並更新 Taiwan IP 清單
sh /root/42_10/update_tw_ip.sh
# 確認目前集合內容
nft list set inet fw4 taiwan_ips
# 手動補充單一 IP如 VPS 未被涵蓋)
nft add element inet fw4 taiwan_ips { <ip_address> }
```
**資料來源**`https://www.ipdeny.com/ipblocks/data/countries/tw.zone`
建議搭配 cron 定期執行 `update_tw_ip.sh`,例如每月一次:
```sh
# crontab -e
0 3 1 * * sh /root/42_10/update_tw_ip.sh
```
---
## 防火牆規則驗證
```sh
# 本機執行SSH 進路由器並格式化輸出規則
sh /root/42_10/show_nft_rules.sh
# 驗證台灣 IP 通行、非台灣 IP 攔截
sh /root/42_10/test_connection.sh
```
`test_connection.sh` 會:
1. 查詢目前出口 IP 所在地(透過 `https://ip.lotimmy.com/json`
2.`125.229.110.50` 的指定 Port`51433`, `31433`)發起測試
3. 判斷結果是否符合預期(台灣 IP 應通過,非台灣 IP 應被攔截)
---
## 轉發規則調整
若需移除已失效的 Port 轉發(如原本指向不存在主機),執行:
```sh
sh /root/42_10/remove_mysql_forward.sh
```
手動移除流程:
```sh
# 找出目標規則
ssh root@192.168.42.10 "uci show firewall | grep <port>"
# 刪除並提交
ssh root@192.168.42.10 "uci delete firewall.<rule_id> && uci commit firewall"
# 重載防火牆
ssh root@192.168.42.10 "fw4 restart"
# 確認規則已移除
ssh root@192.168.42.10 "nft list chain inet fw4 dstnat_wan | grep <port>"
```
---
## WireGuard VPN
**架構**:路由器作為 server外部裝置以 client 身份連入,取得對 LAN`192.168.42.0/24`)的存取權。
```
外部裝置
│ UDP 51820
192.168.42.10 wg0: 10.0.0.1/24 ← server
├── 10.0.0.2 Workstation
└── 10.0.0.3 iPhone 15 Pro Max
```
### 狀態查看
```sh
# 查看所有 peer 連線狀況last handshake、傳輸量
wg show
# 只看介面摘要
wg show wg0
```
### 新增 Peer
```sh
# 1. 在路由器上產生新的 keypair
wg genkey | tee /tmp/peer_private.key | wg pubkey > /tmp/peer_public.key
cat /tmp/peer_private.key
cat /tmp/peer_public.key
# 2. 加入 peer 設定(以 10.0.0.4 為例)
uci add network wireguard_wg0
uci set network.@wireguard_wg0[-1].public_key='<peer_public_key>'
uci set network.@wireguard_wg0[-1].private_key='<peer_private_key>'
uci set network.@wireguard_wg0[-1].persistent_keepalive='25'
uci add_list network.@wireguard_wg0[-1].allowed_ips='10.0.0.4/32'
uci add_list network.@wireguard_wg0[-1].allowed_ips='192.168.42.0/24'
uci set network.@wireguard_wg0[-1].dns='1.1.1.1'
uci set network.@wireguard_wg0[-1].description='<裝置名稱>'
uci commit network
service network restart
```
### 移除 Peer
```sh
# 找出目標 peer 的索引
uci show network | grep -n '<peer_public_key>'
# 刪除(假設是 @wireguard_wg0[2]
uci delete network.@wireguard_wg0[2]
uci commit network
service network restart
```
### Client 設定檔範本
將以下內容存為 `.conf` 檔匯入裝置WireGuard app 或 `wg-quick`
```ini
[Interface]
PrivateKey = <peer_private_key>
Address = 10.0.0.x/24
DNS = 1.1.1.1
[Peer]
PublicKey = s7fZj/dlgcjc1q4Pd1EaeoCOgq8EStyS30h30hOL1RI=
Endpoint = 125.229.110.50:51820
AllowedIPs = 192.168.42.0/24, 10.0.0.0/24
PersistentKeepalive = 25
```
> `AllowedIPs` 只填 `192.168.42.0/24, 10.0.0.0/24` 表示 split tunnel只有內網流量走 VPN
> 若要讓所有流量都走 VPN改為 `0.0.0.0/0, ::/0`。
### 現有 Peer 一覽
| 描述 | VPN IP | Public Key前 8 碼) |
|---|---|---|
| Workstation | `10.0.0.2` | `daM1BFUS` |
| iPhone 15 Pro Max | `10.0.0.3` | `PZVrUwd1` |
### 防火牆規則說明
| 規則 | 說明 |
|---|---|
| WAN UDP 51820 → ACCEPT | 允許外部 client 建立 VPN tunnel |
| vpn → lan ACCEPT + masq | VPN client 可存取內網,並做 NAT |
若防火牆規則遺失,手動補回:
```sh
# 允許 WireGuard 進入
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-WireGuard'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest_port='51820'
uci set firewall.@rule[-1].proto='udp'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
fw4 restart
```
---
## TailscaleHeadscale client
路由器以 Tailscale client 身份加入自架的 Headscale tailnetcontrol server`https://headscale.lotimmy.com`user `mainnet`)。節點名 `openwrt`tailnet IP `100.64.0.9`
> ⚠️ **邊界路由器絕對不可用 `--accept-routes`。** `.10` 是站點 gatewaytailnet 上已有節點宣告 `192.168.42.0/24`;一旦 `--accept-routes``.10` 會把這條路由裝進 `tailscale0`**黑洞掉自己的 LAN、DNAT 轉送與站內 Headscale 控制面 → 全站斷線**且重開機不會自愈prefs 會保留。2026-06 曾因此造成 sev1。
### 安裝與連線
```sh
opkg update && opkg install tailscale # 約 9.6MB 下載overlay 佔用 ~30MB
/etc/init.d/tailscale enable
/etc/init.d/tailscale start
# 連線(必須 --accept-routes=false
tailscale up --login-server https://headscale.lotimmy.com --accept-routes=false
```
正常時 `tailscale status` 會出現 `Some peers are advertising routes but --accept-routes is false`,且 `ip route get 192.168.42.x` 應走 `dev br-lan`(不是 tailscale
> Headscale control 走 `headscale.lotimmy.com`(→ WAN `125.229.110.50`)會髮夾彎回站內 NPM憑證 CN 不符而連不上。已在 `.10` 的 `/etc/hosts` 加 split-DNS 覆寫,直接走內網 NPM
> ```
> 192.168.42.124 headscale.lotimmy.com
> ```
### 出事時的救援in-band 全斷)
`.10` 路由被劫持、LAN/tailnet/WAN 全進不去,改走 **WireGuard**`wg0: 10.0.0.1` 與被黑洞的 `192.168.42.0/24` 無關):
```sh
# 在任一 WG peer如 iPhone 10.0.0.3
ssh root@10.0.0.1
tailscale down # 立即撤掉劫持路由,全站恢復,免重開機
```
備援OpenWrt failsafe 模式(開機狂按 reset→ 網路線直插、靜態 `192.168.1.x``ssh root@192.168.1.1``/etc/init.d/tailscale disable`
### 從 tailnet 管理 `.10`(選用)
目前 `tailscale0` 未納入任何 fw4 zone所以 **tailnet → 路由器 SSH 會被 reject**(節點仍可被 `tailscale ping`)。若需從 tailnet 直接管理,將 `tailscale0` 加入 `lan` zone 或新增對應 input 規則。