跳轉到

在 x86_64 UEFI 小主機安裝 OpenWrt 25.12.5:從寫入映像到 LuCI、SSH 與首份備份

狀態:已發布
領域:網路/OpenWrt/x86 軟路由
版本基準:OpenWrt 25.12.5,target x86/64,profile generic
查證日期:2026-08-20

完成後會得到什麼?

讀者會把官方 OpenWrt 25.12.5 x86-64 UEFI SquashFS 映像安全寫入小主機的內部磁碟,在不先接 Internet 的情況下辨識預設 LAN 埠,登入 LuCI/SSH、設定管理密碼、建立 SSH Key 管理入口,完成重開機驗證,並把第一份可還原的設定備份保存到管理電腦。

這份指南會清除整顆目標磁碟

dd 會直接覆寫指定磁碟。選錯 /dev/disk/by-id/<TARGET-DISK> 可能摧毀管理電腦、Live USB 或其他資料碟。開始前必須準備本機螢幕與鍵盤、Linux Live USB、外接備份碟,並確認管理連線不依賴即將被改寫的設備。不要透過唯一的遠端連線執行這份指南。

安全主線

本機救援可用
→ 辨識並卸載目標磁碟
→ 驗證外接備份碟後建立整碟備份
→ 從官方 checksum 驗證映像
→ 寫入並完整比對映像內容
→ 離線開機並辨識 LAN
→ 設定密碼與驗證 SSH Key
→ 匯出設定備份
→ Reboot 後重新驗證
→ 最後才進入 WAN/PPPoE 設定

一、適用情境與範圍

適用

  • x86_64 小主機或一般 PC。
  • 使用 UEFI 開機。
  • 至少一張 OpenWrt 能辨識的 Ethernet 網卡;作為 Router 建議兩張以上。
  • 能接本機螢幕、鍵盤,或已有獨立序列主控台。
  • 可從另一支 Linux Live USB 開機,離線寫入內部磁碟。

不適用

  • ARM/MIPS 路由器、Raspberry Pi 或特定品牌路由器。
  • 只接受廠商 sysupgrade.bin 的裝置。
  • Legacy BIOS-only 機器;這類機器應改用非 EFI 的 combined.img.gz,不可照抄本文檔名。
  • 想保留目標磁碟原有分割區或雙系統。
  • 完全沒有本機救援方法、只能透過現有 Router 遠端操作的環境。

本篇刻意不做

  • PPPoE、WAN VLAN 或 ISP 認證。
  • 把 OpenWrt 接到 Internet。
  • AdGuard Home、WireGuard、UniFi 或 Docker。
  • 擴大 SquashFS 系統分割區。
  • 把未使用的磁碟空間直接併入 root filesystem。

先完成「可開機、可管理、可備份、可復原」的基線,再處理上網與附加服務。

二、為什麼選 SquashFS combined EFI?

本篇固定使用:

openwrt-25.12.5-x86-64-generic-squashfs-combined-efi.img.gz

名稱各部分代表:

部分 意義
x86-64 64-bit x86 target
generic 一般 x86 profile
squashfs 唯讀基底加可寫 overlay,支援 OpenWrt 常見的 reset/failsafe 模式
combined 內含可直接寫入整顆磁碟的分割表、Kernel 與 root filesystem
efi 使用 UEFI 開機

如果目標是大量本機儲存、Docker 或頻繁修改 root filesystem,Ext4 可能更合適;但磁碟擴充、Overlay 行為與復原方式不同,應另立進階指南,不在第一次安裝時混用。

三、準備硬體與救援路徑

必要設備

  • x86_64 UEFI 小主機。
  • 目標內部 SSD/eMMC/SATA 碟。
  • Linux Live USB。
  • 外接備份碟;保守估算時,可用空間至少應等於原目標磁碟容量,不要先假設資料一定能高度壓縮。
  • 本機螢幕與鍵盤。
  • 一台管理電腦與 Ethernet 線。

開始前的實體拓撲

