新增 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>
14 KiB
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 │
└──────────┘
對外開放的 Port(WAN → 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 | — |
9000–10000 |
TCP | 192.168.42.100:9000–10000 |
Bore Range | — |
21115–21119 |
TCP/UDP | 192.168.42.101:21115–21119 |
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 Box(SSH、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 |
NetBird(Management + 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
系統狀態確認
# 開機時間與負載
uptime
# 記憶體用量
free -m
# 磁碟空間
df -h
# 近期系統紀錄
logread -l 50
# 即時追蹤紀錄
logread -f
套件管理
# 更新套件列表
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)
# 列出所有規則
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
網路診斷
# 介面清單與狀態
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>
日誌
# 查看系統紀錄
logread
# 即時監控
logread -f
# 最近 50 筆
logread -l 50
# 過濾防火牆相關
logread | grep -i firewall
服務管理
# 啟動 / 停止 / 重啟
/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
設定備份與還原
# 備份整個系統設定
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 集合管理
# 重新抓取並更新 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,例如每月一次:
# crontab -e
0 3 1 * * sh /root/42_10/update_tw_ip.sh
防火牆規則驗證
# 本機執行:SSH 進路由器並格式化輸出規則
sh /root/42_10/show_nft_rules.sh
# 驗證台灣 IP 通行、非台灣 IP 攔截
sh /root/42_10/test_connection.sh
test_connection.sh 會:
- 查詢目前出口 IP 所在地(透過
https://ip.lotimmy.com/json) - 對
125.229.110.50的指定 Port(51433,31433)發起測試 - 判斷結果是否符合預期(台灣 IP 應通過,非台灣 IP 應被攔截)
轉發規則調整
若需移除已失效的 Port 轉發(如原本指向不存在主機),執行:
sh /root/42_10/remove_mysql_forward.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
狀態查看
# 查看所有 peer 連線狀況(last handshake、傳輸量)
wg show
# 只看介面摘要
wg show wg0
新增 Peer
# 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
# 找出目標 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):
[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 |
若防火牆規則遺失,手動補回:
# 允許 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
Tailscale(Headscale client)
路由器以 Tailscale client 身份加入自架的 Headscale tailnet(control server:https://headscale.lotimmy.com,user mainnet)。節點名 openwrt,tailnet IP 100.64.0.9。
⚠️ 邊界路由器絕對不可用
--accept-routes。.10是站點 gateway,tailnet 上已有節點宣告192.168.42.0/24;一旦--accept-routes,.10會把這條路由裝進tailscale0,黑洞掉自己的 LAN、DNAT 轉送與站內 Headscale 控制面 → 全站斷線,且重開機不會自愈(prefs 會保留)。2026-06 曾因此造成 sev1。
安裝與連線
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(→ WAN125.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 無關):
# 在任一 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 規則。