Internet/舊 Router
        X 先不要連接

管理電腦 ── Ethernet ── OpenWrt 小主機其中一個網路埠
                         螢幕+鍵盤

避免兩個 192.168.1.1 同時存在

OpenWrt 預設 LAN 位址為 192.168.1.1/24。若舊 Router 也使用 192.168.1.1,第一次設定時必須直接連線,不能把兩者接到同一個 Layer-2 網路。

四、變數與範例

以下命令在 Linux Live USB 的 Bash shell 執行;若目前不是 Bash,先執行 bash

OPENWRT_VERSION='25.12.5'
IMAGE='openwrt-25.12.5-x86-64-generic-squashfs-combined-efi.img.gz'
RAW_IMAGE="${IMAGE%.gz}"
TARGET='/dev/disk/by-id/<TARGET-DISK-ID>'
BACKUP_MOUNT='/media/<EXTERNAL-BACKUP-DISK>'
BACKUP_DIR="$BACKUP_MOUNT/openwrt-install"

本文所有 <...> 都是必須替換的佔位符,不能原樣執行。<TARGET-DISK-ID> 應替換成目標內部磁碟的實際 by-id 名稱;不得選擇名稱以 -partN 結尾的分割區連結,也不要在尚未確認磁碟時直接改用 /dev/sda

若 eMMC 或控制器沒有可用的 by-id,可依序考慮 /dev/disk/by-path/;只有在 by-id 與 by-path 都不存在時,才可在同一次 Live boot 中以型號、序號、容量及傳輸介面四項都核對成功的 raw device path。裝置重新開機後必須重新辨識,不能假設 /dev/sdX 順序不變。

五、變更前備份原磁碟

Step 1 — 從 Linux Live USB 開機

執行位置: 目標小主機的 Linux Live USB
影響: 只啟動臨時系統;尚未修改內部磁碟。

在 UEFI 設定中:

  1. 使用 UEFI mode。
  2. 若映像無法啟動,確認 Secure Boot 已關閉。
  3. 暫時把 Live USB 設為第一開機順位。
  4. 保持 Internet/WAN 線拔除。

Step 2 — 唯讀辨識磁碟

lsblk -o NAME,PATH,SIZE,MODEL,SERIAL,TRAN,MOUNTPOINTS

接著列出 stable by-id:

ls -l /dev/disk/by-id/

確認 TARGET 最終指向哪個 block device:

TARGET_REAL="$(readlink -f "$TARGET")"
test -n "$TARGET_REAL" && test -b "$TARGET_REAL"
case "$TARGET" in
  *-part[0-9]*) echo '錯誤:TARGET 指向分割區,不是整顆磁碟' >&2; exit 1 ;;
esac
test -z "$(lsblk -ndo PKNAME "$TARGET_REAL")" || {
  echo '錯誤:TARGET 不是整顆磁碟' >&2
  exit 1
}
printf 'TARGET=%s -> %s\n' "$TARGET" "$TARGET_REAL"
lsblk -o NAME,PATH,TYPE,SIZE,MODEL,SERIAL,TRAN,MOUNTPOINTS "$TARGET_REAL"

成功條件:

  • 容量、型號、序號與傳輸介面都對得上目標內部磁碟。
  • 不是 Live USB。
  • 不是外接備份碟。
  • 不是管理電腦的系統碟。

任何一項對不上就停止

不要用「看起來應該是 /dev/sda」作為判斷依據。USB、SATA、NVMe 的列舉順序可能改變。

Step 3 — 卸載來源分割區並驗證外接備份碟

執行位置: Linux Live USB
來源: TARGET 只允許讀取;其子分割區不得掛載。
目的地: 已掛載的外接備份碟,不得位於 TARGET

先檢查目標磁碟的子分割區:

lsblk -o NAME,PATH,TYPE,SIZE,MOUNTPOINTS "$TARGET_REAL"

MOUNTPOINTS 顯示掛載點,逐一卸載畫面上實際列出的分割區:

sudo umount /dev/<ACTUAL-TARGET-PARTITION-1>
sudo umount /dev/<ACTUAL-TARGET-PARTITION-2>

再次執行 lsblk,確認 TARGET 所有子分割區的 MOUNTPOINTS 都是空白。

外接備份碟必須先由 Live 系統掛載完成。先驗證掛載點本身,成功後才建立子目錄:

mountpoint -q "$BACKUP_MOUNT"
BACKUP_SOURCE="$(findmnt -no SOURCE -T "$BACKUP_MOUNT")"
test -n "$BACKUP_SOURCE"
findmnt -no SOURCE,TARGET,FSTYPE -T "$BACKUP_MOUNT"
lsblk -s -o NAME,PATH,TYPE,SIZE,MODEL,SERIAL,TRAN "$BACKUP_SOURCE"
mkdir -p "$BACKUP_DIR"
findmnt -no SOURCE,TARGET,FSTYPE -T "$BACKUP_DIR"
df -h "$BACKUP_DIR"

BACKUP_SOURCElsblk -s 裝置鏈與 TARGET_REAL 對照,確認它不是 TARGET_REAL,也不是 TARGET_REAL 的子分割區。若 findmnt 顯示 overlaytmpfs、Live USB,或完全沒有輸出,代表目的地不正確,必須停止。

再以 bytes 檢查可用容量:

TARGET_BYTES="$(sudo blockdev --getsize64 "$TARGET_REAL")"
FREE_BYTES="$(df --output=avail -B1 "$BACKUP_DIR" | tail -n 1 | tr -d ' ')"
printf 'target_bytes=%s backup_free_bytes=%s\n' "$TARGET_BYTES" "$FREE_BYTES"
test "$FREE_BYTES" -ge "$TARGET_BYTES"

成功條件: 最後的 test 回傳成功,且人工核對確認備份 source device 與目標磁碟沒有父子關係。

Step 4 — 建立整碟備份

使用 UTC timestamp 避免靜默覆寫既有備份:

BACKUP_STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
BACKUP_IMAGE="$BACKUP_DIR/before-openwrt-full-disk-$BACKUP_STAMP.img.gz"
test ! -e "$BACKUP_IMAGE"

完整備份目標磁碟:

set -o pipefail
sudo dd if="$TARGET_REAL" bs=4M status=progress \
  | gzip -1 > "$BACKUP_IMAGE"
sync

dd 回報讀取錯誤或 pipeline 回傳非零,這次備份不算成功;不要用 noerror 把壞磁碟的錯誤隱藏成一般安裝流程。需要救援故障磁碟時應改用 GNU ddrescue,另行處理。

驗證壓縮封裝並保存 checksum:

gzip -t "$BACKUP_IMAGE"
sha256sum "$BACKUP_IMAGE" > "$BACKUP_IMAGE.sha256"
printf '%s\n' "$TARGET_BYTES" > "$BACKUP_IMAGE.bytes"
sha256sum -c "$BACKUP_IMAGE.sha256"

成功條件:

  • dd 與整條 pipeline 成功結束。
  • gzip -t 無錯誤;這只證明壓縮封裝可完整解碼。
  • sha256sum -c 顯示 OK
  • 備份檔、.sha256 與記錄原磁碟長度的 .bytes 位於已核對的外接磁碟。

這是整碟備份,包含原分割表與資料;OpenWrt 的 sysupgrade 設定備份不能取代它。

六、下載並驗證官方映像

Step 5 — 下載固定版本

執行位置: Linux Live USB 或另一台可信任的 Linux 管理電腦。

curl -fLO \
  "https://downloads.openwrt.org/releases/${OPENWRT_VERSION}/targets/x86/64/${IMAGE}"
curl -fLO \
  "https://downloads.openwrt.org/releases/${OPENWRT_VERSION}/targets/x86/64/sha256sums"

不要只相信文章手抄的 hash;直接用同一官方目錄下載的 sha256sums 驗證:

sha256sum --ignore-missing -c sha256sums

本文查證時,指定映像的官方 SHA-256 是:

2a7d864032631005ec70eb4deb242d76914904ee8abc4ac32e22b4ce6c6964ca

成功條件:

openwrt-25.12.5-x86-64-generic-squashfs-combined-efi.img.gz: OK

若沒有出現指定映像的 OK,或命令回傳非零,刪除映像與 checksum 檔後重新下載;不要繼續寫入。

升級文章版本時要重新查 checksum

SHA-256 只適用這個精確版本與檔名。未來若改成其他版本,不得沿用本文 hash。

七、把映像寫入內部磁碟

Step 6 — 確認分割區沒有掛載

lsblk -o NAME,PATH,TYPE,SIZE,MOUNTPOINTS "$TARGET_REAL"

若子分割區有掛載點,逐一卸載實際顯示的分割區,例如:

sudo umount /dev/<ACTUAL-PARTITION-1>
sudo umount /dev/<ACTUAL-PARTITION-2>

不要照抄範例分割區名稱;以 lsblk 顯示為準。

再次執行 lsblk,只有在所有目標子分割區的 MOUNTPOINTS 都是空白時才可繼續。

Step 7 — 最後一次確認目標

printf '即將完全覆寫:%s -> %s\n' "$TARGET" "$TARGET_REAL"
lsblk -o NAME,PATH,TYPE,SIZE,MODEL,SERIAL,TRAN,MOUNTPOINTS "$TARGET_REAL"

把畫面上的型號、序號與容量再和實體設備核對一次。

Step 8 — 解壓縮後寫入映像

先把已驗證的壓縮映像完整解壓成一般檔案:

gzip -t "$IMAGE"
rm -f "$RAW_IMAGE"
gzip -dc "$IMAGE" > "$RAW_IMAGE"
test -s "$RAW_IMAGE"
RAW_BYTES="$(stat -c '%s' "$RAW_IMAGE")"
printf 'raw_image=%s bytes=%s\n' "$RAW_IMAGE" "$RAW_BYTES"

以下 dd 會立即破壞目標磁碟原內容

sudo dd if="$RAW_IMAGE" of="$TARGET_REAL" \
  bs=4M conv=fsync status=progress
sync

dd 必須以零退出;若有任何 I/O error,停止並保留畫面資訊,不要開機。

Step 9 — 完整比對已寫入內容

只比對開頭數 MiB 不能證明 root filesystem 等後段內容正確,因此以解壓後映像的完整長度進行 byte-for-byte 比對:

sudo cmp -n "$RAW_BYTES" "$RAW_IMAGE" "$TARGET_REAL"

成功條件: cmp 沒有輸出並回傳 0

這項比對能證明指定 TARGET_REALRAW_BYTES bytes 與映像完全一致,但不能證明磁碟選對。若一開始選錯磁碟,對同一錯誤磁碟讀回仍會成功;防止選錯只能依靠寫入前對型號、序號、容量、介面與整碟路徑的人工確認。

八、第一次啟動

Step 10 — 關機並調整開機順序

sudo poweroff
  1. 拔除 Linux Live USB。
  2. 外接備份碟可先拔除並妥善保存。
  3. 在 UEFI 中把 OpenWrt 內部磁碟設為第一順位。
  4. 仍不要接 Internet/WAN。
  5. 接上本機螢幕與鍵盤後開機。

成功條件: 主控台進入 OpenWrt,沒有持續 reboot 或停在找不到 root filesystem。

Step 11 — 從本機主控台確認系統

在 OpenWrt 主控台執行:

ubus call system board
ip link show
ip addr show
uci show network

OpenWrt 25.12.5 的 generic x86 預設邏輯是:

eth0 → LAN
若存在 eth1:eth1 → WAN(DHCP client)
LAN IPv4 → 192.168.1.1/24

eth0eth1 對應到哪個實體 RJ45 埠取決於硬體與驅動列舉,不能只看機殼印字判斷。

九、辨識預設 LAN 埠

Step 12 — 逐一插拔網路線

執行位置: OpenWrt 本機主控台+管理電腦。

插線前先記錄一次:

ip link show

把管理電腦的網路線逐一插到小主機各 Ethernet 埠;每次插拔後重新執行:

ip link show
ip addr show

比較哪個介面的 state、carrier 或 LOWER_UP 隨插拔改變。

找到屬於 LAN/br-lan 的實體埠後立即貼上臨時標籤。不要先把另一個未確認的埠接到 Internet。

Step 13 — 從管理電腦取得位址

把管理電腦只連到已確認的 LAN 埠,將有線網路設成 DHCP。

預期關係:

管理電腦 IPv4:192.168.1.100~192.168.1.249 其中一個位址
Netmask:255.255.255.0
Gateway:192.168.1.1
OpenWrt LAN:192.168.1.1

若 DHCP 未成功,先暫時設定管理電腦:

IPv4:192.168.1.2
Netmask:255.255.255.0
Gateway:留空
DNS:留空

再測試:

ping 192.168.1.1

十、第一次登入 LuCI 與 SSH

Step 14 — 開啟 LuCI

在管理電腦瀏覽器開啟:

http://192.168.1.1/

若使用 HTTPS:

https://192.168.1.1/

第一次使用自簽憑證時,瀏覽器會顯示警告;確認網址是直接連線的 192.168.1.1 後再繼續。

OpenWrt 25.12.5 x86/64 官方 manifest 已包含 LuCI、uHTTPd、Dropbear 與 LuCI SSL 套件。

全新官方映像的 LuCI 使用者名稱是 root,初始 root 密碼尚未設定。只在目前的隔離直連 LAN 上,以 root 登入並將密碼欄留空;登入後立刻執行下一步設定密碼。密碼完成前,OpenWrt 不得接到 Internet、舊 LAN 或其他不受信任網路。

Step 15 — 立即設定 root 管理密碼

推薦位置: LuCI → System → Administration
替代方式: OpenWrt 本機主控台或 SSH:

passwd

密碼設定完成前不要接 WAN。

Step 16 — 驗證 SSH

ssh root@192.168.1.1

使用剛設定的管理密碼登入後,執行唯讀確認:

ubus call system board
ip addr show
uci get network.lan.ipaddr
service dropbear status
service uhttpd status

成功條件:

  • 系統板資訊可讀取。
  • LAN 位址是 192.168.1.1,或是後續由你明確改過的位址。
  • Dropbear 與 uHTTPd 正常。
  • SSH 與 LuCI 都能從直接連線的 LAN 管理電腦使用。

十一、建立 SSH Key 管理入口

Step 17 — 在管理電腦產生專用 Key

若尚未有專用管理 Key:

ssh-keygen -t ed25519 \
  -f ~/.ssh/openwrt_admin_ed25519 \
  -C 'openwrt-admin'

只把 .pub 公鑰交給 OpenWrt;私鑰留在管理電腦,不要貼進 LuCI、文件或聊天。

Step 18 — 加入公鑰

推薦位置: LuCI → System → Administration → SSH-Keys

先在管理電腦顯示公鑰內容:

cat ~/.ssh/openwrt_admin_ed25519.pub

複製輸出的完整單行公鑰(通常以 ssh-ed25519 開頭),貼入 LuCI 的 SSH-Keys 欄位。不要貼檔案路徑,也不要貼沒有 .pub 的私鑰內容。

Step 19 — 開另一個終端機驗證 Key

保持原本密碼 SSH session 不要關閉,另開終端機:

ssh -i ~/.ssh/openwrt_admin_ed25519 root@192.168.1.1

Key 登入成功前,不要停用密碼登入。

密碼登入硬化留到基線穩定後

若要停用 SSH 密碼登入,應在 Key 登入、LuCI、本機主控台與備份都已驗證後另行處理。第一次安裝不要把「建立 Key」和「移除所有備援登入」綁成同一步。

十二、建立第一份 OpenWrt 設定備份

Step 20 — LuCI 匯出

位置: LuCI → System → Backup / Flash Firmware

選擇 Generate archive/產生備份封存檔,下載到管理電腦。

Step 21 — Shell 等價方式

在 OpenWrt:

sysupgrade -b /tmp/openwrt-initial-config-backup.tar.gz
sha256sum /tmp/openwrt-initial-config-backup.tar.gz

在管理電腦:

scp -O -i ~/.ssh/openwrt_admin_ed25519 \
  root@<OPENWRT-LAN-IP>:/tmp/openwrt-initial-config-backup.tar.gz .
sha256sum openwrt-initial-config-backup.tar.gz
tar -tzf openwrt-initial-config-backup.tar.gz > /tmp/openwrt-backup-file-list.txt

比較 OpenWrt 與管理電腦算出的 SHA-256,兩者必須一致;tar -tzf 必須能正常列出內容。OpenWrt 25.12.5 stock image 沒有 OpenSSH SFTP server,因此對常見新版 OpenSSH 用戶端明確使用 scp -O 的 legacy SCP protocol。

設定備份不是整碟備份

sysupgrade -b 主要保存設定檔,不包含完整磁碟、所有額外套件與一般使用者資料。安裝前的整碟映像仍須保留,直到確認不再需要回復原系統。

十三、重開機與持久化驗證

Step 22 — 在本機救援仍可用時重開機

reboot

等待 OpenWrt 完成啟動,重新驗證:

ping <OPENWRT-LAN-IP>
ssh -i ~/.ssh/openwrt_admin_ed25519 root@<OPENWRT-LAN-IP>

登入後:

ubus call system board
uci get network.lan.ipaddr
service dropbear status
service uhttpd status

再確認:

  • LuCI 可登入。
  • SSH Key 可登入。
  • 管理密碼有效。
  • LAN 位址與 DHCP 設定在 reboot 後仍保留。
  • 備份檔已保存在管理電腦,而不是只留在 /tmp

完成以上項目後,才進入下一篇 WAN/PPPoE 指南。

十四、驗證矩陣

層次 檢查 成功條件
Boot 本機主控台 OpenWrt 正常進入系統,沒有 boot loop
Link 插拔前後執行 ip link show 能把實體埠對應到 LAN 介面
Address ip addr show LAN 有預期的管理位址
DHCP 管理電腦重新取得 lease 取得同一 LAN subnet 的位址
LuCI 開啟管理網址 可登入且已設定密碼
SSH Key 登入 不依賴空密碼,Key 可建立新 session
Persistence Reboot 後重測 LAN、LuCI、SSH 設定仍存在
Backup SHA-256 比對 管理電腦保存的備份與 OpenWrt 來源一致
Isolation WAN 線仍拔除 尚未設定前不把未硬化系統接上 Internet

十五、常見問題與唯讀診斷

症狀一:UEFI 找不到 OpenWrt 磁碟

優先確認:

  • 是否使用 combined-efi.img.gz
  • UEFI 是否停用 Secure Boot。
  • 映像是否寫到整顆磁碟,而不是某個分割區。
  • Live USB 寫入後的完整 cmp 是否成功。
  • UEFI boot order 是否指向內部磁碟。

不要先重複 dd;先確認寫入目標與 UEFI 模式。

症狀二:OpenWrt 已開機,但管理電腦拿不到 DHCP

在本機主控台:

ip link show
ip addr show
uci show network
uci show dhcp.lan
logread

判讀順序:

  1. 插拔網路線時是否有介面 Link state 變化?
  2. 變化的介面是否屬於 LAN/br-lan
  3. LAN 是否有管理 IP?
  4. DHCP LAN 是否被停用?
  5. 管理電腦是否還連著 Wi-Fi 或其他競爭路由?

先用 192.168.1.2/24 靜態位址測試,不要直接 factory reset。

症狀三:能 Ping,但 LuCI 打不開

service uhttpd status
ubus call service list '{"name":"uhttpd"}'
logread -e uhttpd

若 SSH 可用,可嘗試只重啟管理 Web 服務:

service uhttpd restart

重啟 uHTTPd 不等於重啟整台 Router;仍應先看 status 與 log。

症狀四:SSH 密碼或 Key 無法登入

從本機主控台確認:

service dropbear status
ls -l /etc/dropbear/authorized_keys

可在本機重新執行:

passwd

不要為了修 SSH 而立刻清除全部 Router 設定。

十六、Rollback 與復原

A. 回復安裝前的完整磁碟

只能從 Linux Live USB/其他系統執行,不能對正在運作的目標 root disk 原地覆寫。這個流程假設還原到建立備份時的同一顆磁碟。

重新設定並核對實際值:

TARGET='/dev/disk/by-id/<TARGET-DISK-ID>'
TARGET_REAL="$(readlink -f "$TARGET")"
BACKUP_MOUNT='/media/<EXTERNAL-BACKUP-DISK>'
BACKUP_IMAGE="$BACKUP_MOUNT/openwrt-install/<ACTUAL-BACKUP-FILENAME>.img.gz"

先完成所有前置檢查:

test -b "$TARGET_REAL"
case "$TARGET" in
  *-part[0-9]*) echo '錯誤:TARGET 指向分割區' >&2; exit 1 ;;
esac
test -z "$(lsblk -ndo PKNAME "$TARGET_REAL")"
mountpoint -q "$BACKUP_MOUNT"
findmnt -no SOURCE,TARGET,FSTYPE -T "$BACKUP_IMAGE"
lsblk -o NAME,PATH,TYPE,SIZE,MODEL,SERIAL,TRAN,MOUNTPOINTS "$TARGET_REAL"
gzip -t "$BACKUP_IMAGE"
sha256sum -c "$BACKUP_IMAGE.sha256"
EXPECTED_BYTES="$(tr -d '[:space:]' < "$BACKUP_IMAGE.bytes")"
ACTUAL_BYTES="$(sudo blockdev --getsize64 "$TARGET_REAL")"
test "$EXPECTED_BYTES" = "$ACTUAL_BYTES"

TARGET 的所有已掛載子分割區逐一 umount,重新執行 lsblk,確認 MOUNTPOINTS 全空,再做最後一次型號、序號與容量人工確認。

以下命令會完全覆寫目標磁碟

set -o pipefail
gzip -dc "$BACKUP_IMAGE" \
  | sudo dd of="$TARGET_REAL" bs=4M conv=fsync status=progress
sync

還原完成後,對完整磁碟長度比對解壓資料 hash:

set -o pipefail
BACKUP_RAW_HASH="$(gzip -dc "$BACKUP_IMAGE" | sha256sum | awk '{print $1}')"
TARGET_RAW_HASH="$(sudo dd if="$TARGET_REAL" bs=4M status=progress \
  | sha256sum | awk '{print $1}')"
printf 'backup=%s\ntarget=%s\n' "$BACKUP_RAW_HASH" "$TARGET_RAW_HASH"
test "$BACKUP_RAW_HASH" = "$TARGET_RAW_HASH"

只有 hash 相同才關機、拔除 Live USB,並從內部磁碟開機;之後驗證原系統分割區、開機與資料。

B. 重新安裝 OpenWrt 並還原設定備份

若 OpenWrt 系統毀損但不需要回復原作業系統:

  1. 從 Live USB 開機。
  2. 重新辨識整顆 TARGET、卸載其分割區並核對型號/序號/容量。
  3. 從官方 sha256sums 驗證相同 target/profile 的 OpenWrt 映像。
  4. 重新寫入映像並執行完整 cmp
  5. 離線開機,設定暫時管理密碼並確認 LuCI/SSH。

設定備份只應還原到相同 target/profile 與已確認相容的版本。先在管理電腦檢查:

tar -tzf openwrt-initial-config-backup.tar.gz
sha256sum openwrt-initial-config-backup.tar.gz
scp -O -i ~/.ssh/openwrt_admin_ed25519 \
  openwrt-initial-config-backup.tar.gz \
  root@<OPENWRT-LAN-IP>:/tmp/restore-config.tar.gz

在 OpenWrt 重新計算 hash,和管理電腦的結果核對一致後才還原:

sha256sum /tmp/restore-config.tar.gz
sysupgrade -r /tmp/restore-config.tar.gz
reboot

sysupgrade -r 會把封存中的設定寫回系統,但本身不會自動 reboot。還原可能同時改回舊 LAN 位址、密碼與 SSH 設定,因此執行前必須保留本機主控台;重開後依備份當時的 LAN 位址重新驗證 LuCI、密碼、SSH Key 與網路設定。

C. SquashFS 清除設定

只有在已確認使用 SquashFS、已保存備份且有本機主控台時,才考慮:

firstboot -y
reboot

這會清除 overlay 中的設定並回到映像預設值,不會恢復安裝前的舊作業系統。執行前應先嘗試唯讀診斷與較小範圍修復。

十七、安全與版本注意事項

  • 不要把未設定密碼的 OpenWrt 接到不受信任網路。
  • 私鑰只保存在管理端;OpenWrt 只放公鑰。
  • 不公開完整設定備份,因其可能包含 Wi-Fi、VPN、PPPoE 或其他敏感設定。
  • x86 網卡順序不是機殼標籤的可靠保證,必須用 Link state 實測。
  • 本文固定 OpenWrt 25.12.5;升級版本時重新確認檔名、SHA-256、manifest 與 UI 路徑。
  • SquashFS 與 Ext4 的 reset、儲存與磁碟擴充方式不同,不要交叉套用命令。
  • 本篇成功只代表管理基線成立,不代表 WAN、NAT、DNS 或 Firewall 已完成端到端驗證。

十八、為什麼這個順序較安全?

本機救援
→ 整碟備份
→ 官方映像與 checksum
→ 離線寫入
→ 本機開機驗證
→ 找出 LAN
→ 設管理密碼
→ 驗證 SSH Key
→ 匯出設定備份
→ Reboot 驗證
→ 最後才接續 WAN/PPPoE

這個順序把「會清空磁碟」「可能失去管理入口」和「會改變網路資料平面」拆開,避免第一次安裝同時處理過多故障來源。

十九、來源與查證紀錄

  1. OpenWrt 25.12.5 release directory
  2. OpenWrt 25.12.5 x86/64 image index:映像名稱、大小與 SHA-256。
  3. OpenWrt 25.12.5 x86/64 manifest:確認 stock image 包含 Dropbear、LuCI、LuCI SSL 與 uHTTPd。
  4. OpenWrt source:default network generation:generic 預設 eth0 為 LAN,存在 eth1 時設為 WAN。
  5. OpenWrt source:LAN default address:LAN 預設 192.168.1.1/24
  6. OpenWrt source:dnsmasq DHCP defaults:LAN DHCP 預設 start 100、limit 150、lease 12h,WAN DHCP server disabled。
  7. OpenWrt source:Dropbear defaults:SSH port 22 與預設認證設定。
  8. OpenWrt source:uHTTPd defaults:HTTP 80 與 HTTPS 443 listener。
  9. OpenWrt source:sysupgrade-b 建立設定封存、-r 還原設定且不自動 reboot。

本次實際查證

  • 已從 OpenWrt 官方下載站下載本文指定的 25.12.5 x86-64 SquashFS combined EFI 映像。
  • 本地 sha256sum 結果與官方 index 的 2a7d8640...6964ca 一致。
  • 已讀取同版 manifest,確認 LuCI、LuCI SSL、uHTTPd 與 Dropbear 套件存在。
  • 已讀取 OpenWrt v25.12.5 原始碼,確認 generic network、LAN IP、DHCP、Dropbear 與 uHTTPd 預設。
  • 本次沒有在備用 x86 主機上執行破壞性 dd、首次開機或還原演練;因此文章不把預期結果描述成這次的實機輸出。